2023. 10. 30. 00:00ㆍBACKEND/Docker & Kubernetes
본 포스팅은 Docker Swarm 과 Service의 개념을 익히고 실제 사용할 수 있도록 데모를 실행해보는 것을 목표합니다.
📌 Docker Series
Docker Engine, 제대로 이해하기 (1) - docker engine deep dive
Docker Engine, 제대로 이해하기 (2) - namespace, cgroup
Docker Network, 제대로 이해하기 (1) - libnetwork
Docker Network, 제대로 이해하기 (2) - bridge, host, none drivers
> Docker Swarm, 제대로 이해하기 - Swarm & Service
Docker Swarm
: 여러 도커 호스트를 클러스터로 묶어 주는 컨테이너 오케스트레이션 도구의 한 종류
Swarm으로 클러스터의 앞 쪽에서 하나 이상의 도커 노드를 그룹화하여 클러스터로 관리할 수 있습니다.
도커 호스트 여러 대를 사용할 때, 컨테이너 오케스트레이션 도구 없이는 확장성있는 애플리케이션을 만들기가 매우 어렵습니다.
어느 도커 호스트에 어떤 컨테이너를 배치해야 할지,
서로 다른 호스트에 위치한 컨테이너간의 통신은 어떻게 제어하는지 등의 조율을 오케스트레이션 도구없이 하기에는 무리가 있습니다.
오케스트레이션 도구를 도입하면 이러한 조율에 수고를 줄여 줄 뿐만아니라,
호스트가 여러대로 나뉘어 있다는 점을 신경 쓰지 않고,
클러스터를 투명하게 다룰 수 있다는 이점도 있습니다.
컨테이너 그룹을 오케스트레이션하기 위해서 알아볼 키워드를 정리하자면, 아래와 같습니다.
이름 | 역할 | 대응하는 명령어 |
Compose | 여러 컨테이너로 구성된 도커 애플리케이션을 관리 (주로 단일 호스트) | docker-compose |
Swarm | 클러스터 구축 및 관리(주로 멀티 호스트) | docker swarm |
Service | 스웜에서 클러스터 안의 서비스(컨테이너 하나 이상의 집합)를 관리 | docker service |
Stack | 스웜에서 여러개의 서비스를 합한 전체 애플리케이션을 관리 | docker stack |
Swarm 은 아래의 두 가지 용도로 사용할 수 있습니다.
✔️ 상용 도커 호스트의 보안 클러스터
An enterprise-grade secure cluster of Docker hosts
✔️ 마이크로서비스 앱의 오케스트레이터
An orchestrator of microservices apps
📌 Benefits
Swarm은 따로 설치나 설정 없이도 바로 사용할 수 있는 Out-of-the-box 서비스로 아래와 같은 기능을 제공합니다.
- 암호화된 분산 클러스터 스토어 Encrypted distributed cluster store
- 암호화된 네트워크 Encrypted networks
- Mutual TLS
- 보안을 위한 클러스터 조인 토큰 Secure cluster join tokens
- 인증서 관리 및 재발급을 쉽게 해주는 PKI
또, 노드를 중단 없이 non-disruptively 추가 및 제거할 수도 있습니다.
오케스트레이션 앞 쪽에서, 스웜으로 복잡한 마이크로서비스 앱을 쉽게 배포하고 관리할 수 있습니다.
앱을 정의하는 파일을 제작한 후, 네이티브 도커 명령으로 스웜에 배포할 수 있습니다.
뿐만 아니라, 도커가 기본으로 제공하는 간단한 명령으로 롤링 업데이트, 롤백, 스케일링 작업까지 수행할 수 있습니다.
Swarm은 쿠버네티스 Kubernetes 와 비슷하게 컨테이너화된 애플리케이션을 오케스트레이션합니다.
쿠버네티스는 훨씬 더 많은 탄력성과 더 활발한 커뮤니티 및 생태계를 가지고 있지만,
Swarm은 쉽게 사용할 수 있고, 많은 중소기업과 애플리케이션 배포 시 채택되고 있습니다.
혹은, 쿠버네티스를 학습하기 위해 Swarm을 먼저 알아두면 큰 도움이 될 수 있습니다.
Commands
데모를 생성하기 전에, 사용할 모든 명령어들을 먼저 훑어 보겠습니다.
✔️ docker swarm init
: 새로운 swarm 생성
해당 명령어를 실행하는 노드가 첫 번째 관리자가 되어, swarm mode로 실행되도록 전환됩니다.
✔️ docker swarm join-token
: worker와 manager를 swarm에 포함시키기 위해 필요한 명령과 토큰 발급
새로운 manager를 가입시키기 위해서 docker swarm join-token manager 명령을 사용합니다.
새로운 worker를 가입시키기 위해서 docker swarm join-token worker 명령을 사용합니다.
토큰은 반드시 안전하게 보관합니다.
✔️ docker node ls
: swarm 내의 모든 노드를 나열
어떤 게 manager인지 또 어떤 게 leader 인지를 포함한 모든 노드를 확인할 수 있습니다.
✔️ docker service create
: 새로운 서비스를 만드는 명령어
✔️ docker service ls
: 실행 중인 서비스를 나열
실행 중인 서비스를 확인할 수 있어, 서비스 상태 및 실행 중인 replicas에 대한 기본 정보를 확인할 수 있습니다.
✔️ docker service ps <service>
: 특정 서비스 replicas에 대한 보다 자세한 정보 제공
✔️ docker service inspect
: 서비스에 대한 매우 상세한 정보 제공
가장 중요한 정보만을 확인하려면 위해 --pretty
플래그를 입력할 수 있습니다.
✔️ docker service scale
: 서비스의 복제본 수를 확장하거나 수축
✔️ docker service update
: 실행 중인 서비스의 많은 속성을 업데이트
✔️ docker service logs
: 서비스의 로그 확인
✔️ docker service rm
: swarm에서 서비스를 삭제
확인을 요구하지 않고 모든 서비스 복제본을 삭제하므로 주의하여 사용해야 합니다.
Swarm Hands-on
실제 swarm을 제작해보겠습니다.
Single engine mode vs Swarm mode
swarm에 포함되지 않은 도커 노드는 single-engine mode라고 합니다.
swarm에 추가되면 자동으로 swarm mode로 전환됩니다.
single-engine mode로 도커 호스트에서 docker swarm init
을 실행하면,
해당 노드가 swarm mode로 전환되고, 새로운 swarm을 생성하며 노드가 스웜의 첫 번째 관리자가 됩니다.
그러면 추가 노드를 worker 또는 manager로 포함될 수 있으며,
이 때 자동으로 swarm mode로 전환됩니다.
Overview
실제 진행할 데모에 대해 알아보겠습니다.
먼저, Manager 2대, Worker 3대의 컨테이너를 생성합니다.
스웜을 구축하는 과정을 스웜 초기화라고 하며, 크게 아래의 과정으로 진행됩니다.
1. Manager 초기화 및 등록 Initialize the first manager
2. Workers 등록 Join workers
✔️ manager
Control plane 관리. Cluster의 상태 관리나 worker에게 task를 보내는 것과 같은 swarm 전체를 제어하는 역할
✔️ worker
manager로부터 작업을 수락하고 실행
Manager 1 에서 새로운 swarm을 생성하기 위해 초기화 명령어를 입력합니다.
그런 다음 Worker 1, Worker 2 및 Worker 3를 워커 노드로 합류시키는데,
이 과정에서 해당 컨테이너들은 자동으로 swarm mode로 전환됩니다.
마지막으로 Manager 2 를 추가 관리자로 등록하는데, 이 때도 동일하게 자동으로 swarm mode로 전환됩니다.
모든 과정이 끝나면 5개 노드 모두 swarm mode임을 확인할 수 있으며, 동일한 swarm로써 작동하게 됩니다.
📌 여러 대의 도커 호스트로 스웜 클러스터 구성하기
Docker Machines
여러 대의 도커 호스트를 만들 수 있으며, 도커 머신즈를 사용하려면 macos 에서는 virtualbox 드라이버, 윈도우에서는 hyperv 드라이버가 각각 필요합니다.
Virtual Box
같은 가상화 소프트웨어를 사용하면 물리 호스트 1대에 여러 대의 도커 호스트를 실행할 수 있음 도커 공식 참조 문서에서도 이 방법을 소개하고 있습니다.
Docker in Docker
= dind. 도커 호스트 역할을 할 도커 컨테이너를 여러 개 실행하는 방법이며, 도커 컨테이너 안에서 도커 호스트를 실행할 수 있습니다.
1. docker-compose 작성
먼저, swarm이라는 디렉토리 하나를 생성해서 docker-compose를 구성합니다.
❯ mkdir swarm
❯ cd swarm
❯ vi docker-compose.yml
version: "3"
services:
registry:
container_name: registry
image: registry:2.6
ports:
- 5000:5000
volumes:
- "./registry-data:/var/lib/registry"
manager:
container_name: manager
image: docker:dind
privileged: true
tty: true
ports:
- 8000:80
- 9000:9000
depends_on:
- registry
expose:
- 3375
command: "--insecure-registry registry:5000"
volumes:
- "./stack:/stack"
worker01:
container_name: worker01
image: docker:dind
privileged: true
tty: true
depends_on:
- manager
- registry
expose:
- 7946
- 7946/udp
- 4789/udp
command: "--insecure-registry registry:5000"
worker02:
container_name: worker02
image: docker:dind
privileged: true
tty: true
depends_on:
- manager
- registry
expose:
- 7946
- 7946/udp
- 4789/udp
command: "--insecure-registry registry:5000"
worker03:
container_name: worker03
image: docker:dind
privileged: true
tty: true
depends_on:
- manager
- registry
expose:
- 7946
- 7946/udp
- 4789/udp
command: "--insecure-registry registry:5000"
2. docker-compose 실행
이제 docker-compose.yml 실행합니다.
❯ docker-compose up -d
[+] Running 6/6
✔ Network swarm_default Created 0.0s
✔ Container manager02 Started 0.8s
✔ Container manager01 Started 0.6s
✔ Container worker02 Started 1.8s
✔ Container worker01 Started 1.7s
✔ Container worker03 Started
💣 오류 발생
Your kernel does not support cgroup memory limit
🔮 해결
: Apple M2 Chip에서 발생한 오류로, docker-image 변경함
Before
image: docker:18.05.0-ce-dind
After
image: docker:dind
3. 새로운 swarm 초기화
docker swarm init
명령어로 도커를 manager로 지정합니다.
❯ docker container exec -it manager01 docker swarm init
Swarm initialized: current node (2kgbjysdan5582hetvrlz0a66) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1dke3... 172.21.0.2:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
위의 명령어와 같이 swarm init
명령 성공하게 되면, 해당 도커 호스트는 manager로 마킹되면서
swarm mode가 활성화됩니다.
종료 후 출력된 join 토큰을 확인할 수 있습니다.
해당 토큰을 통해 worker docker 를 해당 manager가 관리하게끔 만듭니다.
Token
토큰은 위처럼 생성 시 확인할 수도 있고, join-token 명령어를 통해 확인할 수 있습니다.
Worker를 등록하고자 토큰을 발급하고 싶다면, 아래와 같이 worker 를 입력합니다.
❯ docker container exec -it manager01 docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-543ojw1... 172.23.0.2:2377
또 다른 manager를 등록하고자 한다면, manager를 입력하여 발급받습니다.
❯ docker container exec -it manager01 docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-543ojw1... 172.23.0.2:2377
4. Swarm에 Worker 등록
worker 컨테이너에서 manager 컨테이너를 식별하도록 manager:2377 로 join 토큰 전달합니다.
❯ docker container exec -it worker01 docker swarm join --token SWMTKN-1-1dke3... manager01:2377
This node joined a swarm as a worker.
나머지도 등록해줍니다.
❯ docker container exec -it worker02 docker swarm join --token SWMTKN-1-1dke3... manager01:2377
This node joined a swarm as a worker.
❯ docker container exec -it worker03 docker swarm join --token SWMTKN-1-1dke3... manager01:2377
This node joined a swarm as a worker.
5. Swarm에 추가 Worker 등록
추가 manager를 등록합니다.
위에서 살펴본 join-token 명령어에 manager를 입력하여 발급받습니다.
❯ docker container exec -it manager01 docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1dke3... 172.21.0.2:2377
발급받은 토큰을 이용해 manager로 등록해줍니다.
❯ docker container exec -it manager02 docker swarm join --token SWMTKN-1-1dke3js... manager01:2377
This node joined a swarm as a manager.
6. Swarm cluster 상태 확인
그럼 이후 manager에 등록된 노드들을 확인할 수 있습니다.
❯ docker container exec -it manager01 docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ifc8dg8cdl0rwvw66lfd8yhha 0bfa1e8e38bc Ready Active Reachable 24.0.6
fynomalhu2fryrut2hh2e75dx 055ede599440 Ready Active 24.0.6
cslu1q9tv2vqcgch8ji9rjff5 77539678ba45 Ready Active 24.0.6
xqsafi0huh7azu1sg2dyfk5r3 * ac9c5449faa0 Ready Active Leader 24.0.6
r5umbj98vrl6huftnhwrqou1k cbcf19990e5e Ready Active 24.0.6
Swarm Lock
이전 manager를 다시 시작하거나, 이전 백업을 복원하면 클러스터에 충돌이 발생할 수 있습니다.
이전 manager가 다시 조인하면 암호를 해독하여 Raft log time-series database에 액세스할 수 있고,
현재의 Swarm configuration을 오염시키거나 삭제할 수도 있습니다.
이러한 상황을 방지하기 위해 도커는 Autolock 기능으로 스웜을 잠글 수 있습니다.
이는 클러스터에 다시 들어가기 전에 관리자가 키를 제시하도록 강제합니다.
초기화 과정에서 --autolock
플래그를 docker swarm init
명령에 전달하여 스웜을 잠글 수 있지만,
이미 Swarm을 구축했기 때문에 docker swarm update
명령을 사용하여 Swarm을 잠가야 합니다.
Swarm의 manager에게 다음 명령을 실행합니다.
$ docker swarm update --autolock=true
Swarm updated.
To unlock a swarm manager after it restarts, run the `docker swarm unlock` command and
provide the following key:
SWMKEY-1-XDeU3XC75Ku7rvGXixJ0V7evhDJGvIAvq0D8VuEAEaw
Please remember to store this key in a password manager, since without it you will not be able
to restart the manager.
잠금 해제 키는 안전한 장소에 보관해야 합니다.
docker swarm unlock-key
명령으로 항상 현재 스웜 잠금 해제 키를 확인할 수 있습니다.
관리자 노드 중 하나를 재시작하여 클러스터에 자동으로 재가입되는지 확인합니다.
명령어 앞에 sudo를 붙여야 할 수도 있습니다.
$ service docker restart
# Try and list the nodes in the swarm.
$ docker node ls
Error response from daemon: Swarm is encrypted and needs to be unlocked before it can be used.
Docker service가 관리자에서 다시 시작되었지만 Swarm에 다시 조인하는 것은 허용되지 않았습니다.
다른 관리자 노드에서 docker node ls
명령을 실행해서 확인할 수 있습니다.
다시 시작된 manager는 down
과 unreachable
로 표시됩니다.docker swarm unlock
명령을 실행하여, 재시작된 관리자에 대한 docker swarm unlock
명령을 실행합니다.
재시작된 manager에 대해 이 명령을 실행하고, 이 때 unlock 키를 함께 제공해야 합니다.
$ docker swarm unlock
Please enter unlock key: <enter your key>
노드는 swarm에 다시 가입할 수 있으며, 만약 docker node ls
명령을 하게 되면 ready
와 reachable
로 표시 됩니다.
운영 환경에서는 스웜을 잠그고 unlock 키를 보호하는 것이 좋습니다.
Docker Service
위에서 생성한 Swarm을 배포하기 위해 Service를 생성하여 한 번에 배포합니다.
단일 도커 컨테이너 배포는 docker container run
명령으로 컨테이너를 하나씩 실행하거나,
compose 를 통해 여러 컨테이너 동시 실행하곤 합니다.
Swarm 은 아래와 같이 넓은 범위를 아우르게 구성될 수 있기 때문에,
애플리케이션을 구성하는 일부 컨테이너를 제어하기 위한 단위로 서비스라는 개념을 가집니다.
이번에는 생성한 Swarm을 배포해보겠습니다.
1. Service 생성
먼저, leader manager에 접속해서 서비스를 하나 생성합니다.
❯ docker container exec -it manager01 docker service create --replicas 1 --publish 8000:8000 --name echo gngsn/echo:latest
overall progress: 0 out of 1 tasks
1/1: preparing [=================================> ]
2. Service 확인
다음, 서비스가 제대로 생성되었는지 확인합니다.
❯ docker container exec -it manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
6royaikec2pg echo replicated 1/1 gngsn/echo:latest *:8000->8000/tcp
3. Service Scaling
만약, 서비스 내에서 동일한 컨테이너 수를 늘리고 싶을 땐 어떻게 해야 할까요?
각각의 컨테이너 수만큼 docker container run
명령을 반복해야겠지만, 현실적이지 않습니다.
docker service scales
: 레플리카 수 조절
위 명령어는 자동으로 컨테이너를 복제하고 여러 노드에 배치합니다.
이를 통해 애플리케이션을 쉽게 스케일 아웃할 수 있습니다.
❯ docker container exec -it manager docker service scale echo=6
늘어난 REPLICAS 확인해보면, 6 개로 늘어난 것을 확인할 수 있습니다.
❯ docker container exec -it manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
js126i5zxbe0 echo replicated 6/6 registry:5000/gngsn/echo:latest *:8000->8000/tcp
4. Service 삭제
생성한 서비스는 아래와 같이 제거할 수 있습니다.
❯ docker container exec -it manager docker service rm echo
echo
제거한 서비스를 확인해봅니다.
❯ docker container exec -it manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
FYI.
✔️ 서비스는 레플리카 수(컨테이너 수)를 조절해 컨테이너를 쉽게 복제할 수 있으며, 여러 노드에 레플리카를 배치할 수 있기 때문에 스케일 아웃에 유리
✔️ 서비스로 관리되는 (여러 개의) 레플리카는 서비스명으로 name resolution 되므로 서비스에 대한 트래픽이 각 레플리카로 분산됨
✔️ 스웜 클러스터 외부에서 스웜에 배포된 서비스를 이용하려면 서비스에 트래픽을 분산시키기 위한 프록시를 갖춰야 함
'BACKEND > Docker & Kubernetes' 카테고리의 다른 글
Kubernetes Architecture, 제대로 이해하기 (0) | 2024.03.03 |
---|---|
Kubernetes Architecture, 제대로 이해하기 - Control Plane (2) | 2023.11.22 |
Docker, 제대로 사용하기 - Commands (2) | 2023.10.17 |
Docker Network, 제대로 이해하기 (2) (1) | 2022.02.15 |
Docker Network, 제대로 이해하기 (1) (3) | 2022.02.09 |
Backend Software Engineer
𝐒𝐮𝐧 · 𝙂𝙮𝙚𝙤𝙣𝙜𝙨𝙪𝙣 𝙋𝙖𝙧𝙠