만자의 개발일지

[Docker] Docker Swarm Cluster 구축하기(Swarm Mode) 본문

Docker

[Docker] Docker Swarm Cluster 구축하기(Swarm Mode)

박만자 2022. 6. 17. 16:38

이번 포스팅에서는 도커 스웜 모드 기반의 클러스터를 구축하는 법에 대해 알아보도록 하겠습니다.

 

도커 스웜 모드 클러스터 구축

아래 예제들은 3개의 AWS EC2(Amazon Linux 2) 인스턴스를 사용하여 진행하였습니다.

 

도커 설치

먼저 다음 명령어들을 통해 도커를 설치하고 실행해 줍니다.

# 도커 설치
$ yum install docker -y
# 도커 실행
$ systemctl start docker
# 재부팅시 도커 실행
$ systemctl enable docker
# 도커 상태 확인
$ systemctl status docker

 

도커 스웜 모드는 도커 엔진에 내장되어 있습니다. 때문에 별도의 설치없이 바로 사용하실 수 있습니다.


스웜 클러스터 생성

docker swarm init 명령어를 통해 스웜 클러스터를 초기화 시켜줍니다.

--advertise-addr 옵션에는 다른 도커 서버가 매니저 노드에 접근할 수 있도록 매니저 노드의 IP 주소(Private IP)를 입력해야 합니다.

기본적으로 클러스터 관리에 대한 통신 포트는 2377번 포트를(TCP) 사용하고, 노드간에 통신에는 7946번 포트(TCP/UDP) 그리고 overlay 네트워크에서 오고가는 트래픽에 대해서는 4789번 포트(UDP)를 사용합니다.
$ docker swarm init --advertise-addr <manager-private-ip>[:port(default 2377)]

Swarm initialized: current node (7wupsnro4eyvclxxxxxxxxxx) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-5dxzz5mrhjlwnxlogz83f0d1uxbiywdcmelvwsqb0gsvyq1z-1hbzg52wdkn19csxxxxxxxxxx <manager-private-ip>:<port>

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

초기화를 진행하면 위와 같이 워커 노드를 추가하는 토큰 값을 가진 명령어가 자동으로 생성됩니다.

 

워커 노드 추가

클러스터를 초기화하여 생성된 토큰 값을 가지고 워커 노드를 추가할 수 있습니다.

docker swarm join 명령어를 통해 워커 노드를 추가해 줍니다.

--token 옵션뒤에 클러스터를 초기화하여 생성된 토큰 값을 입력해 줍니다.

$ docker swarm join \
  --token SWMTKN-1-5dxzz5mrhjlwnxlogz83f0d1uxbiywdcmelvwsqb0gsvyq1z-1hbzg52wdkn19csxxxxxxxxxx \
  <manager-private-ip>:<port>
  
This node joined a swarm as a worker.

 

만약 토큰 값을 분실했을 경우 docker swarm join-token worker 명령어를 통해 토큰 값을 생성할 수 있습니다.

$ docker swarm join-token worker
To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-5tiekyzoangkyn9ixj2wpgqovqmqvulmbp9xs4b6r6ydifc3q9-btp0m933oeb40tcxxxxxxxxxx <manager-private-ip>:<port>

 

매니저 노드 추가

도커 스웜은 멀티 매니저 노드 기능을 지원 합니다. 따라서 하나의 클러스터에 여러 개의 매니저 노드를 추가할 수 있습니다.

docker swarm join-token manager 명령어를 통해 매니저 노드를 추가할 수 있는 토큰 값을 생성할 수 있습니다.

$ docker swarm join-token manager

To add a manager to this swarm, run the following command:

docker swarm join --token SWMTKN-1-5tiekyzoangkyn9ixj2wpgqovqmqvulmbp9xs4b6r6ydifc3q9-8r5szfs3fiewf18xxxxxxxxxx <manager-private-ip>:<port>

 

그다음 docker swarm join 명령어를 통해 매니저 노드를 추가할 수 있습니다.

--token 옵션에 위에서 생성한 토큰 값을 입력해 주시면 됩니다.

$ docker swarm join \
  --token SWMTKN-1-5tiekyzoangkyn9ixj2wpgqovqmqvulmbp9xs4b6r6ydifc3q9-8r5szfs3fiewf18xxxxxxxxxx \
  <manager-private-ip>:<port>
  
This node joined a swarm as a manager.

 

노드 목록 확인

docker node ls 명령어로 스웜에 추가된 노드들의 목록을 확인할 수 있습니다.

$ docker node ls
ID                            HOSTNAME                                        STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
mo6gezdk8fqjxwxi0qq309dz0     ip-10-10-10-10.ap-northeast-2.compute.internal   Ready     Active                          20.10.13
o30v47wwsm1fmchbyxdmx2du0 *   ip-10-10-10-11.ap-northeast-2.compute.internal   Ready     Active         Leader           20.10.13
pypppp7re6wzois9s9sqmnztk     ip-10-10-10-12.ap-northeast-2.compute.internal   Ready     Active                          20.10.13

 

서비스 생성

docker service create 명령어를 통해 도커 스웜 모드에서 컨테이너를 실행시킬 수 있습니다.

예제로 아파치 이미지를 불러와 실행시켜보도록 하겠습니다.

sudo docker service create --name apache -p 80:80 httpd

 

서비스 상태 확인

docker service ps 명령어를 통해 서비스가 정상적으로 작동하고 있는지, 서비스의 상태를 확인할 수 있습니다.

$ docker service ps apache
ID             NAME       IMAGE          NODE                                           DESIRED STATE   CURRENT STATE            ERROR     PORTS
2sntyj3yjr1q   apache.1   httpd:latest   ip-10-10-10-10.ap-northeast-2.compute.internal   Running         Running 18 seconds ago

