본문 바로가기
AI Journey/클라우드

[Docker Swarm] 컨테이너 및 노드 장애 복구 메커니즘

by 보눔비스타 2026. 1. 15.

Docker Swarm을 오케스트레이션 도구로 사용하는 가장 큰 이유는 서비스의 안정성을 보장하기 위함이다.

Swarm 모드는 사용자가 선언한 'Desired State(목표 상태)'를 지속적으로 유지하려는 성질을 가진다.

즉, 특정 컨테이너가 죽거나 노드 자체가 다운되더라도, Swarm 매니저는 이를 감지하고 스스로 복구(Self-healing)한다.

 

Docker Swarm 클러스터를 구성하고, 컨테이너 강제 삭제와 노드 셧다운을 해 봄으로써 Swarm의 장애 복구 과정을 체험해보자.

1. 테스트 환경 준비

가상머신(VMware 등)을 이용해 master 노드 1대와 slave1, slave2 워커 노드 2대를 준비한다.

테스트를 위해 nginx 이미지를 기반으로 한 testweb 서비스가 레플리카(Replica) 3개로 실행 중인 상황을 가정한다.

Desired State (목표 상태) :

Swarm 매니저는 서비스가 생성될 때 정의된 레플리카 수를 기억한다.

현재 실행 중인 컨테이너 수(Current State)가 목표 수(Desired State)와 달라지면, 매니저는 즉시 개입하여 상태를 일치시킨다.

2. 시나리오 1️⃣: 단일 컨테이너 장애 복구 (Container Failover)

첫 번째 단계로 워커 노드에서 실행 중인 컨테이너 하나를 강제로 종료(삭제)했을 때 Swarm이 어떻게 반응하는지 확인한다.

2.1 현재 상태 확인 및 컨테이너 삭제

먼저 slave1 노드에서 실행 중인 컨테이너 목록을 확인하고, nginx 컨테이너 중 하나를 삭제한다.

 

# slave1 노드에서 실행
docker ps -a 
# ... (생략) ...
# 1baf27b89069   nginx:latest   ...   Up 11 minutes   testweb.3.n07ixp661qg6brcttqix7j1qe
# ... (생략) ...

# 컨테이너 강제 삭제 (장애 상황 시뮬레이션)
docker rm -f testweb.3.n07ixp661qg6brcttqix7j1qe
testweb.3.n07ixp661qg6brcttqix7j1qe

2.2 Swarm 매니저의 복구 동작 확인

Master 노드에서 서비스 상태를 조회하면 Swarm이 어떻게 대응했는지 알 수 있다.

# master 노드에서 실행
docker service ps testweb
ID             NAME             IMAGE          NODE      DESIRED STATE    CURRENT STATE            ERROR                         PORTS
qkojdj15cfir   testweb.3        nginx:latest   slave1    Running          Running 26 seconds ago                                 
n07ixp661qg6    \_ testweb.3    nginx:latest   slave1    Shutdown         Failed 31 seconds ago    "task: non-zero exit (137)"

 

  • slave1의 Docker 데몬이 컨테이너 종료(exit code 137)를 감지하고 Swarm 매니저에게 보고한다.
  • 매니저는 testweb 서비스의 목표 레플리카 수가 3개임을 확인한다.
  • 현재 2개만 실행 중이므로, 즉시 새로운 testweb.3 태스크를 생성하여 스케줄링한다.
  • 결과적으로 삭제된 컨테이너는 'Failed' 상태로 기록되고, 새로운 컨테이너가 'Running' 상태로 대체된다.

 

2.3 컨테이너 복구 메커니즘

이 과정은 매니저와 워커 노드 간의 끊임없는 상태 동기화(Reconciliation Loop)를 통해 이루어진다.

 

3. 시나리오 2️⃣: 노드 장애 및 리스케줄링 (Node Failover)

이번에는 단순히 컨테이너가 죽는 것이 아니라, 서버(노드) 자체가 다운되는 장애 상황을 가정해 본다.

3.1 노드 셧다운 (장애 발생)

slave1 노드를 강제로 종료(power off)하여 물리적 장애 또는 OS 크래시 상황을 연출한다.

# slave1 노드에서 실행
shutdown -h now

 

이후 Master 노드에서 노드 상태를 확인하면 slave1의 상태가 Down으로 변경된 것을 볼 수 있다.

# master 노드에서 실행
docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
zusguu0rpklsrwnb1xwmwcnm5 *   master     Ready     Active         Leader           24.0.2
dk76134jj99r7mxfwqyrt47an     slave1     Down      Active                          24.0.2
# ... (생략) ...

 

3.2 서비스 리스케줄링 (Rescheduling) 확인

slave1이 다운됨에 따라 해당 노드에서 돌고 있던 testweb.3 컨테이너도 함께 사라졌다. Swarm은 이를 어떻게 처리했을까?

# master 노드에서 실행
docker service ps myweb2
ID             NAME             IMAGE          NODE      DESIRED STATE    CURRENT STATE             ERROR
8d9msv655z4o   testweb.3        nginx:latest   slave2    Running          Running 10 seconds ago    
qkojdj15cfir    \_ testweb.3    nginx:latest   slave1    Shutdown         Running 2 minutes ago

 

 

  • 매니저는 slave1과의 헬스 체크 실패를 감지하고 해당 노드를 Unreachable 또는 Down으로 판정한다.
  • slave1에 할당되었던 태스크(testweb.3)가 더 이상 실행 불가능함을 인지한다.
  • 가용 가능한 다른 노드(slave2)를 찾아 해당 태스크를 이전(Rescheduling) 시킨다.
  • 로그를 보면 testweb.3이 slave1에서 Running(과거 상태)이었으나, 새로운 인스턴스가 slave2에서 Running 중임을 확인할 수 있다.

3.3 노드 장애 복구 로직

노드 장애 시 컨테이너가 다른 노드로 이사(Migration)가는 로직은 다음과 같다.

 

 

4. 노드 복구와 클러스터 재합류

 

마지막으로 다운되었던 slave1 노드를 다시 부팅하면 어떻게 되는지 확인한다.

4.1 노드 재부팅 및 상태 확인

slave1을 부팅한 후 Master에서 노드 목록을 조회한다.

# slave1 재부팅 후 master에서 확인
docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
dk76134jj99r7mxfwqyrt47an     slave1     Ready     Active                          24.0.2
# ... (생략) ...

 

 

  • 별도의 설정 없이도 노드가 부팅되어 Docker 데몬이 실행되면, 기존에 저장된 Swarm 인증 정보를 이용해 자동으로 클러스터에 합류하며 상태가 Ready로 변경된다.
  • 주의점: 노드가 돌아왔다고 해서 다른 노드로 옮겨갔던 컨테이너가 즉시 slave1로 다시 돌아오지는 않는다(Rebalancing은 별도 작업 필요). 이는 불필요한 컨테이너 이동을 막기 위함이다.

5. 정리

  1. 컨테이너 레벨의 복구: 컨테이너 프로세스가 종료되면 즉시 동일한 노드(혹은 다른 노드)에서 재시작하여 서비스 연속성을 유지한다.
  2. 노드 레벨의 복구: 물리적 서버 장애 발생 시, 해당 서버의 작업량을 살아있는 다른 서버로 자동으로 분산시킨다.