Chapter 3

도커 스웜

  • 3.1 도커 스웜과 스웜 모드
  • 3.2 스웜 클러스터 구축
  • 3.3 스웜 모드 서비스

단일 서버에서 도커를 쓰는 건 금방 배워. 근데 프로덕션에서는 여러 호스트에 컨테이너를 분산 배포해야 하잖아. 도커 스웜은 이걸 위한 도커의 내장 오케스트레이션 도구야.

사실 "도커 스웜"이라는 이름으로 불리는 게 두 가지가 있거든. 별도로 설치해야 하는 구버전 Docker Swarm이 있고, 도커 엔진 1.12부터 내장된 스웜 모드가 있어. 지금 쓰는 건 스웜 모드 쪽이야 — 별도 설치 없이 docker swarm init으로 바로 사용 가능하지. 핵심 개념부터 보면, 노드는 클러스터에 참여하는 도커 호스트인데 매니저 노드워커 노드로 나뉘어. 매니저 노드는 클러스터를 관리하고 서비스를 스케줄링하면서 워커 역할도 동시에 수행할 수 있고, 워커 노드는 매니저의 지시를 받아 실제로 컨테이너를 실행해. 서비스는 스웜에서 컨테이너를 배포하는 단위이고, 태스크는 서비스의 각 컨테이너 인스턴스야. 서비스가 3개의 레플리카를 가지면 3개의 태스크가 생기는 거지.

스웜 모드는 **분산 합의 알고리즘(Raft)**을 사용해서 매니저 노드 간의 상태를 동기화해. 매니저 노드가 홀수 개여야 하는 이유가 여기 있어 — 과반수 투표가 필요하니까. 보통 3개 또는 5개를 권장하지.

클러스터를 만드는 건 놀라울 정도로 간단해:

docker swarm init --advertise-addr 매니저IP

이 명령어를 실행하면 현재 호스트가 매니저 노드가 되고, 워커 노드를 추가하기 위한 토큰이 출력돼. 워커 노드에서는 이렇게 조인하면 끝이야:

docker swarm join --token SWMTKN-1-xxx... 매니저IP:2377

토큰을 잃어버렸으면 매니저에서 docker swarm join-token worker로 다시 확인할 수 있어. 매니저 노드를 추가하려면 docker swarm join-token manager로 매니저용 토큰을 따로 확인해야 하는데, 워커 토큰과 매니저 토큰이 다르거든. 고가용성을 위해 매니저를 여러 개 두는 게 좋지만, 너무 많으면 합의 과정이 느려지니까 3개 또는 5개가 적절해.

docker node ls

노드 상태를 Active, Drain, Pause로 변경해서 특정 노드에 태스크를 배정하지 않을 수도 있어. 노드를 유지보수할 때 Drain 상태로 바꾸면 해당 노드의 태스크가 다른 노드로 옮겨가지.

스웜에서 컨테이너를 배포하는 기본 단위는 서비스야:

docker service create --name my-web --replicas 3 -p 80:80 nginx

이 명령어는 nginx 컨테이너를 3개 만들어서 클러스터에 분산 배치해. 서비스 타입은 두 가지인데, replicated 서비스는 지정한 레플리카 수만큼 태스크를 생성하는 기본값이고, global 서비스는 모든 노드에 태스크를 하나씩 생성하는 거야. 모니터링 에이전트 같은 걸 배포할 때 --mode global 옵션으로 쓰지.

docker service ls                     # 서비스 목록
docker service ps my-web              # 서비스의 태스크 목록
docker service logs my-web            # 서비스 로그
docker service scale my-web=5         # 레플리카 수 변경
docker service update --image nginx:latest my-web  # 이미지 업데이트
docker service rm my-web              # 서비스 삭제

서비스를 업데이트할 때 모든 컨테이너를 한 번에 교체하면 다운타임이 생기잖아. 스웜은 기본적으로 하나씩 순차적으로 업데이트하는 롤링 업데이트를 지원해:

docker service update \
  --update-parallelism 2 \
  --update-delay 10s \
  --image nginx:1.25 my-web

--update-parallelism은 동시에 업데이트할 태스크 수, --update-delay는 각 업데이트 사이의 대기 시간이야. 업데이트에 실패하면 --rollback으로 이전 버전으로 되돌릴 수 있어.

그리고 스웜 모드에서 서비스를 -p로 퍼블리시하면 재밌는 일이 생기는데, 클러스터의 모든 노드에서 해당 포트로 접근할 수 있어. 해당 노드에 태스크가 없어도 라우팅 메시가 알아서 태스크가 있는 노드로 요청을 전달해주거든. 로드 밸런싱이 내장되어 있는 셈이야.


정리

3장 읽고 기억할 거 세 가지:

  1. 스웜 모드는 도커에 내장된 오케스트레이션 도구다. 별도 설치 없이 docker swarm init으로 바로 시작할 수 있다.
  2. 매니저 노드는 클러스터를 관리하고, 워커 노드는 컨테이너를 실행한다. 매니저는 Raft 합의 알고리즘으로 상태를 동기화하며, 3개 또는 5개를 권장.
  3. 서비스가 배포의 기본 단위다. 레플리카 수를 지정하면 스웜이 알아서 분산 배치하고, 롤링 업데이트와 라우팅 메시를 기본 지원한다.