/엔지니어/Docker / 컨테이너/Docker Swarm 클러스터 — 서비스 배포와
Docker / 컨테이너중급linuxdockerswarmcluster

Docker Swarm 클러스터 — 서비스 배포와 스케일링 완전 가이드

Docker Swarm으로 매니저/워커 클러스터를 구성하고, 서비스 배포·스케일링·롤링 업데이트·오버레이 네트워크·시크릿까지 운영 관점에서 실습합니다.

Docker Swarm 이란?

Docker Swarm은 Docker 엔진에 내장된 컨테이너 오케스트레이터입니다. 여러 호스트를 하나의 가상 Docker 엔진처럼 묶어 서비스를 분산 배포하고, 스케일링·롤링 업데이트·셀프 힐링(self-healing)을 별도 설치 없이 제공합니다.

  • 쿠버네티스보다 단순: 기존 docker CLI와 Compose 문법을 거의 그대로 사용
  • 내장 기능: 서비스 디스커버리, 로드밸런싱(라우팅 메시), 롤링 업데이트, 시크릿
  • 소규모~중규모 클러스터나 운영 단순함이 중요한 경우에 적합

대규모/복잡한 생태계(오토스케일링, 커스텀 컨트롤러, 풍부한 에코시스템)가 필요하면 쿠버네티스가 사실상 표준입니다. Swarm은 "Compose에서 멀티 호스트로의 가장 쉬운 다음 단계"라는 위치를 이해하고 선택하세요.


클러스터 구성

매니저 노드 초기화

Bash
# 매니저가 될 노드에서 (--advertise-addr 는 다른 노드가 접속할 IP)
docker swarm init --advertise-addr 192.168.1.10
# Swarm initialized. To add a worker ... docker swarm join --token SWMTKN-1-...

워커 노드 조인

Bash
# init 출력의 join 명령을 워커 노드에서 실행
docker swarm join --token SWMTKN-1-xxxx 192.168.1.10:2377

조인 토큰을 다시 확인하려면:

Bash
docker swarm join-token worker      # 워커용
docker swarm join-token manager     # 매니저용

노드 확인

Bash
docker node ls
# ID          HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
# abc * ...   node1      Ready    Active         Leader
# def ...     node2      Ready    Active
역할책임
ManagerRaft로 클러스터 상태 합의, 스케줄링, API 수신
Worker할당된 태스크(컨테이너) 실행만

매니저는 가용성을 위해 **홀수(3 또는 5개)**로 두세요. Raft 합의는 과반이 필요하므로 3개 중 1개 장애까지 견딥니다. 매니저 2개는 오히려 단일 장애에 취약합니다.


서비스 배포와 스케일링

Swarm의 배포 단위는 컨테이너가 아니라 **서비스(service)**이며, 서비스는 여러 복제본(replica) 태스크로 실행됩니다.

Bash
# nginx 서비스 3개 복제본으로 배포, 80포트 외부 노출
docker service create --name web --replicas 3 -p 80:80 nginx:1.27

docker service ls
docker service ps web      # 어느 노드에서 도는지 태스크 단위 확인

스케일링

Bash
docker service scale web=5
# 또는
docker service update --replicas 5 web

셀프 힐링 확인

컨테이너를 죽이거나 노드가 빠져도 Swarm이 원하는 복제본 수를 유지합니다.

Bash
docker rm -f <task-container>     # 워커 노드에서 강제 종료
docker service ps web             # 자동으로 새 태스크가 재생성됨

라우팅 메시와 게시 모드

서비스를 -p 80:80으로 게시하면 모든 노드의 80포트로 들어온 요청이 라우팅 메시를 통해 복제본으로 분산됩니다. 해당 복제본이 그 노드에 없어도 자동 전달됩니다.

Bash
# ingress(기본): 모든 노드에서 접근 + 부하분산
docker service create --name web -p 80:80 nginx

# host: 해당 컨테이너가 실제로 있는 노드에서만 노출
docker service create --name web \
  --publish published=80,target=80,mode=host nginx

오버레이 네트워크

