이 포스트는 Korea Azure User Group에서 진행하는 Docker/Container 스터디 그룹에 참여하며 작성했습니다.
스터디를 진행한 Katacoda 강좌: Docker & Containers/Orchestration
진행한 강의 목록
- Learn Docker Swarm 101
- Getting Started With Swarm Mode
- Create Overlay Network
- Load Balance and Service Discover in Swarm Mode
- Apply Rolling Updates Across Swarm Cluster
스터디는 Katacoda의 화면을 참조하되, 실습은 제 개인 PC에서 VM을 구성해서 진행했습니다. 따라해볼 수 있는 것만 별도로 정리했습니다.
구성환경
- Windows 10 Pro 1809
- Hyper-V
- CentOS 7.6.1810 (Kernel 4.20.2-1.el7)
내용 정리
# 컨테이너를 한두개 정도로 띄우는 것이라면 크게 관여할 것이 적다.
# 하지만, 다량의 컨테이너를 관리하고, 또 배포해야한다면 오케스트레이션 도구를 이용해야한다.
# 여기엔 Docker에 기본 탑재되어 있는 Swarm을 이용해서 노드간 연결 및 컨테이너 배포에 대해 알아보자
[root@docker-master ~]# docker swarm init --advertise-addr 10.10.0.10 # swarm 구성에 대한 초기화를 하며, 이용할 네트워크를 지정해준다.
Swarm initialized: current node (ltdlolaft6ui125702kry34g4) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5xahht9brfebnn9zs7jluhogp637mqcjmxxxvsoajsj7sufx37-6p2pnq6mnrdaqwouh1i26ihhh 10.10.0.10:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
[root@docker-node01 ~]# docker swarm join --token SWMTKN-1-5xahht9brfebnn9zs7jluhogp637mqcjmxxxvsoajsj7sufx37-6p2pnq6mnrdaqwouh1i26ihhh 10.10.0.10:2377 # 다른 노드에서 join을 해준다.
This node joined a swarm as a worker.
[root@docker-master ~]# docker node ls # 노드상태 확인시 연결된 것이 나온다.
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ltdlolaft6ui125702kry34g4 * docker-master Ready Active Leader 18.09.3
psvof4rkv74wtd4vg6rmuqjtg docker-node01 Ready Active 18.09.3
# Docker 노드간 배치되는 컨테이너들의 통신을 위해 Overlay 네트워크를 생성한다.
[root@docker-master ~]# docker network create -d overlay ysyukr
xkhhlx5lqgb4e0rwwefl1qmqz
[root@docker-master ~]# docker network ls # overlay 로 지정된 네트워크에 컨테이너를 올리면 노드간 통신이 된다.
NETWORK ID NAME DRIVER SCOPE
9e4def94a4bb bridge bridge local
def6f3893f90 docker_gwbridge bridge local
e5230bd01399 host host local
kxyhou2tznvs ingress overlay swarm
802e1aa038d9 none null local
xkhhlx5lqgb4 ysyukr overlay swarm
[root@docker-master ~]# docker service create --name redis --network ysyukr redis:alpine # 만만한 redis를 오버레이 네트워크에 올려보자.
x1eotbp9gs2y1cgn68i3xtxmn
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker service create --network ysyukr -p 80:3000 --replicas 1 --name app1-web katacoda/redis-node-docker-example # 오버레이 네트워크의 redis로 연결할 간단한 웹서버를 띄워준다.
wsct44ff17tx52ksulrztanzh
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker ps # 컨테이너 확인
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec61cf2f564c redis:alpine "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp redis.1.lm27jdyo57kcavshx7ikhx9kn
[root@docker-master ~]# curl localhost # 접속 테스트
This page was generated after talking to redis.
Application Build: 1
Total requests: 1
IP count:
::ffff:10.255.0.2: 1
[root@docker-node01 ~]# docker ps # 두번째 노드에서 컨테이너 확인
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b3b07a0040a katacoda/redis-node-docker-example:latest "npm start" 12 seconds ago Up 11 seconds 3000/tcp app1-web.1.yhe6xtasygoj0ddr1k9srxx1y
[root@docker-node01 ~]# curl localhost # 접속 테스트
This page was generated after talking to redis.
Application Build: 1
Total requests: 2
IP count:
::ffff:10.255.0.2: 1
::ffff:10.255.0.3: 1
# 다중 노드에 컨테이너를 배치해서 로드밸런싱을 할 수 있다.
[root@docker-master ~]# docker service create --name lb-app1 --replicas 2 -p 81:80 katacoda/docker-http-server
ff6s3oye9mmgvr5mh1belc68b
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
395114908c2c katacoda/docker-http-server:latest "/app" 14 seconds ago Up 13 seconds 80/tcp lb-app1.1.03pum2puc5eusjg12su1o4hor
[root@docker-node01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d840c887173d katacoda/docker-http-server:latest "/app" 10 seconds ago Up 10 seconds 80/tcp lb-app1.2.56nz649ujhu7zguoup0uadj86
[root@docker-master ~]# curl localhost:81
<h1>This request was processed by host: 395114908c2c</h1>
[root@docker-node01 ~]# curl localhost:81
<h1>This request was processed by host: d840c887173d</h1>
[root@docker-master ~]# docker network create --attachable -d overlay eg1 # --attachable 옵션을 넣어서 네트워크를 생성한다.
kstkz6pesfwoqatvxbeb6icha
[root@docker-master ~]# docker service create --name http --network eg1 --replicas 2 katacoda/docker-http-server # 테스트할 컨테이너 생성
d5xaw1k9uy6jpzjpx2l9bz8pq
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker run --name=dig --network eg1 benhall/dig dig http # dig 컨테이너로 IP 주소 확인
Unable to find image 'benhall/dig:latest' locally
latest: Pulling from benhall/dig
12b41071e6ce: Already exists
d23aaa6caac4: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:ed7d241f0faea3a015d13117824c04a433a79032619862e4e3741a31eb9e4272
Status: Downloaded newer image for benhall/dig:latest
; <<>> DiG 9.10.2 <<>> http
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10990
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;http. IN A
;; ANSWER SECTION:
http. 600 IN A 10.0.1.2
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Sun Mar 24 07:40:17 UTC 2019
;; MSG SIZE rcvd: 42
[root@docker-master ~]# docker run --name ping --network eg1 alpine ping -c1 http # ping 컨테이너로 IP 주소 확인
PING http (10.0.1.2): 56 data bytes
64 bytes from 10.0.1.2: seq=0 ttl=64 time=0.066 ms
--- http ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.066/0.066/0.066 ms
[root@docker-master ~]# docker service inspect http --format="{{.Endpoint.VirtualIPs}}"
[{kstkz6pesfwoqatvxbeb6icha 10.0.1.2/24}]
[root@docker-master ~]# docker inspect --format="{{.NetworkSettings.Networks.eg1.IPAddress}}" $(docker ps | grep docker-http-server | head -n1 | awk '{print $1}')
10.0.1.4
# 다중 컨테이너 배포시 설정 또는 이미지 업데이트가 필요할 때가 있다.
# 이때 update를 이용해서 롤링 업데이트로 순차적인 업데이트를 하면 된다.
[root@docker-master ~]# docker service create --name http --replicas 2 -p80:80 katacoda/docker-http-server:v1 # 다중 컨테이너 실행, 여기선 2개
t89vh1672mo6yviuo9ztn8wd7
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker service update --env-add KEY=VALUE http # 환경설정에 KEY = VALUE 형태로 받아들이도록 업데이트
http
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker service update --limit-cpu 2 --limit-memory 512mb http # CPU/MEM에 대한 제한 설정
http
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker service inspect --pretty http # 제한 설정한 컨테이너의 상세 내역 확인
ID: t89vh1672mo6yviuo9ztn8wd7
Name: http
Service Mode: Replicated
Replicas: 2
UpdateStatus:
State: completed
Started: 37 seconds ago
Completed: 24 seconds ago
Message: update completed
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: katacoda/docker-http-server:v1@sha256:4d7bfcb1e38912d286c5cda63aeddc850a4be16127094ffacbb7abfc6298c5fa
Env: KEY=VALUE
Init: false
Resources:
Limits:
CPU: 2
Memory: 512MiB
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
[root@docker-master ~]# docker service update --replicas=6 http # 컨테이너를 2개에서 6개로 증설
http
overall progress: 6 out of 6 tasks
1/6: running [==================================================>]
2/6: running [==================================================>]
3/6: running [==================================================>]
4/6: running [==================================================>]
5/6: running [==================================================>]
6/6: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker service inspect --pretty http # 증설되었는지 상세 확인
ID: t89vh1672mo6yviuo9ztn8wd7
Name: http
Service Mode: Replicated
Replicas: 6
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: katacoda/docker-http-server:v1@sha256:4d7bfcb1e38912d286c5cda63aeddc850a4be16127094ffacbb7abfc6298c5fa
Env: KEY=VALUE
Init: false
Resources:
Limits:
CPU: 2
Memory: 512MiB
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
[root@docker-master ~]# docker service update --image katacoda/docker-http-server:v2 http # v1 서버를 v2 서버로 롤링업데이트
http
overall progress: 6 out of 6 tasks
1/6: running [==================================================>]
2/6: running [==================================================>]
3/6: running [==================================================>]
4/6: running [==================================================>]
5/6: running [==================================================>]
6/6: running [==================================================>]
verify: Service converged
[root@docker-master ~]# docker ps # 컨테이너 확인시 v2로 업데이트 확인
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b18eeb4274a2 katacoda/docker-http-server:v2 "/app" 14 seconds ago Up 10 seconds 80/tcp http.4.5auhxyqqwep0hh61wtrr74fnc
e9814ab71234 katacoda/docker-http-server:v2 "/app" 26 seconds ago Up 21 seconds 80/tcp http.2.g10r59z8nh3nfqrmlz9bgrgnb
d55238175cc5 katacoda/docker-http-server:v2 "/app" 32 seconds ago Up 30 seconds 80/tcp http.6.rnmjghk0bmyinu5ezq1qdv6l2
[root@docker-master ~]# curl localhost
<h1>New Release! Now v2! This request was processed by host: b18eeb4274a2</h1>