6 minute read

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

도커와 쿠버네티스를 책으로 학습하면서 내용을 정리하고 있다. 기존에는 도커를 컨테이너를 생성하고 배포하는 용도로만 사용했지만, 여러 서버를 묶어 확장성을 확보하는 구조를 이해하기 위해 스웜 모드를 먼저 구성해본다.

도커 스웜은 여러 서버를 하나의 자원 풀로 묶어 클러스터를 구성하고, 컨테이너를 분산 실행해 스케일 아웃을 지원하는 기능이다. 쿠버네티스를 사용하기 전에 기본 개념을 이해하기 위해 스웜 모드를 먼저 실습한다.

스웜 구조

스웜은 매니저 노드와 워커 노드로 구성된다. 워커 노드는 실제 컨테이너가 실행되는 서버이고, 매니저 노드는 클러스터 전체를 관리하는 역할을 한다.

매니저 노드는 클러스터 상태를 저장하고 스케줄링을 수행하는 핵심 노드다. 여러 개의 매니저를 둘 수 있으며, 그 중 하나가 Leader가 된다.

스웜은 Raft 합의 알고리즘을 사용해 매니저 간 상태를 동기화한다. Leader가 상태 변경을 제안하고 과반수 매니저가 동의하면 반영된다. 따라서 매니저 노드는 보통 홀수 개로 구성한다.

실습 환경

실습은 VM 3대로 구성, 진행하였다.

docker-practice 192.168.0.14
swarm-worker1 192.168.0.16
swarm-worker2 192.168.0.17

스웜 클러스터 생성

root@docker-practice:/home/sungbin# docker swarm init --advertise-addr 192.168.0.14
Swarm initialized: current node (ba6yp5fu0aicdjit3av6p2vby) is now a manager.

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

    docker swarm join --token SWMTKN-1-3b4bm4u6vn6e5pubd6ovau7yb6bt9qs54mj4bdhjqpzdyyxu0v-801uwui2lj03qa8jf2d80f6vp 192.168.0.14:2377

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

각 워커 노드에서 join 명령어를 실행해 클러스터에 참여시킨다.

root@swarm-worker1:/home/sblee# docker swarm join --token SWMTKN-1-3b4bm4u6vn6e5pubd6ovau7yb6bt9qs54mj4bdhjqpzdyyxu0v-801uwui2lj03qa8jf2d80f6vp 192.168.0.14:2377
This node joined a swarm as a worker.

클러스터 상태 확인

root@docker-practice:/home/sungbin# docker node ls
ID                            HOSTNAME          STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
ba6yp5fu0aicdjit3av6p2vby *   docker-practice   Ready     Active         Leader           29.3.0
m8694b48dgqk2pzdvbptrsrae     swarm-worker1     Ready     Active                          29.3.0
nn12t9nwbjaa2g60tfiv7757z     swarm-worker2     Ready     Active                          29.3.0
root@docker-practice:/home/sungbin#

현재 * 표시가 붙은 노드가 Leader 매니저 노드다. 워커 노드들도 정상적으로 Ready 상태로 추가된 것을 확인할 수 있다.

스웜 서비스

스웜은 컨테이너가 아닌 서비스 단위로 관리한다.

서비스는 정의된 레플리카 수를 유지하며, 부족한 경우 자동으로 컨테이너를 생성한다. 특정 노드에 문제가 발생하면 다른 노드에 재배치된다.

또한 롤링 업데이트를 지원해 서비스 중단 없이 배포가 가능하다.

서비스 생성

root@docker-practice:/home/sungbin# docker service create \
> ubuntu:14.04 \
> /bin/sh -c "while true; do echo hello world; sleep 1; done"

zdj1m3f1y8juutg7maalunlmo
overall progress: 1 out of 1 tasks
1/1: running
verify: Service zdj1m3f1y8juutg7maalunlmo converged

서비스 확인

root@docker-practice:/home/sungbin# docker service ls
ID             NAME             MODE         REPLICAS   IMAGE          PORTS
zdj1m3f1y8ju   cool_aryabhata   replicated   1/1        ubuntu:14.04
root@docker-practice:/home/sungbin# docker service ps cool_aryabhata
ID             NAME               IMAGE          NODE              DESIRED STATE   CURRENT STATE           ERROR     PORTS
o0iickbfqf40   cool_aryabhata.1   ubuntu:14.04   docker-practice   Running         Running 3 minutes ago
docker service rm cool_aryabhata

