docker swarm

docker swarm

docker에 대해 글을 쓰는게 많아지는 요즘 이번에는 docker swarm에 대해서 글을 써보려 한다.
N 개의 물리서버를 clustering 할수있는 환경을 재공하며 나아가 rollback, scaling, 무중단 배포까지 가능 하다.
결론부터 말하면 환경구성하기는 무척이나 쉽다. 그리고 신기하다 .

환경구성

docker swarm을 구성하기전에 당연히 시스템에 docker가 설치되어있어야한다.
docker install에서 설치를 진행해도되고, 필자는 github gist를 이용해 아주 쉽게(?) 설치를 진행하였다.

1
$ curl -s https://gist.githubusercontent.com/setyourmindpark/fdbac4f4eab71b6a03b13660cd064710/raw/9d0f68f6150a57205b7a6df7ddbdab68131335a3/install-docker-ce-centos | bash

설치 완료를 하면 다음과 같은 버전정보를 확인할수있다 . ( 현 201802 )

1
2
$ docker --version
Docker version 17.12.0-ce, build c97c6d6

docker swarm 환경구성을 위해서는 clustering이나 N개의 서버 환경이 필요하다.
따라서 필자는 이전포스트 vagrant 에서 진행한 가상환경 centos 2개의 환경에서 진행할것이기에 2개의 환경모두 같은 docker version으로 설치를 진행하였다.

docker swarm

먼저 docker swarm 을 구성하기전에 leader node 로 사용할 서버에서 다음의 명령어를 입력한다.
leader node는 N개의 node를 관리하는 관리자 node 라고 생각하면된다.

1
2
3
4
5
6
7
8
9
[server1 (leader) ]
$ docker swarm init --advertise-addr 10.10.10.11
Swarm initialized: current node (sfx2ywb1o3cgaehkk1recc78n) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2wo52bbwsw2v350eyjwx2xwof5rk8m3t9ki0ax02jwkgyo14kt-cefzjz5ky4mf3qvyxuxdwuahr 10.10.10.11:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

–advertise-addr 옵션뒤 leader node( 현재서버 ip )를 적어주게되면, leader node를 join할 명령어 token을 친절하게 알려준다.
이제 leader node에서 생성한 token 정보로, 다른 node에서 join을 해보자.

1
2
3
[server2 (worker) ]
$ docker swarm join --token SWMTKN-1-2wo52bbwsw2v350eyjwx2xwof5rk8m3t9ki0ax02jwkgyo14kt-cefzjz5ky4mf3qvyxuxdwuahr 10.10.10.11:2377
This node joined a swarm as a worker.

정상적으로 swarm join이 되었는지 leader node에서 확인해보자.

1
2
3
4
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
sfx2ywb1o3cgaehkk1recc78n * server1 Ready Active Leader
n2awbegivqvw6dhc6npazwc5s server2 Ready Active

leader(server1)와 worker(server2) 모두 정상적으로 clustering 이되었다.

ingress

docker swarm 을 활용하기위해서 ingress의 개념부터 잘 알아야할것 같다.
docker swarm으로 cluster를 구성하게되면 ingress network가 default로 생성된것을 확인할수있다.

1
2
3
4
5
6
7
8
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
08e25cf17147 bridge bridge local
c589e1859f70 docker_gwbridge bridge local
bd3a091f88d0 dockerregistry_default bridge local
eac1648255dc host host local
05jt5qn72nvy ingress overlay swarm
ed2fcc6343f2 none null local

scope의 swarm으로 된 ingress 가 보인다.
ingress란 아주 쉽게 말해 nginx를 load balancer로 사용한 효과와 같다고 생각하면 된다.
다시말해서, 1번 node에 어떠한 service 컨테이너가 존재하고, 2번 node에는 존재하지않는다고 가정한다면, client 입장에서는 1번 node 또는 2번 node 둘중 아무 node를 호출(ex 10.10.10.11:service port 또는 10.10.10.12:service port ) 하여도 같은 결과를 return 한다.
ingress가 존재하는 container를 찾아 자동으로 load balancing 하여 마치 한몸처럼 동작하게 되는것이다 .
설명하는것보다 다음그림을 보는것이 이해하기 편할것이다.
ingress
https://docs.docker.com/engine/swarm/ingress/
이제 ingress를 테스트해보자 .
container의 unique id를 확인할수있는 image를 받는다.

1
$ docker pull jwilder/whoami

image pull은 leader node에서 수행하여야 한다. 해당 image를 N개의 node에서 관리할것이므로.
document는 https://hub.docker.com/r/jwilder/whoami/ 에서 확인가능하다.
이제 service를 생성하자.

1
2
[server1 (leader) ]
$ docker service create --name whoami -p 8000:8000 jwilder/whoami

service를 확인한다.

1
2
3
4
5
6
7
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
qnueloqeyi63 whoami replicated 1/1 jwilder/whoami:latest *:8000->8000/tcp
$ docker service ps whoami
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
mmcok9zpdfso whoami.1 jwilder/whoami:latest server1 Running Running about a minute ago

1개의 container 가 server1(leader node) 에 생성된것을 확인할수있다.
이제 document에 제시된바와같이 curl을 날려보자 .

1
2
3
server1( leader node )
$ curl server1:8000
I'm f8754dbd7fea

ingress가 제대로 동작된다면 server2(worker node) 에서도 동작되어야한다.
( worker node 에는 container가 없다 )

1
2
3
server1( worker node )
$ curl server2:8000
I'm f8754dbd7fea

server2 ( worker node )에는 container가 존재하지않지만 ingress 가 해당 서비스가 존재하는 node를 찾아가는것을 확인할수있다.
혹시 ingress가 동작하지않는다면 다음과 같이 docker service를 restart 해준다 .

1
$ service docker restart

약간의 버그가 있는듯하다. 해당 issue와 관련해 질문이 많은것을 알수있는데 https://github.com/moby/moby/issues/32195 를 참고하도록 하자 .
docker swarm 환경에서 ingress의 동작원리를 간단하게 살펴보았다.
docker swarm으로 서비스를 구성한다면 traffic에 관련된 처리라던지, 장애에대한 rollback, 그리고 scaling등의 옵션도 있으니 각자가 추구하는 방향으로 서비스를 구성하면 될것이다.

견해

필자는 docker swarm 을 알고나서 google의 kubernetes나 , apache의 mesos와 같은 ocastration 에 관심이 더욱더 많아졌다.
kubernetes가(docker 기반) 요즘 핫하긴한데. 약간의 진입장벽이 있는듯하다.
docker를 좀더 친숙하게 다룬후 kubernetes를 다시 도전해보려한다.

참고사이트

https://medium.com/@zh3w4ng/docker-swarm-with-private-registry-for-micro-services-behind-corporate-proxy-bafb349d0b9c
https://subicura.com/2017/02/25/container-orchestration-with-docker-swarm.html
https://docs.docker.com/engine/swarm/
https://docs.docker.com/engine/swarm/ingress/