
Docker Swarm으로 가볍게 오케스트레이션 맛보기
사이드 프로젝트를 진행하다 오케스트레이션의 도입의 필요성을 느끼게 되었습니다.
다들 사용하는 Kubernetes에 대한 공부를 하던 중 문득 이런 생각이 들었습니다.
솔직히 우리 규모에 쿠버네티스(Kubernetes, k8s)까지 필요한가?
물론 쿠버네티스는 강력한 툴입니다. 하지만 러닝 커브가 매우 높고, 유지 보수 비용이 높으며, 작은 프로젝트에는 오버 스펙이 될 수도 있습니다. 오늘은 그 대안으로 Docker Swarm을 살펴보고 사용하기에 적합한지 살펴보겠습니다.
0. Docker Swarm에 대해서..
Docker Swarm을 사용하는 이유에 앞서서 Docker Swarm에 대해서 간단히 그림을 통해 알아보고자 합니다.

위의 그림을 보면 Docker Swarm의 모델을 볼 수 있습니다.
Docker Swarm은 Manager/Worker 노드로 구성되어 있으며, Manager 노드는 클러스터 전체 상태 관리, 스케쥴링, 명령 처리 등 도커 스웜의 매니징 역할을 합니다. Worker 노드는 Manager 노드에서 전달된 명령을 수행(컨테이너를 실행하고, 호스팅) 하는 역할을 합니다. (물론 Manager 노드에서도 컨테이너를 동작 시킬 수 있습니다.)
단순하게 요약해보자면, Docker Swarm은 여러 개의 물리 서버 도커 환경을 하나의 도커 환경처럼 묶는 기술입니다.
우리는 로컬 도커 환경을 사용할 때 포트를 직접 외부와 매핑하고, 연결하여 사용합니다. 그렇다면 Docker Swarm 환경에서 우리가 컨테이너를 동작시키면 우리는 어떻게 그 위치를 알 수 있을까요?
- 직접 Manager/Worker 노드를 순회하며 컨테이너 포트를 찾는다.
- Docker Swarm에서 직접 모든 포트를 관리한다.
위와 같은 두가지 경우가 있을 것 같습니다. 여기에서 조금만 생각해봐도 1번에 문제가 있다는 것을 알 수 있죠? 저런 방식으로 오케스트레이션을 사용한다면, 사용하는 이유가 불분명해 질 수 있습니다. 이러한 문제점을 해결하기 위해서 Docker Swarm에서는 Ingress 네트워크 방식을 지원합니다.
1. Ingress와 Host Port: 네트워크의 이해
여러 컨테이너를 여러 서버에 올릴 때에 가장 헷갈리는 것이 바로 네트워크입니다. Docker Swarm에서는 두 가지 방식을 지원합니다.
Host Port (Node Port) 방식
가장 직관적인이고 익숙한 방식일 것입니다. 호스트(서버)의 특정 포트를 컨테이너의 포트와 직접 연결합니다.
- 예시:
8080:80(서버의 8080으로 들어오면 컨테이너의 80으로 연결) - 단점: 특정 노드에 컨테이너가 죽으면 서비스가 중단될 수 있고, 포트 충돌(Port Conflict)을 신경 써서 운영해야 합니다.
Ingress (Routing Mesh) 방식
Docker Swarm의 핵심 클러스터링 기술입니다.
- 동작 방식: 외부에서 클러스터 내의 어떤 노드로 요청을 보내든, 스웜의 Ingress Network(Routing Mesh)가 알아서 해당 서비스가 실행 중인 컨테이너로 트래픽을 전달해 줍니다.
- 장점:
- 로드 밸런싱이 자동으로 수행됩니다. (Replicas 내에서 기본적으로 Round Robin 방식으로 수행)
- 클라이언트가 어떤 노드에 컨테이너가 떠 있는지 알 필요가 없습니다.
- 단점:
- 고가용성이 요구되는 환경에서는 네트워크 레이턴시가 문제 될 수 있습니다. (어쨌든 하나의 홉을 추가로 거치게됨)
우선 말로만 설명하니 이해가 어려울 것 같아서 아래의 그림을 예시로 설명해보겠습니다.

