EX) docker service create
$ docker service create ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep1; done"
도커 서비스 생성
서비스의 레플리카 셋을 정의하지 않았으므로 1개의 컨테이너만 생성
$ docker service create ubuntu:14.04
서비스 내의 컨테이너는 detached 모드로, 즉 docker run 명령어의 -d 옵션을 사용해 동작할 수 있는 이미지를 사용해야 한다.
다음과 같이 서비스를 생성하면 컨테이너 내부를 차지하고 있는 프로세스가 없어 컨테이너가 정지될 것이고,
스웜 매니저는 서비스의 컨테이너에 장애가 생긴 것으로 판단해 컨테이너를 계속 반복해서 생성할 것이다
EX) docker service ls
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
om1wnphdvtt4 jovial_merkle replicated 1/1 ubuntu:14.04
스웜 클러스터 내의 서비스 목록 확인
EX) docker service ps
$ docker service ps jovial_merkle
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bp40g9k8w965 jovial_merkle.1 ubuntu:14.04 red-virtual-machine Running Running 2 minutes ago
g32rmfpitou4 \_ jovial_merkle.1 ubuntu:14.04 red-virtual-machine Shutdown Complete 2 minutes ago
서비스의 자세한 정보를 확인
EX) docker service rm
$ docker service rm jovial_merkle
jovial_merkle
서비스 생성을 위해 Private 저장소 또는 레지스트리에서 이미지를 받아올 경우,
매니저 노드에서 로그인 한 뒤 docker service create 명령어에 --with-registry-auth을
추가해 사용하면 워커 노드에서 별도로 로그인을 하지 않아도 이미지를 받아올 수 있다.
EX) nginx 웹 서버 서비스 생성
$ docker service create --name myweb --replicas 2 -p 80:80 nginx
r3e9ujc8s1zmujxwf55h3id0p
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service converged
--name myweb : 서비스 이름 myweb 지정
--replicas 2 : 생성할 도커 갯수 2
-p 80:80 : 컨테이너의 80번 포트를 각 노드의 80번 포트로 연결
$ docker service ps myweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
tlve68yzxnd3 myweb.1 nginx:latest red-virtual-machine Running Running 11 seconds ago
31gc0ijtqur5 myweb.2 nginx:latest red-virtual-machine Running Running 11 seconds ago
Nginx 웹서버에 접근하면 어떤 노드에 접근하는 것일까?
- swarm-manager와 swarm-worker1 노트에 생성됐다.
- 그렇다고 해서 꼭 두 노드의 IP 주소로 접근해야만 Nginx 웹 서버에 접근할 수 있는 것은 아니다.
- docker service create 명령어에서 -p 옵션에 80:80을 입력함으로써 스웜 클러스터 자체에 포트를 개방했다고 생각하면 쉽게 이해할 수 있다.
- 스웜 클러스터 내의 어떠한 노드로 접근해도 위 서비스의 웹 서버에 접근할 수 있다.
- Nginx 컨테이너가 없는 swarm-worker2 노드로 접근해도 서비스에 접근할 수 있다.
- 같은 노드게 2개의 컨테이너가 할당될 수도 있으며 이는 전혀 문제가 안 된다. 컨테이너가 각 컨테이너들이 호스트의 80번 포트에 연결된 것이 아니며 실제로는 각 노드의 80번 포트로 들어온 요청을 위 4개의 컨테이너 중 1개로 리다이렉트(redirect)하기 때문이다. 따라서 각 호스트의 어느 노드로 접근하든 4개의 컨테이너 중 1개에 접근하게 된다.
EX) docker service scale
$ docker service scale myweb=4
myweb scaled to 4
overall progress: 4 out of 4 tasks
1/4: running
2/4: running
3/4: running
4/4: running
verify: Service converged
레플리카 셋의 수를 4개로 늘렸다.
$ docker service ps myweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
tlve68yzxnd3 myweb.1 nginx:latest red-virtual-machine Running Running 12 minutes ago
31gc0ijtqur5 myweb.2 nginx:latest red-virtual-machine Running Running 12 minutes ago
k0g77qibntum myweb.3 nginx:latest red-virtual-machine Running Running 13 seconds ago
8p2u2nkc121j myweb.4 nginx:latest red-virtual-machine Running Running 13 seconds ago
EX) --mode global
$ docker service create --name global_web --mode global nginx
puhmwv08f95n56c99f66192es
overall progress: 1 out of 1 tasks
s9ywh74vze0t: running
verify: Service converged
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
puhmwv08f95n global_web global 1/1 nginx:latest
레플리카의 값이 global로 설정됨
$ docker service ps global_web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
b6evk4mt10mt global_web.s9yw
각 노드에 컨테이너가 하나씩 생성
EX) 특정 컨테이너 장애
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a3815bc0205 nginx:latest "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 80/tcp myweb.4.y3p8m6j63izo922u0d8d50ryh
18ae8bbe28e3 nginx:latest "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 80/tcp myweb.3.f8mjncmjuis5wpcvlrvpn1w4v
d5c1596243cb nginx:latest "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 80/tcp myweb.2.kpd6031qjfqd2b190u08aqug0
63f1b3fd6f51 nginx:latest "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 80/tcp myweb.1.7sguc6ut8o6sz2vvu2u50hfhj
f3d16236b350 nginx:latest "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp global_web.s9ywh74vze0tcbqm837e56esd.b6evk4mt10mtik3tw3dcyvwar
$ docker rm -f myweb.1.7sguc6ut8o6sz2vvu2u50hfhj
myweb.1.7sguc6ut8o6sz2vvu2u50hfhj
컨테이너 강제 종료
$ docker service ps myweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
ERROR PORTS
6wz9esxaeq8q myweb.1 nginx:latest red-virtual-machine Running Running 4 seconds ago
7sguc6ut8o6s \_ myweb.1 nginx:latest red-virtual-machine Shutdown Failed 10 seconds ago "task: non-zero exit (137)"
kpd6031qjfqd myweb.2 nginx:latest red-virtual-machine Running Running about a minute ago
f8mjncmjuis5 myweb.3 nginx:latest red-virtual-machine Running Running 44 seconds ago
y3p8m6j63izo myweb.4 nginx:latest red-virtual-machine Running Running 44 seconds ago
myweb.1 을 보면 새로운 컨테이이너가 생성됐음을 확인 가능
docker service ps 명령어에서 NAME 항목에 _ 가 붙어있는 컨테이너는 어떠한 이유로든 동작을 멈춘 컨테이너로서, 서비스에서의 컨테이너 변경 기록을 나타낸다.
EX) 특정 노드 장애
swarm-worker1$ service docker stop
특정 노드 장애
$ docker node ls
특정 노드 STATUS가 Down 상태로 변경됨
다운 됐던 도느를 다시 시작해 정상적인 상태를 회복해도 장애를 복구하기 위해 다른 노드로 옮겨진 컨테이너가 해당 노드에 자동으로 할당되지는 않는다.(rebalance)
$ docker service scale myweeb=1
$ docker service scale myweeb=4
새로운 노드를 추가하거나 다운됐던 노드를 다시 복구했을 때 서비스의 컨테이너 할당의
균형을 맞추기 위해서는 cale 명령어를 이용해 컨테이너의 수를 줄이고 다시 늘려야 한다.
docker ps --filter is-task=true
스웜의 서비스로 생성된 컨테이너만 확인
EX) docker service update
$ docker service create --name myweb2 --replicas 3 nginx:1.10
$ docker service update --image nginx:1.11 myweb2
이미지를 업데이트하려면 --image 옵션 설정
$ docker service create --replicas 4 --name myweb3 --update-delay 10s --update-parallelism 2 nginx:1.10
--update-delay 10s : 컨테이너를 10초 단위로 업데이트
--update-parallelism 2 : 업데이트 작업을 한번에 2개의 컨테이너에 수행
EX) 롤링 업데이트 설정 확인
root@red-virtual-machine:~# docker service inspect --pretty myweb
ID: uyodwj0vbp8ix44wedlixm12t
Name: myweb
Service Mode: Replicated
Replicas: 4
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: nginx:latest@sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514
Init: false
Resources:
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
--update-failure-action continue 지정으로 On failure 변경 가능
EX) docker service rollback myweb
$ docker service rollback myweb
서비스 롤링 업데이트 후, 서비스를 롤링 업데이트 전으로 되돌리는 롤백(rollback)