만약 NAME 항목 앞에 \_ 가 붙어있는 컨테이너는 어떤 이유로든 동작을 멈춘 컨테이너로서, 서비스에서의 컨테이너 변경 기록을 나타냅니다.

 

혹은 docker ps 명령어에 -f is-task=true 옵션을 추가하여 현재 서버에서 스웜 서비스의 상태만 확인할  수도 있습니다.

$ docker ps -f is-task=true
CONTAINER ID   IMAGE          COMMAND              CREATED          STATUS          PORTS     NAMES
3d56c28bd57a   httpd:latest   "httpd-foreground"   5 minutes ago    Up 5 minutes    80/tcp    apache.1.hdrxb965eyutv0tizobnovkyn

 

서비스 목록 확인

docker service ls 명령어를 통해 현재 클러스터에서 실행되는 서비스 목록을 확인할 수 있습니다.

$ docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
ao254m0975sh   apache    replicated   1/1        httpd:latest   *:80->80/tcp

 

서비스 확장

노드에 장애가 발생하면 노드에 있던 컨테이너는 다른 노드로 할당되게 됩니다.

노드가 다시 정상적인 상태를 회복해도 다른 노드로 옮겨진 컨테이너는 다시 해당 노드에 할당되지 않습니다.

때문에 새로운 노드를 추가하거나 장애가 발생했던 노드를 다시 복구했을 때 서비스의 컨테이너 할당의 균형을 맞추기 윟서는 컨테이너의 수를 줄이고 다시 늘려야 합니다.

 

docker service scale 명령어를 통해 서비스를 복제하여 확장시킬 수 있습니다. 

$ docker service scale apache=3
apache scaled to 3
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

 

복제된 서비스는 각 노드에 균등하게 할당됩니다. 

$ docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
n4kczpo8e0hx   apache    replicated   3/3        httpd:latest   *:80->80/tcp

$ docker service ps apache
ID             NAME       IMAGE          NODE                                            DESIRED STATE   CURRENT STATE            ERROR     PORTS
ig646dpljxuh   apache.1   httpd:latest   ip-10-10-10-10.ap-northeast-2.compute.internal   Running         Running 5 minutes ago
yiuuna45pp85   apache.2   httpd:latest   ip-10-10-10-11.ap-northeast-2.compute.internal   Running         Running 5 minutes ago
p4kib810pas9   apache.3   httpd:latest   ip-10-10-10-12.ap-northeast-2.compute.internal   Running         Running 5 minutes ago

 

또한 확장된 서비스를 다시 축소 시킬 수 있습니다.

$ docker service scale apache=1
apache scaled to 1
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

$ docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
n4kczpo8e0hx   apache    replicated   1/1        httpd:latest   *:80->80/tcp

 

글로벌 서비스 생성

서비스에는 두 가지 모드가 있습니다. 하나는 위에서 생성한 아파치 서비스 같이 레플리카 셋의 수를 정의해 그만큼의 같은 컨테이너를 생성하는 복제(Replicated) 모드로서 실제 서비스를 제공하기 위해 일반적으로 사용하는 모드입니다.

 

다른 하나는 글로벌(Global) 모드입니다. 글로벌 모드로 서비스를 생성하면 스웜 클러스터 내에서 사용할 수 있는 모든 노드에 컨테이너를 반드시 하나씩 생성합니다. 따라서 글로벌 모드로 생성한 서비스는 레플리카 셋의 수를 별도로 지정하지 않습니다.

 

글로벌 서비스는 스웜 클러스터를 모니터링하기 위한 에이전트 컨테이너, 안티 바이러스 스캐너 혹은 모든 노드에서 실행되어야 하는 다른 종류의 컨테이너 등을 생성해야 할 때 유용합니다.

 

docker service create 명령어에 --mode global 옵션을 추가하여 글로벌 서비스를 생성할 수 있습니다.

$ docker service create --name apache -p 80:80 --mode global httpd
oach031jfdjip0h6w5ytojyyx
overall progress: 3 out of 3 tasks
qyl4fnrnycko: running   [==================================================>]
4c2xldnhth7x: running   [==================================================>]
ht0r0y7tlwkj: running   [==================================================>]
verify: Service converged

 

서비스 업데이트

docker swarm update 명령어로 서비스를 업데이트 할 수 있습니다.

이미지 뿐만 아니라 DNS, 네트워크, 컨테이너 라벨 등 서비스의 각종 다양한 설정을 변경할 수 있습니다.

$ docker service update --image httpd:2 apache
apache
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

스웜 모드는 업데이트를 할 때 자체적으로 롤링 업데이트방식을 이용한 무중단 배포를 지원합니다.

 

또한 서비스를 생성할 때 업데이트의 주기, 업데이트를 동시에 진행할 컨테이너의 개수, 업데이트에 실패했을 때 어떻게 할 것인지 등에 대해서 설정할 수 있습니다.

아래는 컨테이너를 30초마다 2개씩 업데이트를 수행하는 것을 의미합니다.

$ docker service create \
  --replicas 3 \
  --name apache \
  --update-delay 30s \
  --update-parallelism 2 \
  httpd

 

서비스 삭제

docker service rm 명령어를 통해 서비스를 삭제할 수 있습니다.

$ docker service rm apache
apache

 

클러스터에서 노드 제외

docker swarm leave 명령어를 통해 노드를 클러스터에서 제외 시킬 수 있습니다.

--force 옵션은 마지막 남은 매니저 노드를 제외할 때 사용합니다.

$ docker swarm leave [--force]
Node left the swarm.

 

참고

Comments