도커를 다룬지 3년이 넘어가는 것 같지만 스웜(Swarm)을 사용하지 않았다. MesOS나 Rancher 같은 녀석을 사용하거나 직접 만들어서 사용하다 보니, 필요성을 느끼지 못했다. 뒤늦게? 스웜을 써보려는 이유는 스웜위에 Spark를 올리기 위해서다. MesoS위에서도 올릴 수 있겠지만 Spark 스터디 용도로 설치하려는데, 너무 나가는 것 같아서 간단하다는 스웜을 선택했다. Hadoop yarn도 마찬가지의 (복잡하다는)이유로 선택하지 않았다.
도커(docker)는 1.12.0 버전 부터 swarm모드를 지원한다. 1.12 이전의 도커는 호스트 레벨에서만 작동을 했으며, 클러스터를 구성하기 위해서는 MesOS와 같은 툴을 사용해야 했다. 이제 스웜(Swarm)을 이용해서 기본적인 클러스터의 관리가 가능하다.
서비스 : 기본 배포단위다. 예를 들어 NginX로 로드밸런서를 구축한다면, NginX로 구성된 컨테이너들이 서비스가 된다.
테스크 : 서비스의 구성단위다. 워드프레스 서비스는, 워드 프레스 애플리케이션, Mysql 테스크로 구성될 것이다.
스웜 생성
새로운 스웜(스웜 클러스터)를 만들어보자. 먼저 스웜 클러스터를 관리할 매니저 노드를 설정해야 한다. swarm01 노드를 매니저 노드로 등록하자.
$ docker swarm init --advertise-addr 192.168.56.10
Swarm initialized: current node (kndz5fsmeg5229t96tvv37g47) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-5fbm1eqi2ako9cc1n50iqm5mi70kwvlqwsxx1tgptgysiqd4de-3fp0vx104o2ct68riqebtyuf0 \
192.168.56.10:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
이제 워커 노드들은 token에 있는 문자열을 이용해서, 스웜 클러스터에 합류 할 수 있다.
docker info 명령으로 도커 상태를 확인해보자.
스웜 클러스터가 active 인 것을 확인 할 수 있다.
docker node ls로 스웜 클러스터를 구성하고 있는 노드들을 확인 할 수 있다.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
kndz5fsmeg5229t96tvv37g47 * swarm01 Ready Active Leader
스웜에 노드 추가하기
지금 스웜 클러스터는 manager node하나만 등록되 있다. 이제 워커 노드를 만들어보자. swarm02, swarm03 노드를 워커노드로 등록한다. swarm-02, swarm-03 노드에서 아래 명령을 실행하자.
$ docker swarm join --token SWMTKN-1-5fbm1eqi2ako9cc1n50iqm5mi70kwvlqwsxx1tgptgysiqd4de-3fp0vx104o2ct68riqebtyuf0 192.168.56.10:2377
This node joined a swarm as a worker.
docker node ls 명령을 실행해보자. swarm02, swarm03 노드가 클러스터에 포함된 걸 확인 할 수 있을 것이다.
yundream@swarm01:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
kndz5fsmeg5229t96tvv37g47 * swarm01 Ready Active Leader
rniubrtixywbqb20mvsucpist swarm02 Ready Active
t26yi2c5ent1eaxelrdwgf81a swarm03 Ready Active
스웜에 서비스 전개하기
스웜은 전개하기 원하는 서비스의 상태를 정의해서 실행한다. 아래와 같은 정보들을 정의할 수 있다.
서비스 컨테이너의 이름과 태그
얼마나 많은 컨테이너가 실행될지
어떤 포트를 외부에 노출 할지
도커시작시 서비스를 자동으로 실행 할지.
서비스가 다시 시작될 때 발생하는 동작 설정.
서비스가 실핼될 조건들
서비스 만들기
하나의 컨테이너로 실행되는 서비스는 설정 없이 실행 할 수 있다. 단지 이미지의 이름만 설정하면 된다. 아래는 nginx 서비스를 실행하는 예제다.
$ docker service create nginx
axgvnpk2sq5mu1d5wgrt7e9vd
docker service ls로 서비스 목록을 확인 할 수 있다. 랜덤이름으로 실행됐다.
$ docker service ls
ID NAME MODE REPLICAS IMAGE
o3aj11ae8wwe tender_kirch replicated 1/1 nginx:latest
alpine 이미지로 부터 helloworld 이름을 가지는 서비스를 만들었다. 컨테이너는 실행하면서 ping docker.com 명령을 실행 한다.
$ docker service create --name helloworld alpine ping docker.com
서비스 업데이트
docker service update명령으로 서비스의 정보를 변경 할 수 있다. 서비스를 업데이트하면, 도커는 컨테이너를 stop 한 다음에 새로운 설정으로 재시작 한다. 테스트를 위해서 my_web 이라는 이름의 nginx 서비스를 만들었다.
$ docker service create --name my_web nginx
zoki6hj8pn4kcnwp90dixpdej
호스트의 8080을 컨테이너의 80으로 포워딩 설정했다.
$ docker service update --publish-add 8080:80 my_web
서비스 컨테이너는 스웜 노드들 중 하나에 뜨지만, 다른 모든 스웜노드로 서비스에 접근 할 수 있다.
스웜은 호스트의 포트를 routing mesh와 port directly on the warm node 두 가지 방식으로 외부에 노출 할 수 있다. 스웜은 별도의 설정이 없을 때 routing mesh모드로 포트를 노출하는데, 스웜의 모든 노드에서 포트에 접근 할 수 있게 해준다.
아래 그림은 routing mesh를 묘사하고 있다.
서비스 삭제
사용하지 않는 서비스는 docker service remove로 삭제 할 수 있다.
$ docker service remove my_web
서비스 스케일링
원하는 갯수만큼 서비스를 실행 할 수 있다. my_web 컨테이너를 3개로 늘렸다.
$ docker service scale my_web=3
docker service ls로 서비스 상태를 확인해 보자.
yundream@swarm01:~$ docker service ls
ID NAME MODE REPLICAS IMAGE
fgsdcjuhdsf5 jolly_khorana replicated 0/1 my_web
i8h2zeq6ig4n affectionate_yalow replicated 0/1 my_web
nxc5sq41eemr wizardly_brown replicated 0/1 my_web
pe3140dqrneb my_web replicated 3/3 nginx:latest
원본까지 해서 총 4개의 컨테이너가 실행됐다.
Rolling Update
앞서 my_web 애플리케이션을 스케일링 해서 4개의 컨테이너가 실행했다. my_web 애플리케이션의 버전이 올라갈 경우 이들을 모두 새로 실행해야 한다. 이 과정은 무중단으로 진행해야 한다. 실 환경에서 서비스 관리자는 서비스 프로세스를 하나씩 죽였다 살리는 식으로 주의깊게 작업을 진행한다. 프로세스가 그리 많지 않다면, 수작업을 해도 상관없겠으나 수십개가 넘는다면 대략 난감할 것이다.
스웜의 rolling update 기능을 이용해서 이 과정을 자동으로 진행할 수 있다.
스웜을 구성하는 노드는 워커 노드와 관리자 노드 두 개의 타입이 있다. 워커노드는 관리자 노드의 명령을 받아서 컨테이너를 실행하는 일만 한다. 반면 관리자 노드는 스웜 클러스터를 관리하는 일을 한다.
서비스를 실행할 자원이 부족 하다면 워커 노드를 추가해서 자원을 늘려주면 된다. 관리자 노드는 클러스터의 안정성과 가용성을 확보하기 위한 목적으로 사용한다. 스웜 클러스터에 두 개 이상의 관리자 노드를 추가하면, 하나의 관리자 노드에 문제가 생기더라도 서비스를 계속 할 수 있다. 보통은 최소 3개 정도의 관리자 노드를 구성한다. 관리자 노드들 중 하나가 리더로 선출되며, 이 리더가 클러스터를 관리한다. 만약 리더가 죽는다면, 작동중인 관리자 노드들 중 하나가 리더로 선출되서 클러스터를 계속 관리한다.
관리노드에서 join-token명령으로 토큰을 만들어서 배포하면 된다. 워커 노드를 위한 토큰을 만들어보자.
$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-5fbm1eqi2ako9cc1n50......qebtyuf0 \
192.168.56.10:2377
이제 추가할 노드(swarm04)에서 위의 명령을 실행하면 된다.
$ docker swarm join \
>--token SWMTKN-1-5fbm1eqi2ako9cc1n50iqm5mi70kwvlqwsxx1tgptgysiqd4de-3fp0vx104o2ct68riqebtyuf0 \
>192.168.56.10:2377
This node joined a swarm as a worker.
swarm04가 추가된 걸 확인 할 수 있다.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
kndz5fsmeg5229t96tvv37g47 * swarm01 Ready Active Leader
rbmzjtshc3cveo8a18d2qohsg swarm04 Ready Active
rniubrtixywbqb20mvsucpist swarm02 Ready Active
t26yi2c5ent1eaxelrdwgf81a swarm03 Ready Active
매너지 노드를 추가해보자. join-token worker 대신 join-token manager를 호출하면 된다.
$ docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-5fbm1eqi2ako9cc1n50iqm5mi70kwvlqwsxx1tgptgysiqd4de-ba14im77qflw7xpc7h3c8yiac \
192.168.56.10:2377
스웜 서비스 네트워크 관리
스웜은 두 개의 트래픽 타입을 지원한다.
제어및 관리 트래픽 : 스웜에 노드를 추가하는 등의 관리 트래픽이다. 항상 암호화 된다.
애플리케이션 트래픽 : 응용 프로그램을 위한 데이터 트래픽으로 컨테이너에서 발생하는 트래픽과 외부 클라이언트와의 트래픽이 포함된다.
여기에서는 애플리케이션 서비스를 위한 트래픽을 제어하는 방법에 대해서 살펴보려 한다. 스웜 네트워크 모델을 완전히 이해하고 싶다면Docker networking reference architecture문서가 도움이 될 것이다.
스웜 서비스는 아래의 네트워크 모델을 지원한다.
오버레이 네트워크(Overlay Network) : 오버레이 네트워크는 스웜에 참여하는 도커 데몬간의 통신을 관리한다.
ingress 네트워크는 서비스 노드들간의 로드 밸런싱을 관리하는 목적으로 사용하는 특수한 오버레이 네트워크다. 스웜 서비스 포트에 대한 요청을 받으면 이 요청은 IPVS라는 모듈로 전달한다. IPVS는 서비스에 참여하는 모든 IP 주소를 추적하여, 그 중 하나를 선택하고 트래픽을 해당 경로로 라우팅 한다. ingress 네트워크는 스웜을 초기화 하거나 새로운 노드가 가입할 때 자동으로 만들어진다. 일반적인 경우에 사용자가 정의 할 필요는 없지만, 원한다면 도커 17.05 이상 버전에서 정의 할 수도 있다.
docker_gwbridge는 오버레이 네트워크를 개별 도커 데몬으로 연결하기 위한 브릿지 네트워크다. 서비스가 실행 중인 각 컨테이너는 로컬 호스트의 docker_gwbridge 네트워크에 연결된다. docker_gwbridge 네트워크는 스웜을 초기화 하거나 노드가 가입 할 때 자동으로 만들어진다. 일반적으로 사용자가 정의 할 필요는 없지만, 원한다면 사용자가 정의해서 사용 할 수도 있다.
방화벽 정책
도커 데몬은 서로 통신을 하기 위해서 두 개 포트를 사용한다. 아래 포트에 대한 방화적 정책을 허용해야 한다.
Contents
Docker swarm
테스트 환경
스웜 구성요소
스웜 생성
스웜에 노드 추가하기
스웜에 서비스 전개하기
서비스 만들기
서비스 업데이트
서비스 삭제
서비스 스케일링
Rolling Update
노드 추가하기
스웜 서비스 네트워크 관리
방화벽 정책
오버레이 네트워크의 구성
Recent Posts
Archive Posts
Tags