여러 호스트에 걸친 서비스 간 통신은 오버레이 네트워크로 처리합니다. 같은 네트워크의 서비스는 서비스명으로 DNS 통신할 수 있습니다.

Bash
docker network create --driver overlay --attachable appnet

docker service create --name api --network appnet myapi:1.0
docker service create --name web --network appnet -p 80:80 myweb:1.0
# web 컨테이너 안에서 'http://api:8080' 으로 접근 가능 (내장 VIP 로드밸런싱)

롤링 업데이트와 롤백

Bash
docker service create --name web --replicas 4 \
  --update-parallelism 1 \          # 한 번에 1개씩
  --update-delay 10s \              # 사이 10초 대기
  --update-failure-action rollback \ # 실패 시 자동 롤백
  nginx:1.26

# 이미지 교체 → 무중단 롤링
docker service update --image nginx:1.27 web

# 수동 롤백
docker service rollback web
옵션의미
--update-parallelism동시에 갱신할 태스크 수
--update-delay배치 사이 대기 시간
--update-failure-action실패 시 pause/continue/rollback
--update-orderstart-first(새 것 먼저) / stop-first

Stack — Compose로 멀티서비스 배포

여러 서비스를 한 파일로 묶어 배포하는 것이 Stack입니다. deploy: 섹션이 Swarm 전용입니다.

YAML
# stack.yml
version: "3.9"
services:
  web:
    image: myweb:1.0
    ports: ["80:80"]
    networks: [appnet]
    deploy:
      replicas: 3
      update_config: { parallelism: 1, delay: 10s }
      restart_policy: { condition: on-failure }
      placement:
        constraints: [node.role == worker]   # 워커에만 배치
  api:
    image: myapi:1.0
    networks: [appnet]
    deploy:
      replicas: 2
      resources:
        limits: { cpus: "0.5", memory: 256M }
networks:
  appnet: { driver: overlay }
Bash
docker stack deploy -c stack.yml myapp
docker stack services myapp
docker stack ps myapp
docker stack rm myapp

Secret과 Config

Swarm은 시크릿/설정을 암호화해 Raft 로그에 저장하고, 실행 중인 컨테이너에만 /run/secrets/<name>으로 마운트합니다.

Bash
echo "S3cr3t!23" | docker secret create db_pass -

docker service create --name api \
  --secret db_pass myapi:1.0
# 컨테이너 안: cat /run/secrets/db_pass

Secret은 환경변수가 아니라 **파일(tmpfs)**로만 노출되어 환경변수 유출 위험이 낮습니다. Compose에서는 secrets: 섹션과 external: true로 참조합니다.


운영 명령 모음

Bash
docker service logs -f web              # 서비스 로그 집계
docker node update --availability drain node2   # 노드 비우기(점검 전)
docker node update --availability active node2  # 복귀
docker node rm node2                    # 워커 제거(먼저 drain 권장)
docker swarm leave                      # 워커가 클러스터 탈퇴
docker swarm leave --force              # 매니저 강제 탈퇴
증상점검
서비스가 Pending리소스 제약/placement 조건 불충족
노드 Downdocker 데몬 상태, 2377/7946/4789 포트 방화벽
서비스 간 통신 불가같은 overlay 네트워크인지, DNS(서비스명) 확인

정리

항목핵심
초기화docker swarm init / join
매니저 수홀수(3·5), Raft 과반 합의
배포 단위service → replica 태스크
부하분산라우팅 메시(ingress)
서비스 통신overlay 네트워크 + 서비스명 DNS
업데이트롤링(parallelism/delay) + 자동 롤백
멀티서비스docker stack deploy (deploy 섹션)
비밀정보secret → /run/secrets 파일 마운트

Swarm은 Compose 사용자가 멀티 호스트로 넘어가는 가장 부드러운 길입니다. 매니저를 홀수로 두고, 오버레이 네트워크로 서비스를 연결하며, 롤링 업데이트와 secret을 활용하면 별도 설치 없이 견고한 소규모 클러스터를 운영할 수 있습니다.

#docker#swarm#cluster#orchestration#scaling
편집 안내 · Editorial Note

이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.

관련 공식 문서Docker 공식 문서

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.