subject PDF 내 nginx 컨테이너에 대한 요구사항
nginx 서버 컨테이너는 80번 포트와 443번 포트를 listening 합니다. http로 연결되는 80번 포트로 접근할 경우, https 인 443번 포트로 301 리다이렉션 되게 해야합니다. 페이지는 http 오류만 아니라면 어떻게 보이든 상관없습니다.
이 컨테이너는 /wordpress 경로로 접근하면 IP:WPPORT 로 307 리다이렉트 되어야합니다.
/phpmyadmin 경로로 접근하면 reverse proxy 를 이용해 IP:PMAPORT 로 접근할 수 있어야합니다.
* WPPORT : WordPress 포트
* PMAPORT : PhpMyAdmin 포트
nginx 컨테이너에 SSH 로그인을 통해 접근할 수 있게 만드세요.
/wordpress 와 /phpmyadmin 으로 연결해주는 것은, 아직 wp와 pma 컨테이너를 만들지 않았으니 나중에 하기로 하고 나머지 요구사항만 먼저 만들어보기로 했다. SSH 를 빼면 ft_server에서 만들었던 nginx 서버와 크게 다르지 않다.
nginx 컨테이너 만들기
Dockerfile을 먼저 작성한 후 컨테이너에 접속해서 ft_server 복습의 시간을 가졌다. 생각보다 그 때 대충 넘어갔던 것들이 많았다.
FROM alpine:3.12.0
# install required packages
RUN apk update \
&& apk --update --no-cache add \
nginx \
openssl \
openssh-server
COPY ./nginx_setup.sh /usr/sbin/nginx_setup.sh
RUN chmod +x /usr/sbin/nginx_setup.sh
COPY ./default.conf /etc/nginx/conf.d/
EXPOSE 80 443 22
ENTRYPOINT ["/usr/sbin/nginx_setup.sh"]
- --update : 최신버전으로
- --no-cache : 로컬에 패키지의 인덱스를 저장하지 않는다. Docker 컨테이너를 가볍게 유지할 수 있다.
- openssh-server : openssh 는 openssh-server와 openssh-client를 포함한다. 여기서 openssh-server 만 설치하는 이유는 우리 과제에선 client를 쓸 일이 없기 때문이고, 가벼운 컨테이너를 지향하는 alpine linux 를 쓰는 목적에 맞춰 컨테이너를 더 가볍게 유지하기 위함이다.
RUN, CMD, ENTRYPOINT 에 대하여
- 도커파일에서 RUN 명령은 실행할 때 마다 레이어가 생성되고 캐시된다. 각각의 레이어마다 달라진 점이 commit 되면서 쌓이는 형태로 컨테이너가 빌드되기 때문에, cd 명령 같은걸 RUN으로 실행하면 달라진 점이 없는 셈이라 명령이 먹히지 않고 넘어간다. ㅠㅠ
- 그러므로 && 으로 명령들을 연결해서 하나의 RUN 으로 실행하거나, 파일로 컨테이너 내에서 실행할 명령들을 쉘 스크립트에 담아서 내부에서 실행해줘도 된다. 난 후자 선택
- ENTRYPOINT 는 docker run 해줄 때 실행되는 명령이라고 보면 된다. 자세한건 아래 링크 참고
- default.conf 작성은 ft_server랑 거의 똑같아서 설명생략
nginx_setup.sh
컨테이너 내부에서 실행될 쉘 파일
#!/bin/sh
# ssl configuration
mkdir -p /etc/nginx/ssl
openssl req -new -x509 -nodes -newkey rsa:4096 -keyout localhost-nginx.key -out localhost-nginx.crt -days 365 -subj "/C=KR/ST=Seoul/L=Seoul/O=42Seoul/CN=localhost"
mv localhost-nginx.key /etc/nginx/ssl
mv localhost-nginx.crt /etc/nginx/ssl
# 모든 프로토콜에 대해 호스트 키 생성
ssh-keygen -A
# SSH로 접속할 수 있는 유저 생성
# 비밀번호로 접속하는 것을 막고 ssh key로만 접속할 수 있게함.
adduser --disabled-password ${SSH_USERNAME}
echo "${SSH_USERNAME}:${SSH_PASSWORD}" | chpasswd
mkdir -p /run/nginx
echo "<h1>THIS IS hjung's FT_SERVICES NGINX INDEX.HTML</h1>" >> /var/www/index.html
/usr/sbin/sshd
/usr/sbin/nginx -g "daemon off;"
nginx_setup.sh
- nginx를 구동할 때 /run/nginx/ 디렉토리가 있어야 nginx.pid 파일이 정상적으로 생성되어 nginx 구동이 가능. 없으면 오류남.
- index.html 파일 간단하게 생성.
- minikube에 서비스 후 브라우저에서 external-IP로 접속하면 이 페이지가 보이는 걸 확인하기 위해 간단하게 생성
- ssh 설정
- SSH는 외부에서 접속해서 서버를 만져야하는 경우가 생길 수 있기 때문에 필요하다. 서버에서 요청해서 컨텐츠를 받는 거 말고, 서버 자체에 접속할 수 있게 하기 위함이다.
- SSH 로그인 정보는 민감한 정보가 될 수 있으므로 secret 으로 따로 빼서 설정해봤다.
- secret을 사용하는 자세한 방법은 조금 후에.
- daemon off 에 대하여
- docker container의 경우 daemon off; 는 nginx를 foreground에서 실행하도록 한다. 한 컨테이너에 하나의 서비스만 존재할 때 사용함.
- -g 는 그냥 global 옵션.
도커 자주 쓰는 명령어 정리
👇
더보기
#dockerfile로 image 생성
docker build . -t [이미지 이름]
#image 기반 container 생성
docker run -it -p 80:80 -p 443:443 [이미지 이름]
#컨테이너에 접속
docker exec -it [컨테이너 이름] /bin/bash
#컨테이너 삭제
docker rm [컨테이너 id]
#이미지 삭제
docker rmi [이미지 id]
#이미지 지우면서 컨테이너도 같이 삭제하려면 -f 옵션
docker rmi -f [이미지 id]
이제 잘 만든 nginx 컨테이너를 minikube에 올려보자.
nginx.yaml
Service
- IP 고정하기
# metallb로 하여금 서비스들의 ip를 모두 똑같게 설정하게 함
metallb.universe.tf/allow-shared-ip: "shared"
# 그 IP 주소를 정확하게 지정할 수 있음
loadBalancerIP : 192.168.99.100
- 포트는 TCP를 이용하되, 서비스는 80 포트로 서비스를 하고(port: 80), 서비스의 80 포트의 요청을 컨테이너의 80 포트로 연결(targetport: 80)해서 서비스를 제공한다.
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
Secret 사용법
nginx-secret.yaml 로 파일을 분리해준다.
SSH 로그인 아이디는 user, 비밀번호는 pass 로 설정했다.
apiVersion: v1
kind: Secret
metadata:
name: ssh-secret
stringData:
username: user
password: pass
nginx-secret.yaml
Deployment 내에서 아래와 같이 참조
env:
- name: SSH_USERNAME
valueFrom:
secretKeyRef:
name: ssh-secret
key: username
- name: SSH_PASSWORD
valueFrom:
secretKeyRef:
name: ssh-secret
key: password
nginx.yaml
이제 minikube에 apply 해주면 kubectl get svc 에서 External IP 주소를 확인할 수 있다.
결과
브라우저에서 External IP 로 접근하니 nginx 서버 내 index.html 파일이 잘 보인다.
ssh 로그인 확인방법
터미널에서 이렇게 하면 비밀번호 입력하라고 나오고 무사히 접속됨.
$ ssh user@192.168.99.100
하지만
- 접속 종료 후 컨테이너를 종료 시켰다가 다시 띄우면, WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 가 뜨면서 안됨
- ~/.ssh/known_hosts 에 등록된 정보와 달라졌기 때문에 뜨는 오류로, 해당 ip의 정보를 지워야 함
- ssh-keygen -R 192.168.99.100 하면 지워지고 다시 접속하면 잘 접속됨
trivia
- 크롬 보안 정책 때문에 페이지가 보이지 않았었다. 흰 부분 아무데나 클릭하고 thisisunsafe 타이핑해주면 짠 나타남 (yuhan 님 감사합니다)
- apk add --no-cache 와 rm -f /var/cache/apk/* 의 차이
- 처음에 nginx 설정하는게 제일 오래 걸렸다. MySQL + Wordpress + PMA 3대장도 쉽진 않지만, 컨테이너를 하나하나 만들면서 속도가 점점 빨라졌다.
nginx 코드 참고
github.com/hysimok/ft_services/tree/main/srcs/nginx
'공부기록 > 42 Seoul' 카테고리의 다른 글
Transcendence 공부 리소스 (0) | 2021.07.11 |
---|---|
42 과제에서 배운 것 정리 (0) | 2021.05.29 |
[ft_services] MetalLB 설정 (2) | 2021.01.19 |
[ft_services] 쿠버네티스 알아보기 및 구현 시작 (0) | 2021.01.18 |
[ft_services] Overview 및 환경 설정 (0) | 2021.01.17 |