[배포] 2.무중단 배포 nginx
1. Nginx
-
nginx를 이용해 라우팅 할 컨테이너를 실행한다.
$ docker run -p 8081:8080 --name myapp-container1 zkdlu/myapp:v1 $ docker run -p 8082:8080 --name myapp-container2 zkdlu/myapp:v1
-
nginx의 reverse-proxy를 이용해 해당 서비스로 라우팅 해준다.
-
nginx.conf 작성
worker_processes 4; events { worker_connections 1024; } http { upstream my-app { least_conn; server localhost:8081 weight=10 max_fails=3 fail_timeout=30s; server localhost:8082 weight=10 max_fails=3 fail_timeout=30s; } server { listen 80; location / { proxy_pass http://my-app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } }
nginx에 대한 공부는 차후 진행 할 예정
-
설치하기 싫으니까 nginx도 Docker를 이용한다.
# Dockerfile FROM nginx COPY nginx.conf /etc/nginx/nginx.conf RUN apt-get update RUN apt-get install vim
$ docker build --tag nginx-image .
실행
$ docker run -p 80:80 --name nginx-container -v nginx.conf:/etc/nginx/nginx.conf nginx-image
-
Rolling 배포
-
업데이트 할 서비스를 nginx에서 down 상태로 변경한다.
worker_processes 4; events { worker_connections 1024; } http { upstream my-app { least_conn; server localhost:8081 weight=10 max_fails=3 fail_timeout=30s; server localhost:8082 weight=10 max_fails=3 fail_timeout=30s down; } server { listen 80; location / { proxy_pass http://my-app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } }
-
nginx를 reload 한다.
$ docker exec -it nginx-container service nginx reload
-
기존 컨테이너를 제거 한 후 업데이트 된 컨테이너를 실행한다.
$ docker run -p 8082:8080 --name myapp-container2 zkdlu/myapp:v2
-
nginx의 설정을 서로 변경 후 위 과정을 반복한다.
... upstream my-app { least_conn; server localhost:8081 weight=10 max_fails=3 fail_timeout=30s down; server localhost:8082 weight=10 max_fails=3 fail_timeout=30s; } ...
Blue/Green 배포
Nginx에서 Rolling 을 이용한 무중단 배포는 굉장히 번거로운 점이 있었다.
- 로컬에서 동작 할 경우 서비스마다 포트를 변경해주어야 함.
- nginx를 수정하고 컨테이너를 지우고 생성하는 등 작업이 많음.
docker-compose를 이용하면 번거로운 작업을 줄일 수 있다.
-
docker-compose 실행
#docker-compose.yml version: '3' services: proxy: image: nginx:latest container_name: nginx_container ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf myapp1: image: zkdlu/myapp:v1 container_name: myapp-container1 expose: - "8080" myapp2: image: zkdlu/myapp:v1 container_name: myapp-container2 expose: - "8080"
$ docker-compose up -d
-
nginx.conf 설정하기
worker_processes 4; events { worker_connections 1024; } http { upstream my-app { server myapp-container1:8080 weight=10 max_fails=3 fail_timeout=30s; server myapp-container2:8080 weight=10 max_fails=3 fail_timeout=30s; } server { listen 80; location / { proxy_pass http://my-app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } }
docker network는 bridge에 속한 컨테이너가 서로 통신할 때 docker host에서 생성한 dns 서버를 이용하기 떄문에 컨테이너의 이름으로 설정이 가능하다.
-
실행하기
$ docker-compose up -d
-
docker-compose가 실행된 후에 업데이트를 진행한다.
-
docker-compose.yml 에 새로운 버전의 서비스를 증설한다.
.... myapp1: image: zkdlu/myapp:v1 container_name: myapp-container1 expose: - "8080" myapp2: image: zkdlu/myapp:v1 container_name: myapp-container2 expose: - "8080" myapp3: image: zkdlu/myapp:v2 container_name: myapp-container3 expose: - "8080" myapp4: image: zkdlu/myapp:v2 container_name: myapp-container4 expose: - "8080"
docker-compose를 실행하면 변경 된 사항만 추가된다.
$ docker-compose up -d
-
reverse proxy를 다시 설정하여 새로운 서비스로 라우팅 되도록 한다
worker_processes 4; events { worker_connections 1024; } http { upstream new-my-app { server myapp-container3:8080 weight=10 max_fails=3 fail_timeout=30s; server myapp-container4:8080 weight=10 max_fails=3 fail_timeout=30s; } server { listen 80; location / { proxy_pass http://new-my-app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } }
-
nginx를 reload한다.
$ docker exec nginx-container service nginx reload
-
업데이트가 완료 되었다면 docker-compose에서 기존의 서비스를 제거한다.
docker-compose.yml 수정 후
$ docker-compose up -d --remove-orphans