목차
컨테이너 오케스트레이션 도구는 쿠버네티스 밖에 다뤄보지 않았다. Docker Swarm은 그냥 말만 들어보고 정확히 이론조차 알지 못하였는데 이번 시간에 간단하게 Swarm에 대해 알아보고 다뤄보려고 한다. 기존에 Docker Swarm과 비슷한 ECS를 다뤄보아서 이해하는데에는 큰 어려움이 없었다.
Docker Swarm
Docker Swarm은 Docker에서 제공하는 클러스터링 및 스케일링 도구로, 여러 Docker 호스트들을 하나의 클러스터로 결합하여 컨테이너를 관리하고 배포할 수 있는 기능을 제공한다. Docker Swarm을 사용하면 컨테이너를 클러스터의 여러 노드에 걸쳐 배포하여 고가용성(HA)과 확장성(스케일링)를 구현할 수 있다는 점이 일반 Docker와 다르다. 굳이 크게 쿠버네티스와 다른 점을 뽑자면 Raft알고리즘을 가진것이다. 쿠버네티스의 컨트롤 플레인과 워커노드가 완벽히 분리된 느낌이 아닌 Manager Node와 Worker Node가 함께 Raft알고리즘을 구성한다. 즉 Manager Node는 클러스터역할 뿐아니라 Worker Node의 역할도 함께 한다.
주요 개념
1. Node
Node는 Docker swarm cluster를 구성하는 각각의 Docker host이다.
- Manager Node: 클러스터를 제어하고 관리하는 역할을 한다. 서비스의 배포, 클러스터 상태 모니터링, Worker Node와의 통신 등 클러스터의 상태를 유지한다.
- Worker Node: 매니저 노드의 명령을 받아 컨테이너를 실행하는 역할을 합니다. 여러 노드에 걸쳐 작업을 분산 처리할 수 있어 클러스터의 확장성이 향상된다.
2. Service
Swarm에서 서비스는 컨테이너의 추상화된 개념으로, 특정 이미지를 기반으로 여러 노드에 컨테이너를 배포하고 관리할 수 있게 한다. 서비스는 각 노드에서 하나 이상의 task을 실행하게 되고, 필요에 따라 스케일링이 가능하다. 한마디로 Node에서 수행하고자 하는 작업(배포)의 단위로 정의할 수 있다. 쿠버네티스의 Depolyment라고 이해하면 쉽다.
3. Task
서비스의 각 인스턴스가 수행하는 개별 작업이다. Task는 특정 노드에서 실행되며, 작업이 실패하면 Swarm은 이를 감지하고 다른 노드에서 새로운 작업을 생성하여 서비스를 복구한다. 쿠버네티스의 Pod와 같다. Pod가 컨테이너를 보유하듯이 각 Task도 하나의 컨테이너를 포함한다.
4. Stack
다중 컨테이너 애플리케이션을 동작시키는 묶음이다. Docker Compose라고 보면된다. 대신 Swarm이기 때문에 단일 호스트 배포가 아닌 다중 호스트 배포에 목적을 둔다.
5. Scheduling
Service 명세에 따라 Task(컨테이너)를 node에 분배하는 작업이다. 균등 분배(Spread)방식이나 labeling을 통해 노드 범위를 제한한다. 쿠버네티스의 selector, label과 비슷한 개념이다.
6. Overlay Network
Docker는 Bridge네트워크 밖에 지원하지 않았지만 Docker Swarm은 여러 호스트 간의 네트워크 통신을 지원하는 Overlay Network를 제공한다. 이를 통해 각 노드에 있는 컨테이너들이 물리적인 호스트 경계와 상관없이 서로 통신할 수 있는 것이다.
Docker Swarm 네트워크 구조
ingress Network

외부에서 들어오는 트래픽을 Swarm 클러스터 내부의 서비스로 라우팅하기 위한 네트워크이다. Ingress 네트워크는 외부 클라이언트가 Docker Swarm 클러스터에서 실행 중인 서비스에 접근할 때 사용된다. 라우팅 메시(Routing Mesh) 기능을 통해 Swarm 클러스터의 모든 노드가 외부 요청을 받을 수 있고, Swarm은 적절한 노드로 트래픽을 라우팅한다. 이때 라우팅 메시인 IPVS가 사용된다. 이 기능 덕분에, 실제로 컨테이너가 실행되고 있지 않은 노드에서도 트래픽을 받을 수 있으며, Swarm은 해당 요청을 자동으로 컨테이너가 실행 중인 노드로 전달한다. 예를들어 클러스터 외부에서 특정 서비스의 포트를 통해 요청을 보내면, 인그레스 네트워크가 트래픽을 해당 서비스로 라우팅하고 IPVS를 이용하여 부하를 분산한다.
Overlay Network

