몇 주 전에 진행했던 CentOS 7.2 기반 튜토리얼에 이어서 이번에는 한 단계 더 나아가 보겠습니다. 앞선 가이드에서는 Docker 1.12에 내장된 네이티브 클러스터링 및 오케스트레이션 기능을 시작하고 활성화하는 방법을 다뤘습니다. 하지만 당시에는 매니저(manager) 노드만 존재했고, 작업을 수행할 워커(worker) 노드는 없었습니다.
이번 글에서는 바로 그 부분을 확장해 보겠습니다. 구체적으로는 서로 다른 배포판으로 구성된 비대칭 노드를 스웜(swarm)에 추가하는 방법을 소개합니다. 즉, 기존의 CentOS 머신 옆에 Fedora 24 노드를 배치하고, 두 시스템이 함께 클러스터에 참여하도록 구성하는 것입니다. 물론 로드밸런싱 같은 화려한 기능들도 함께 다룹니다. 과정이 순탄하지만은 않을 것이고 몇 가지 장애물도 만나게 되겠지만, 그만큼 흥미로운 내용이 될 것입니다. 그럼 시작해 보겠습니다.
사전 준비 사항
추가 노드를 스웜에 성공적으로 합류시키기 전에 몇 가지 준비해야 할 사항이 있습니다. 첫째, 모든 노드는 가능한 한 동일한 버전의 Docker를 실행해야 하며, 네이티브 오케스트레이션을 지원하려면 최소 1.12 이상이어야 합니다. CentOS와 마찬가지로 Fedora 역시 공식 저장소에서 최신 버전을 제공하지 않으므로, 수동 설치 또는 Docker 공식 저장소를 추가하여 올바른 버전을 설치한 뒤 의존성 충돌 문제를 해결해야 합니다. CentOS에서 이 작업을 수행하는 방법은 이미 앞선 튜토리얼에서 소개했으며, 절차는 동일합니다.
둘째, 모든 노드가 서로 통신할 수 있어야 합니다. 매니저와 워커가 상호 간에 대화할 수 있도록 라우팅 및 방화벽 규칙이 마련되어 있어야 하며, 그렇지 않으면 노드를 스웜에 합류시킬 수 없습니다. 문제 해결의 가장 쉬운 방법은 일시적으로 방화벽 규칙을 비우는 것(iptables -F)이지만, 이는 보안상 위험을 초래할 수 있습니다. 무엇을 하고 있는지 충분히 이해하고, 자신의 환경에 맞는 올바른 노드·포트 규칙을 직접 생성해야 합니다.
Error response from daemon: Timeout was reached before node was joined. The attempt to join the swarm will continue in the background. Use the "docker info" command to see the current swarm status of your node.
또한 모든 호스트에 동일한 Docker 이미지가 준비되어 있어야 합니다. 이전 튜토리얼에서 Apache 이미지를 생성했는데, 워커 노드에서도 동일하게 이미지를 만들거나 기존 이미지를 배포해야 합니다. 이 단계를 생략하면 아래와 같은 오류를 만나게 됩니다. Docker 설정에 도움이 필요하다면 입문 가이드와 네트워킹 튜토리얼을 참고하시기 바랍니다.
7vwdxioopmmfp3amlm0ulimcu \_ websky.11 my-apache2:latest
localhost.localdomain Shutdown Rejected 7 minutes ago
"No such image: my-apache2:lat&"
시작하기
CentOS 머신이 정상적으로 구동 중이고 컨테이너를 성공적으로 생성하고 있다고 가정합니다. 호스트 포트를 통해 서비스에 접속할 수 있고 전반적으로 문제없이 동작하는 상태입니다. 현재 스웜에는 매니저 노드만 존재합니다.
워커 노드 합류시키기
새로운 노드를 추가하려면 join 명령어를 사용해야 합니다. 그 전에 워커 노드가 스웜 매니저에게 정상적으로 인증받기 위해 필요한 토큰(token), IP 주소, 포트 정보를 먼저 확인해야 합니다. 매니저 노드에서 다음 명령을 실행하세요.
[root@localhost ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-0xvojvlza90nrbihu6gfu3qm34ari7lwnza ... \
192.168.2.100:2377
방화벽과 라우팅 규칙을 제대로 설정하지 않으면 타임아웃 오류가 발생합니다. 또한 이미 스웜에 합류한 상태에서 join 명령을 반복 실행하면 다음과 같은 메시지가 출력됩니다.
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.
확실하지 않다면 스웜에서 탈퇴한 뒤 다시 시도하면 됩니다.
[root@localhost ~]# docker swarm leave
Node left the swarm.
docker swarm join --token
SWMTKN-1-0xvojvlza90nrbihu6gfu3qnza4 ... 192.168.2.100:2377
This node joined a swarm as a worker.
워커 노드에서는 docker info 명령으로 상태를 확인할 수 있습니다.
Swarm: active
NodeID: 2i27v3ce9qs2aq33nofaon20k
Is Manager: false
Node Address: 192.168.2.103
마찬가지로 매니저 노드에서 확인하면 다음과 같습니다.
Swarm: active
NodeID: cneayene32jsb0t2inwfg5t5q
Is Manager: true
ClusterID: 8degfhtsi7xxucvi6dxvlx1n4
Managers: 1
Nodes: 3
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Node Address: 192.168.2.100
서비스 생성 및 스케일링
이제 Docker가 노드 간에 컨테이너를 어떻게 분배하는지 살펴볼 차례입니다. 필자의 테스트 결과, 부하가 매우 낮은 상태에서는 상당히 단순한 분배 알고리즘이 적용되는 것으로 나타났습니다. 한두 차례는 실행 중인 서비스를 새로운 워커에게 재분배하지 않았으며, 스케일 조정과 업데이트를 시도한 후에도 마찬가지였습니다. 반대로 어느 순간에는 새 서비스를 워커 노드에 온전히 생성하기도 했습니다. 어쩌면 그것이 최적의 선택이었을지도 모릅니다.
새 서비스가 워커 노드에 온전히 생성된 모습.
시간이 지나자 기존 서비스의 컨테이너가 두 노드 사이에서 재분배되기 시작했지만, 다소 시간이 걸렸습니다. 새로운 서비스는 문제없이 잘 동작했습니다. 이는 초기 관찰 결과에 불과하므로 지금 단계에서 더 많은 결론을 내리기는 어렵습니다. 다만 클러스터 동작을 탐색하고 튜닝해 볼 수 있는 좋은 출발점이라고 할 수 있습니다.
잠시 후 로드밸런싱이 작동하기 시작한다.
결론
Docker는 훌륭한 도구이며, 앞으로 더욱 크고 복잡하고 강력해질 것이고, 물론 더 세련되어질 것입니다. 언젠가 대형 엔터프라이즈 기업에게 인수될 것도 시간문제라고 생각합니다. 네이티브 오케스트레이션 관점에서 보면 스웜 모드는 상당히 잘 작동하지만, 그 알고리즘과 확장성의 진정한 힘을 끌어내려면 몇 개의 컨테이너만으로는 부족합니다.
이번 튜토리얼에서는 CentOS 머신이 운영하는 클러스터에 Fedora 노드를 추가하는 방법을 살펴보았고, 두 시스템은 나란히 잘 작동했습니다. 로드밸런싱에 대해서는 아직 풀어야 할 질문들이 남아 있는데, 이 부분은 추후 글에서 더 깊이 다룰 예정입니다. 전반적으로 이번 학습이 유익했기를 바랍니다. 스웜을 구성할 때 흔히 마주치는 사전 요구 사항과 일반적인 문제들을 다루었고, 여러 컨테이너를 구동했으며, 서비스의 스케일링과 분배 방식까지 간단히 살펴보았습니다. 그리고 기억하세요. 이것은 이제 시작에 불과합니다.
그럼, 즐거운 도커 라이프 되시길 바랍니다.