금일은 Container Orchestration 의 Docker Swarm 두번째 시간 입니다.
Docker Swarm Service 는 하나 이상의 서비스를 그룹으로 묶은 단위로, 애플리케이션 전체 구성 단위입니다.
Swarm Stack 을 사용하여 배포된 Service 그룹은 overlay 네트워크(멀티 노드에서 사용, 여러개의 호스트를 묶어서 사용하는 개념)에 속합니다.
다음은 Docker Swarm Stack 을 활용하기 위한 명령어 입니다.
Stack 배포(Manager 실행)
docker stack deploy -c /stack/stack_sample.yml my-stack
배포 된 Stacak 확인
docker stack services my-stack
Stack 에 배포 된 컨테이너 확인
docker stack ps my-stack
Stack 삭제
docker stack rm my-stack
stack.yml
version: '3.7'
services:
nginx:
image: nginx
deploy:
replicas: 2
placement:
constraints: [node.role == worker]
restart_policy:
condition: on-failure
max_attempts: 2
ports: # attach on ingress network 1
- "8088:80"
environment:
SERVICE_PORTS: 80
networks:
- my-overlay-network
proxy:
# image: dockercloud/haproxy
image: haproxy:latest
depends_on:
- nginx
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /stack/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
ports: # attach on ingress network 1
- "80:80"
networks: # attach on web network 2 - nginx connect
- my-overlay-network
deploy:
mode: global
placement:
constraints: [node.role == manager]
networks:
my-overlay-network:
external: true
해당 yml 파일에서 nginx service 의 placement constraints 의 옵션은 배포 전략으로 worker node 에만 배포 하겠다는 의미입니다.
HA proxy 가 필요한 이유는 1번 노드가 망가졌을때 2번노드로 가기위한 설정으로 적용하겠습니다.
또한 manager node 에게만 적용하겠습니다.
replicas : 2 의 설정은 두개의 nginx 컨테이너의 실행을 의미합니다.
stack 실습을 진행하기에 앞서 기존의 swarm node 들을 해당 명령어를 입력해주어 종료 해주어야 한다.
해당 명령어는 worker 노드에서 진행해 주면 됩니다.
다음으로 stop, rm 명령어를 통해 컨테이너를 종료해줍니다.
docker swarm leave
이제 해당 windows 10 버전의 docker-compose 를 실행시켜 manager, worker 노드를 실행해주자
여기서 주의깊게 봐야될 부분은 manager container 의 volume 부분인데 stack_sample.yml 파일과 HAProxy 역할의 설정을 나타 내기 위한 haproxy.cfg 파일이다.
이렇게 하면 기존의 dind 이미지를 node 마다 명령어를 입력할 필요없이 docker-compose 파일하나로 대체 가능합니다.
docker-compose & docker swarm 실행 명령어
docker-compose -f docker-compose-windows10.yml up -d
docker swarm init -> manager
docker swarm join --token SWMTKN-1-2y9tluvu7t8lu3r8w459vz5w92llsnwwkmw8mwuio5usjeody7-cl5q08rryteb067002czgdqu1 172.20.0.2:2377 -> worker 1, 2

overlay network 생성
docker network create --driver overlay my-overlay-netw
ork
해당 overlay netwrok 의 흐름은 localhost:8000 번 호출을 웹브라우저에게 하게 되면 80 포트로 포트포워딩된 HAProxy 가 호출을 받아서 두개의 nginx 로 ip 정보를 기반으로 forawrding 을 진행하게됩니다.

stack-sample.yml 파일 실행
docker stack deploy -c /stack/stack_sample.yml my-
stack
docker stack ls
docker stack services my-stack
docker stack ps my-stack

haproxy.cfg
global
log stdout format raw local0
defaults
log global
mode http
option httplog
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
resolvers docker
nameserver dns 127.0.0.11:53
resolve_retries 3
timeout retry 1s
hold valid 10s
frontend http_front
bind *:80
stats uri /haproxy?stats
default_backend http_back
backend http_back
balance roundrobin
# server app1 10.0.1.28:80 check
# server app2 10.0.1.29:80 check
server-template app 2 nginx:80 check resolvers docker resolve-prefer ipv4
해당 haproxy 파일에서 server app1 10.0.1.28:80 check 해당 부분의 ip 는 worker 노드의 ip address 가 아니라 my overlay network 에 할당된 ip 입니다.
해당 ip 명령어는 worker container 에서 docker inspect [container ID] 에서 찾아볼 수 있습니다.
그 후 manager node 에서 아래의 명령어로 업데이트 해주면 됩니다.
docker service update d--force my-stack_proxy
manager container 포트번호인 localhost:8084 번으로 접속하면 nginx 를 시작할 수 있습니다.
하지만 직접 network ip 를 할당해주는 것보다는 자동으로 ip 를 얻어오는 명령어로 대체해주자
자세히 설명하자면 worker node 안에 cat /etc/resolv.conf 파일을 확인하게 되면 nameserver 의 ip 를 확인 가능하다 해당 설정 값으로 haproxy.cfg 파일의 resolvers docker 부분에 정보를 작성해주고 dns 서버를 사용하여 거기서 할당되어진 정보와 우리가 사용하고 있는 서비스 이름과 매핑하여 자동을 ip를 얻어오게 되는 것이다.
server-template 명령어로 수정해주면 됩니다.
http://localhost:8084/haproxy?stats 해당 url 에서는 haproxy 의 nginx 정보들을 확인 가능하다.

무중단 배포
Rolling Updates
docker swarm 모드는 rolling updates 를 자체 지원하게 됩니다. 실행을 manager node 에서 실행하며
rolling upate options 은 다음과 같습니다.
nginx 버전 변경 update 명령어 예시
docker service create --name myweb --replicas 3 nginx:latest
docker service update --image nginx:1.24 myweb
docker service create --replicas 4 --name myweb2 --update-delay 10s --update-parallelism 2 nginx:latest
docker service update --image nginx:1.24 myweb2
해당 실습은 기존의 stack 을 rm 명령어를 통해 서비스를 종료해주고 manager bash 에서 실행하면 됩니다.
nginx 의 latest 버전을 myweb1 service 의 1.24 로변경한 결과물이다.

myweb2 서비스는 updates 의 options 을 활용하였고 update 과정에서 2개의 컨테이너가 동시에 updates 하는 과정을 볼 수 있다.

마찬가지로 이전 버전의 서비스를 이용할 때 사용하며 update 명령어 대신에 rollback 명령어를 활용하며 manager node 에서 실행합니다.
실습은 redis image 를 이용하며 실행 명렁어는 다음과 같습니다.
docker service create --name redis \
--replica 4 --rollback-delay 10s --rollback-parallelism 1 \
--rollback-failure-acton pause redis:7.0.3
docker service inspect redis --pretty
docker service update --image redis:7.0.4 redis
docker service update --rollback redis
rollback 은 여러 단계로 옮기는 작업은 불가능하며 전 단계로 rollback 하는 것만 가능합니다.
docker commit docker commit <container_name><image_name:tag_name>docker save / load docker save <options> <tag_filename> <image_name:tag_name>
docker load -i <tar_filename>