Swarm 모드 핵심 개념

Swarm 모드 핵심 개념

Docker Engine 1.12에 추가된 클러스터 관리와 오케스트레이션 기능에 대해 알아볼게요. 이 문서에서는 Swarm 모드에서만 볼 수 있는 개념들을 하나씩 살펴보겠습니다. 천천히 따라오시면 어렵지 않아요.

출처: 공식문서

본문

스웜이란 무엇인가요?

Docker Engine에 내장된 클러스터 관리 및 오케스트레이션 기능은 swarmkit을 기반으로 만들어졌어요. swarmkit은 Docker의 오케스트레이션 계층을 구현하는 별도의 프로젝트인데, Docker 안에서 직접 사용된답니다.

스웜은 Swarm 모드로 실행되는 여러 Docker 호스트들로 구성돼요. 이 호스트들은 멤버십과 위임을 관리하는 매니저(manager) 역할을 하거나, swarm 서비스를 실행하는 워커(worker) 역할을 합니다. 물론 하나의 Docker 호스트가 매니저와 워커를 겸할 수도 있어요.

서비스를 만들 때는 원하는 상태(desired state)를 정의하게 돼요. 예를 들어 복제본(replica) 수, 사용할 네트워크와 스토리지 자원, 외부에 노출할 포트 등을 지정하는 거죠. 그러면 Docker가 그 상태를 유지하기 위해 계속 노력해요. 만약 어떤 워커 노드가 사용 불가능해지면, Docker는 그 노드에 있던 태스크를 다른 노드로 다시 스케줄링해요. 여기서 태스크(task)란 swarm 서비스의 일부로 실행되는 컨테이너를 말하며, 일반 standalone 컨테이너와 달리 swarm 매니저가 관리한답니다.

swarm 서비스가 standalone 컨테이너보다 좋은 점 중 하나는, 서비스 구성을 변경할 때 서비스를 직접 재시작할 필요가 없다는 거예요. 네트워크나 볼륨 연결을 바꾸더라도 Docker가 알아서 구성을 업데이트하고, 옛 구성으로 실행 중인 태스크를 중지한 다음 원하는 구성에 맞는 새 태스크를 만들어 준답니다.

Swarm 모드에서도 swarm에 참여한 Docker 호스트 어디에서든 standalone 컨테이너를 실행할 수 있어요. 다만 standalone 컨테이너와 swarm 서비스의 중요한 차이는, swarm을 관리할 수 있는 것은 매니저뿐이라는 점이에요. standalone 컨테이너는 어떤 데몬에서든 시작할 수 있지만, swarm 서비스는 매니저가 관리해야 하죠. Docker 데몬은 매니저, 워커, 또는 둘 다의 역할로 swarm에 참여할 수 있습니다.

Docker Compose로 컨테이너를 정의하고 실행하는 것처럼, Swarm 서비스 스택도 정의하고 실행할 수 있어요.

이제 노드, 서비스, 태스크, 로드 밸런싱 등 swarm 서비스와 관련된 개념들을 자세히 살펴볼게요.

노드

노드(node)는 swarm에 참여하는 Docker Engine 인스턴스를 말해요. Docker 노드라고 생각하면 됩니다. 하나의 물리 컴퓨터나 클라우드 서버에 여러 개의 노드를 실행할 수도 있지만, 실제 운영 환경에서는 보통 여러 물리 머신과 클라우드 머신에 걸쳐 Docker 노드를 분산 배치한답니다.

애플리케이션을 swarm에 배포하려면 매니저 노드에 서비스 정의를 제출해요. 그러면 매니저 노드가 태스크(task)라고 불리는 작업 단위를 워커 노드에 분배합니다.

매니저 노드는 swarm의 원하는 상태를 유지하기 위한 오케스트레이션과 클러스터 관리 기능도 수행해요. 그리고 매니저 노드들 중에서 하나의 리더(leader)를 선출해서 오케스트레이션 작업을 진행하게 됩니다.

워커 노드는 매니저 노드가 보낸 태스크를 받아서 실행해요. 기본적으로 매니저 노드도 워커 노드처럼 서비스를 실행하지만, 설정에 따라 매니저 전용 노드로 만들어 매니저 작업만 수행하게 할 수도 있어요. 각 워커 노드에는 에이전트(agent)가 실행되면서 자신에게 할당된 태스크의 상태를 보고한답니다. 워커 노드는 할당된 태스크의 현재 상태를 매니저 노드에 알려주고, 매니저는 그 정보를 바탕으로 각 워커의 원하는 상태를 유지해요.

서비스와 태스크

서비스(service)는 매니저 또는 워커 노드에서 실행할 태스크의 정의예요. swarm 시스템의 핵심 구조이자, 사용자가 swarm과 상호작용하는 가장 기본적인 단위이기도 하죠.

서비스를 만들 때는 사용할 컨테이너 이미지와 실행 중인 컨테이너 안에서 수행할 명령어를 지정해요.

replicated services 모델에서는 swarm 매니저가 desired state에서 설정한 scale(복제본 수)에 따라 특정 개수의 replica 태스크를 여러 노드에 분배합니다.

global services의 경우에는 클러스터의 모든 사용 가능한 노드에서 서비스당 하나의 태스크를 실행해요.

태스크는 Docker 컨테이너와 그 안에서 실행할 명령어를 담고 있어요. swarm의 원자적 스케줄링 단위라고 할 수 있죠. 매니저 노드는 서비스 scale에 설정된 복제본 수에 따라 워커 노드에 태스크를 할당합니다. 한 번 노드에 할당된 태스크는 다른 노드로 이동할 수 없어요. 할당된 노드에서 실행되거나, 아니면 실패할 뿐이랍니다.

로드 밸런싱

swarm 매니저는 ingress load balancing을 사용해서 swarm 외부에서 접근할 수 있도록 서비스를 노출해요. 매니저가 서비스에 published port를 자동으로 할당할 수도 있고, 직접 설정할 수도 있습니다. 사용하지 않는 포트라면 어떤 포트든 지정할 수 있어요. 포트를 지정하지 않으면 swarm 매니저가 30000-32767 범위에서 포트를 할당한답니다.

클라우드 로드 밸런서 같은 외부 구성 요소는 클러스터의 어떤 노드에서든 published port를 통해 서비스에 접근할 수 있어요. 그 노드가 현재 해당 서비스의 태스크를 실행 중이 아니어도 상관없습니다. swarm의 모든 노드는 ingress 연결을 실행 중인 태스크 인스턴스로 라우팅해 주거든요.

Swarm 모드에는 내부 DNS 구성 요소가 있어서 swarm 안의 각 서비스에 DNS 항목을 자동으로 할당해요. 그리고 swarm 매니저는 내부 로드 밸런싱을 통해 클러스터 내 서비스 간 요청을 서비스의 DNS 이름을 기준으로 분산한답니다.

더 알아보기