Nginx 서비스 생성

root@docker-practice:/home/sungbin# docker service create --name myweb \
> --replicas 2 \
> -p 80:80 \
> nginx
uixdikr7y2vy1s9hsoatzn73g
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service uixdikr7y2vy1s9hsoatzn73g converged
root@docker-practice:/home/sungbin# docker service ps myweb
ID             NAME      IMAGE          NODE              DESIRED STATE   CURRENT STATE            ERROR     PORTS
kktu6al2vrj1   myweb.1   nginx:latest   swarm-worker1     Running         Running 32 seconds ago
qa6k2uyo5raz   myweb.2   nginx:latest   docker-practice   Running         Running 44 seconds ago

컨테이너가 여러 노드에 분산 배치된 것을 확인할 수 있다.

-p 80:80 옵션으로 스웜 전체에 포트를 개방했기 때문에 클러스터 내 어느 노드로 접근해도 동일한 서비스에 접근할 수 있다.

swarm-worker2

컨테이너가 없는 노드로 접근해도 서비스가 정상적으로 동작한다.

스케일 아웃

root@docker-practice:/home/sungbin# docker service scale myweb=4
myweb scaled to 4
overall progress: 4 out of 4 tasks
1/4: running
2/4: running
3/4: running
4/4: running
verify: Service myweb converged
root@docker-practice:/home/sungbin# docker service ps myweb
ID             NAME      IMAGE          NODE              DESIRED STATE   CURRENT STATE            ERROR     PORTS
kktu6al2vrj1   myweb.1   nginx:latest   swarm-worker1     Running         Running 16 minutes ago
qa6k2uyo5raz   myweb.2   nginx:latest   docker-practice   Running         Running 16 minutes ago
meuehgn3uuzy   myweb.3   nginx:latest   swarm-worker2     Running         Running 12 seconds ago
omxv6abj9ljw   myweb.4   nginx:latest   swarm-worker2     Running         Running 12 seconds ago
root@docker-practice:/home/sungbin#

요청은 라운드 로빈 방식으로 분산된다.

글로벌 서비스

root@docker-practice:/home/sungbin# docker service create --name global_web \
> --mode global \
> nginx
zyix7ik84y88k5ei4yus8lutf
overall progress: 3 out of 3 tasks
ba6yp5fu0aic: running
m8694b48dgqk: running
nn12t9nwbjaa: running
verify: Service zyix7ik84y88k5ei4yus8lutf converged

모든 노드에 하나씩 컨테이너가 생성된다.

장애 복구

root@docker-practice:/home/sungbin# docker rm -f myweb.2.qa6k2uyo5raz2vkss021qy45d
myweb.2.qa6k2uyo5raz2vkss021qy45d

컨테이너가 삭제되면 자동으로 새로운 컨테이너가 생성된다.

노드 장애 발생

root@swarm-worker1:/home/sblee# service docker stop
root@docker-practice:/home/sungbin# docker node ls
m8694b48dgqk2pzdvbptrsrae     swarm-worker1     Down

다른 노드에 컨테이너가 재배치된다.

롤링 업데이트

root@docker-practice:/home/sungbin# docker service create --name myweb2 \
> --replicas 3 \
> nginx:1.24
root@docker-practice:/home/sungbin# docker service update --image nginx:1.26 myweb2

기존 컨테이너를 순차적으로 종료하고 새 컨테이너로 교체한다.

Secret & Config

echo 1q2w3e4r | docker secret create my_mysql_password

Secret은 민감한 데이터를 안전하게 관리할 때 사용한다.

docker config create registry-config config.yml

Config는 설정 파일을 관리할 때 사용한다.

스웜 네트워크

root@docker-practice:/home/sungbin# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
969a540e7639   bridge            bridge    local
cad05fc76214   docker_gwbridge   bridge    local
wekq9q6yj3i6   ingress           overlay   swarm

ingress 네트워크는 외부 요청을 서비스로 라우팅하고 로드밸런싱을 수행한다.

overlay 네트워크는 여러 노드 간 컨테이너 통신을 가능하게 한다.

정리

도커 스웜은 여러 서버를 하나의 클러스터로 묶고 컨테이너를 분산 실행하며 장애 복구와 스케일링을 자동으로 처리한다.

Leave a comment