3개의 노드로 구성된 Docker Swarm이 있습니다. 이제 우리가 호스팅할 my-web이라는 애플리케이션은 두 개가 동작하고 있습니다. 이러한 my-web에 위치에 상관없이 node1, node2, node3에 어느 8080포트로 접속하든 my-web 서비스를 사용자는 이용할 수 있는 것입니다. 이러한 구조를 통해서 Docker Swarm은 Ingress 모드로 하나의 커다란 도커 환경처럼 동작할 수 있는 것입니다. 사용자 입장에서는 해당 my-web이라는 서비스가 어느 위치에 있는지 알필요없는 위치의 투명성이 생기게 됩니다.
다른 특징들은 아래와 같습니다.
- 라우팅 메쉬 (Routing Mesh): Swarm 클러스터의 어떤 노드로 트래픽이 들어오든, 해당 노드에 서비스(컨테이너)가 실행 중이 아니더라도 자동으로 실행 중인 컨테이너로 요청을 전달합니다.
- 오버레이 네트워크 (Overlay Network): ingress는 기본적으로 Overlay Network 드라이버를 사용하며, 클러스터 내의 물리적인 서버 위치와 상관없이 모든 컨테이너 간의 통신을 가능하게 합니다.
- 자동 생성 및 설정: Swarm 클러스터를 초기화하거나 노드를 추가할 때 자동으로 생성 및 설정되며, 별도의 복잡한 구성이 필요 없습니다.
- 내부 로드 밸런싱: Ingress 네트워크는 각 노드에 내장된 로드 밸런서(가상 IP, VIP)를 통해 기본적으로 라운드 로빈(Round-Robin) 방식으로 서비스 컨테이너 간에 트래픽을 분산합니다.
- 투명성: 외부 클라이언트는 서비스가 어느 노드에서 실행 중인지 알 필요 없이, 클러스터 내 모든 노드의 게시된 포트로 접속할 수 있습니다.
- 서비스 검색 (Service Discovery) 연동: 내부 DNS 구성 요소를 사용하여 각 서비스에 자동으로 DNS 항목을 할당하며, 이를 통해 요청을 적절한 태스크로 보냅니다.
2. Docker Swarm의 동작 원리
Docker Swarm은 크게 Manager Node와 Worker Node로 구성됩니다.
- Manager Node: 클러스터의 상태를 관리하고(Leader 선택시 Raft 합의 알고리즘 사용, 홀수로 사용하는 것을 권장), 어떤 워커 노드에 컨테이너를 배치할지 결정(스케줄링)합니다.
- Worker Node: 매니저의 지시를 받아 실제 컨테이너(Task)를 실행합니다.
- Service: 스웜에서는 컨테이너 하나하나를 관리하기보다, '서비스'라는 개념으로 관리합니다. "웹 서버를 3개 유지해 줘"라고 선언하면, 스웜이 알아서 3개의 레플리카(Replica)를 유지합니다.
3. docker-compose에서 Swarm으로 마이그레이션
Docker Swarm에서는 기존에 사용하던 docker-compose.yml 파일을 거의 그대로 사용할 수 있다는 것도 장점입니다. deploy 섹션만 추가하면 됩니다.
3.1 기존 docker-compose.yml 예시
services:
web-nginx:
image: nginx:latest
ports:
- "80:80"
3.2 Swarm용 수정 (stack 배포용) 예시
services:
web-nginx:
image: nginx:latest
ports:
- "80:80"
deploy: # 추가된 부분
replicas: 3 # 컨테이너를 3개로 복제 (레플리카)
restart_policy:
condition: on-failure
update_config: # Rolling Update 설정 - 기본 값이 롤링 업데이트입니다.
parallelism: 1
delay: 10s
여기에서 Stack이란 Docker Swarm에서 하나의 Application 단위이고, Service는 하나의 이미지로 동작하는 컨테이너 환경(같은 이미지의 여러개의 Replicas 구성)입니다. deploy 하위에 복제 개수(replicas), 배포 전략(rolling update), 리소스 제한 등을 쓰면 로컬 환경에서 바로 Swarm 클러스터 환경 설정으로 쉽게 바꿀 수 있을 것입니다.
이렇게 간단히 Docker Swarm에 대해서 살펴보았구요. deploy에 관해서는 더욱 더 많은 설정들이 있으니 도커의 정식 문서를 살펴보시길 적극 권장 드립니다.
https://docs.docker.com/engine/swarm/
Swarm mode
Docker Engine Swarm mode overview
docs.docker.com
자 이제 제가 이야기 하고 싶은 두 주제에 대해서 이야기 해보려고 합니다.
저는 항상 새로운 기술을 사용할 때 마음가짐으로 "왜 이 기술을 사용해야할까?", "더 나은 방법(쓰지 않기, 확장) 하는 방법은 없을까?" 두 가지를 고려하려고 합니다.
이러한 생각으로 "Docker Swarm 마이그레이션 시 유의점"과 "단일 호스트 상황에서도 Swarm이 좋은 선택일까?"에 대해서 이야기 해보려합니다.
4. Docker Swarm 마이그레이션 유의점
docker-compose에서 Docker Swarm 환경으로 마이그레션시에 유의해야할 점이 있을까요?
제가 이러한 문제를 인턴에서 겪게 되었는데요.
인턴 중에 Docker Swarm 환경으로 마이그레이션 POC를 생각해보는 목표가 생겼습니다. 이러한 문제에 대해서 곰곰히 생각해보았고, 저는 volume 의존성이 가장 문제가 될 것 같았습니다. 로컬 디렉토리를 volume으로 마운트하거나, 레거시 프로젝트의 일부에서 docker-compose 실행시 해당 코드 Repo를 volume 마운팅해 사용하는 경우가 있기 때문입니다.
이와 같은 더욱 더 난감한 상황이 발생하는 것을 막기 위해서 더욱더 유의해야합니다. 의존성을 최대한 stateless하게 유지하는 것이 중요하다고 생각됩니다.
이러한 상황에서 volume 의존성이 필요하다면 NFS(공유 파일 시스템) 또는 클라우드 스토리지 (AWS EFS) 같은 방법으로 volume 의존성을 하나로 뭉치는 방법도 가능하다고 생각합니다.
5. 왜 '단일 호스트(Single Host)'에서도 Swarm인가?
많은 사람들이 Docker Swarm을 '여러 대의 서버를 묶을 때만 쓰는 도구'로만 생각하는 것 같습니다. 하지만 사이드 프로젝트처럼 서버가 딱 한 대(VPS)인 환경에서도 Swarm은 docker-compose만 사용하는 것보다 좋다고 생각합니다.
왜냐하면 docker-compose에서는 사용하지 못했던 아래의 기능들을 사용할 수 있기 때문입니다.
- 무중단 배포 (Rolling Update):
docker-compose up -d는 재배포 시 필연적으로 잠깐의 다운타임이 발생합니다. Swarm은 기존 컨테이너를 유지한 채 새 컨테이너를 먼저 띄우고 트래픽을 전환하므로 서비스가 끊기지 않습니다. (사실 그냥 변경점 적용시키면 기본값으로 알아서 무중단 배포해줍니다.) - 자동 복구 (Self-Healing): 특정 컨테이너가 이유 없이 죽었을 때, Swarm은 정의된 상태(Replica 수)를 맞추기 위해 즉시 새로운 컨테이너를 실행합니다.
- Replicas 확장 준비 가능: Local Docker에서는 새로운 포트를 하나 사용하며, 확장해야합니다. 또한, 직접 로드 밸런싱 설정을 해줘야 하는 귀찮음이 늘어납니다. 이러한 상황에서 Docker Swarm은 명령어 한 줄로 서버만 추가하면 바로 클러스터가 됩니다.
6. 마치며
항상 느끼지만 기술 스택을 선정할 때 중요한 것은 '남들이 다 쓰니까'가 아니라 '우리의 프로젝트에 적합한가'입니다.
Docker Swarm은 쿠버네티스의 없이도 로드 밸런싱, 스케일링, 무중단 배포 기능을 제공합니다.
사이드 프로젝트에서 비즈니스 로직에 집중하지 못하고 인프라 관리에만 힘을 쓰게 될때, Docker Swarm은 좋은 선택지가 될 것 같습니다.
그러니까 Kuberenetes가 부담스러운 당신 Docker Swarm은 어떠신가요??
'Infra' 카테고리의 다른 글
| 아직도 Logstash만 쓰는 그대를 위한 : Fluentd 알아보기 (0) | 2025.12.08 |
|---|