여러 노드에 분산된 컨테이너 간의 내부 통신을 위한 가상 네트워크이다. 오버레이 네트워크는 Swarm 클러스터의 여러 호스트에 걸쳐 있는 컨테이너들이 서로 통신할 수 있도록 하는 네트워크이다. 오버레이 네트워크는 마치 같은 호스트에 있는 것처럼 여러 노드 간에 컨테이너 간의 통신을 지원한다.
Docker Swarm은 VXLAN(Virtual Extensible LAN) 기술을 사용하여 여러 물리적 노드에 걸친 네트워크를 하나의 가상 네트워크로 확장한다. 이를 통해 다른 물리적 호스트에 있는 컨테이너들이 마치 같은 네트워크 상에 있는 것처럼 통신할 수 있다.
IPVS

Docker Swarm의 부하 분산을 담당하는 기술이다.
IPVS는 클러스터의 각 노드에서 들어오는 트래픽을 여러 컨테이너 인스턴스에 라운드 로빈 방식으로 분산시킨다. 이것을 통해 여러 복제본이 실행되는 서비스에 대한 요청이 고르게 분산된다.
클라이언트의 요청이 들어오면 통신 순서는 다음과 같다.
- 외부 클라이언트의 요청이 Ingress 네트워크를 통해 Swarm 클러스터로 들어온다.
- 이 네트워크는 외부 요청을 수신하고, 이를 적절한 서비스로 라우팅한다.(IPVS 이용)
- IPVS는 요청을 부하 분산하기 위해 클러스터의 서비스 정보를 수집한다.
- 이 정보는 etcd(또는 다른 데이터 저장소)에서 가져온다. 예를 들어, 서비스의 가용성, 복제본 수, 상태 등을 확인하여 요청을 적절한 서비스 인스턴스로 전달하는 것이다.
docker_gwbridge

Swarm 내부 네트워크와 외부 네트워크 간의 게이트웨이 역할을 수행하는 브리지 네트워크이다.
클러스터 내부의 오버레이 네트워크에 있는 컨테이너들이 외부 네트워크(인터넷 등)와 통신할 수 있도록 하는 역할을 한다.
예를 들어, 외부 API 서버에 접속하거나, 외부에서 데이터를 다운로드하려고 할 때 주로 사용하는 것이라고 볼 수 있다.
비교 정리

이렇게 설명만 들었을때는 헷갈릴 수 있다. 비교하여 정리하자면 overlay network는 각 노드(호스트)간 하나의 네트워크로 연결하여 내부에서 통신하는 것이라 보면되고 Docker gwbridge는 컨테이너 내부에서 외부인터넷과의 통신 Ingress와 Ipvs는 클라이언트의 요청에 대한 부하분산처리를 한다고 이해하면된다. 그래서 Docker 단일 호스트만 사용하면 Docker0 네트워크를 연결하지만 Cluster환경에서는 호스트간의 연결인 Overlay network와 외부와의 통신을 위한 Ingress network가 생성된다.
실무에서는 보통 HAProxy를 이용해 좀 더 세밀하게 컨트롤한다.
Docker Swarm 기능 예시
노드 하나를 중지할 경우
Docker Swarm 모드에서 노드를 중지하고 다시 시작하면 해당 노드에서 실행 중이던 태스크(Task)는 자동으로 복구되지 않는다. Swarm은 노드가 장애가 발생하거나 중단된 경우, 다른 활성화된 노드에 태스크를 재분배하여 서비스를 유지하려고 한다.
Global 옵션
쿠버네티스의 Deamonset과 똑같은 역할을 한다. Global은 특정 서비스가 Swarm 클러스터의 모든 노드에서 실행되도록 설정하는 방식입니다.예를 들어, 로그 수집기나 모니터링 에이전트와 같이 모든 노드에서 실행되어야 하는 서비스를 배포할 때 사용된다.
Drain 옵션
마찬가지로 쿠버네티스의 Drain옵션과 유사하다. 노드를 Drain 상태로 설정하면, 해당 노드에서 실행 중인 모든 서비스가 더 이상 새로운 작업을 수신하지 않으며, 기존 작업은 점차 종료된다.
docker node update --availability drain <노드 이름>
Label
Label은 Docker Swarm의 객체(예: 노드, 서비스)에 대한 메타데이터를 추가하는 키-값 이다.
서비스나 노드를 찾거나 선택할 때 조건을 지정하여 특정 레이블을 가진 객체를 식별하는데 사용한다.
노드에 레이블 추가하기
docker node update --label-add <key>=<value> <node-name>
서비스에 레이블 추가하기
docker service create --name <service-name> --label <key>=<value> <image>
주로 노드에 레이블은 추가한후 Stack에 Label 키값을 정해줘서 사용한다.
'Docker' 카테고리의 다른 글
| [Docker] Dockerfile & Build & Docker-Compose (0) | 2024.10.23 |
|---|---|
| [Docker] Docker Resource Limit & Volume (0) | 2024.10.23 |
| [Docker] Docker Networking & Proxy (0) | 2024.10.21 |
| [Docker] Docker Lifecycle & Image & CLI (0) | 2024.10.20 |