단일 프로그램을 각 컴포넌트 별로 나누어 작은 서비스의 조합으로 구축하는 방법
root@manager:~# docker service create --name web --replicas 4 nginx
root@manager:~# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wywyqa46o5rg web.1 nginx:latest manager Running Running 23 seconds ago
u3s9b5po9v0z web.2 nginx:latest worker1 Running Running 23 seconds ago
xomvjr33srh0 web.3 nginx:latest worker2 Running Running 16 seconds ago
oe5jz4541yqd web.4 nginx:latest manager Running Running 23 seconds ago
<삭제 후 다시>
root@manager:~# docker service rm web
<랜덤 하게 생성하지 않고 worker 들만 서비스를 돌리는법>
root@manager:~# docker service create --name web --constraint node.role!=manager --replicas 4 nginx
tvblfaw29cya3fcjih79nl3ok
overall progress: 4 out of 4 tasks
1/4: running
2/4: running
3/4: running
4/4: running
verify: Service converged
root@manager:~# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
k88axpfdwbcs web.1 nginx:latest worker1 Running Running 17 seconds ago
nskqueiwk24u web.2 nginx:latest worker2 Running Running 17 seconds ago
77b3yb1vi5hv web.3 nginx:latest worker1 Running Running 17 seconds ago
p2xbagoj37eu web.4 nginx:latest worker2 Running Running 17 seconds ago
<삭제 후 다시>
<각각의 노드마다 하나씩 올라오게 만드는 법>
root@manager:~# docker service create --name gweb --mode global nginx
root@manager:~# docker service ps gweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
n24hcak62i4q gweb.mcmf0kzq01bv40w9jb3yd0cmm nginx:latest worker1 Running Running 12 seconds ago
xbgnvkzsdszu gweb.nyx5uw0hp9cseo3wfydaekyk4 nginx:latest manager Running Running 12 seconds ago
affryjzoanar gweb.svueexwycqa9530urwnuv5z0x nginx:latest worker2 Running Running 12 seconds ago
root@manager:~# docker service create --replicas 4 --name web --update-delay 10s nginx:1.11 0h01yoldaac1nh83pki68unvl
overall progress: 4 out of 4 tasks
1/4: running
2/4: running
3/4: running
4/4: running
verify: Service converged
root@manager:~# docker service inspect web | grep Image
"Image": "nginx:1.11 @sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582",
<nginx 를 1.23 로 업데이트 하고 싶음>
root@manager:~# docker service update --image nginx:1.23 web
root@manager:~# docker service inspect --pretty web
ID: nv5nz00a2c1hm8qpkmxbodltk
Name: web
Service Mode: Replicated
Replicas: 4
UpdateStatus:
State: updating
Started: 53 seconds ago
Message: update in progress
Placement:
UpdateConfig:
Parallelism: 1
Delay: 10s
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:1.23
Init: false
Resources:
Endpoint Mode: vip
root@manager:~# docker service rollback web
root@manager:~# docker service inspect --pretty web
ID: nv5nz00a2c1hm8qpkmxbodltk
Name: web
Service Mode: Replicated
Replicas: 4
UpdateStatus:
State: rollback_paused
Started: 33 seconds ago
Message: update paused due to failure or early termination of task tl8i6czkxqjjns2xy2lectorj
Placement:
UpdateConfig:
Parallelism: 1
Delay: 10s
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:1.22
Init: false
Resources:
Endpoint Mode: vip
root@manager:~# docker service rm web
web
root@manager:~# docker service create --replicas 4 --name web --update-delay 10s --update- parallelism 2 nginx:1.11
image nginx:1.11 could not be accessed on a registry to record
its digest. Each node will access nginx:1.11 independently,
possibly leading to different nodes running different
versions of the image.
ak4y5b75v2mno0b8s4azjr654 overall progress: 4 out of 4 tasks 1/4: running
2/4: running
3/4: running
4/4: running
verify: Service converged
<2개씩 병렬로 업데이트 됨!>
root@manager:~# docker service update --image nginx:1.23 web image nginx:1.23 could not be accessed on a registry to record its digest. Each node will access nginx:1.23 independently, possibly leading to different nodes running different
versions of the image.
web
overall progress: 4 out of 4 tasks
1/4: running
2/4: running
3/4: running
4/4: version: "3"
services:
wp:
image: wordpress
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
restart_policy:
condition: on-failure
max_attempts: 3
environment:
SERVICE_PORTS: 80
WORDPRESS_DB_HOST: "db"
WORDPRESS_DB_USER: "wpuser"
WORDPRESS_DB_PASSWORD: "1234"
WORDPRESS_DB_NAME: "wordpress"
# links:
# - "db"
depends_on:
- "db"
networks:
- web
proxy:
image: dockercloud/haproxy
depends_on:
- wp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
networks:
- web
deploy:
mode: global
placement:
constraints: [node.role == manager]
db:
image: mariadb
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
restart_policy:
condition: on-failure
max_attempts: 3
environment:
MYSQL_ROOT_PASSWORD: "1234"
MYSQL_DATABASE: "wordpress"
MYSQL_USER: "wpuser"
MYSQL_PASSWORD: "1234"
volumes:
- "/mdb:/var/lib/mysql"
networks:
- web
networks:
web:
external: true
verify: Service converged
현재 내 도커 허브에 websrv:old 라는 이미지를 토대로한 컨테이너 서비스가 동작중이다 replicas 는 4이다.
나는 websrv:new라는 이미지를 생성하여 해당 서비스를 업데이트 하고 싶다 태스크는 2대씩 5 초의간격을두고 롤링업데이트가 되게하고싶다!
websrv:old 는
index.html의 내용이 "old web server" 인 nginx:latest 기반 이미지
websrv:new 는
index.html의 내용이 "new web server" 인 nginx:latest 기반 이미지
echo 명령어를 사용해 html 의 내용이 작성되어 있어야 한다
<dockerfile 1,2>
*********
FROM nginx:latest
COPY index.html /usr/share/nginx/html/
WORKDIR /usr/share/nginx/html
**********
빌드를 websrv:old , websrv:new 의 태그로 했음 도커 허브에 push 하려면 태그를 수정해줘야 함
root@manager:/webold# docker tag websrv:old leeeuijoo/websrv:old
root@manager:/webold# docker tag websrv:new leeeuijoo/websrv:new
root@manager:/webold# docker push leeeuijoo/websrv:old
root@manager:/webold# docker push leeeuijoo/websrv:new
< worker 1,2 에서도 도커 허브에서 new, old pull 해주기>
root@manager:/webold# docker service create -p 3233:80 --name old --replicas 4 leeeuijoo/websrv:old
root@manager:/webold# docker service inspect --pretty old
root@manager:/webold# docker service rollabck
docker network 생성 시에 --attcahable 의 의미 : 도커 단일 호스트에서도 생성한 네트워크를 사용가능하도록 하는 명령어이다.
프록시 서버 : 서버를 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템 혹은 응용프로그램이다.
gyoungseo 님 notion 참고
docker run과 비교가 되는 것 → swarm의 service
docker-compose.yml와 비교가 되는 것 stack
단일 컨테이너만 띄울 것이라면 ⇒ service
root@manager:/docker# docker service rm web websrv
root@manager:/docker# docker network create --driver=overlay --attachable web
root@manager:/docker# docker network ls
NETWORK ID NAME DRIVER SCOPE
2652b511e6f3 bridge bridge local
b5cfd91a936a docker_gwbridge bridge local
d50a85668aae host host local
uywi2i7qukux ingress overlay swarm
1b6094dcff7f none null local
x2jpob7wnpa4 web overlay swarm
root@manager:/docker# cd ..
root@manager:/# mkdir /swarm
root@manager:/# cd /swarm/
root@manager:/swarm# vi web.yml
<web.yml> - gyounseo 님 notion 참고
***********
version: "3"
services:
nginx:
image: nginx
deploy:
replicas: 4
placement:
constraints: [node.role != manager] # manager에는 할당 x
restart_policy:
condition: on-failure # 실패할 때
max_attempts: 3 # 최대 3번까지 실행을 하겠다.
environment:
SERVICE_PORTS: 80 # 데몬의 서비스 포트를 80으로 하겠다.
networks:
- web
proxy:
image: dockercloud/haproxy # 도커 허브에서 받아와야 했음!
depends_on:
- nginx
volumes:
- /var/run/docker.sock:/var/run/docker.sock # 마운트 - 로컬과 컨테이너 내부
ports:
- "80:80"
networks:
- web # 방금 만든 네트워크
deploy:
mode: global # <-> replicas
placement:
constraints: [node.role == manager]
networks:
web:
external: true
***********
< -c 옵션을 사용한 compose 파일 지정>
root@manager:/swarm# docker stack deploy -c web.yml web
root@manager:/swarm# docker stack ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
v4qalucd4uwt web_nginx.1 nginx:latest worker2 Running Preparing 5 seconds ago
neaupjp3dtya web_nginx.2 nginx:latest worker1 Running Preparing 5 seconds ago
5ax3za4cau2v web_nginx.3 nginx:latest worker2 Running Preparing 5 seconds ago
apdyj9ejt2h2 web_nginx.4 nginx:latest worker1 Running Preparing 5 seconds ago
c3sff4doprn9 web_proxy.nyx5uw0hp9cseo3wfydaekyk4 dockercloud/haproxy:latest manager Running Preparing less than a second ago
<curl 명령어로 정상적으로 작동하는지 확인>
root@manager:/swarm# curl 211.183.3.200
root@worker1:~# docker ps
root@worker1:~# docker psroot@worker1:~# docker exec -it 7e9a36078067 /bin/bash
root@7e9a36078067:/# cd /usr/share/nginx/html/ root@7e9a36078067:/usr/share/nginx/html# ls
50x.html index.html
root@7e9a36078067:/usr/share/nginx/html# echo nginx1111 >index.html
curl localhost 명령어를 여러번 쳐서 확인하면 됨 nginx html 화면 or nginx1111 html 화면이 번갈아 나올것임
<portainer>
root@manager:/var/run# docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock --name portainer --restart=always portainer/portainer
<visualizer> - stack deploy하기
root@manager:/visual# vi visual.yml
<visual.yml>
********
version: "3"
services:
visual:
image: dockersamples/visualizer
ports:
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: global
placement:
constraints: [node.role == manager]
********
root@manager:/visual# docker stack deploy -c visual.yml visualizer
root@manager:/visual# docker stack ps visualizer
docker-compose로 구성했던 워드프레스를 적절하게 수정해서 stack deploy를 해보세요 단, db는 manager 노드의 /db 폴더에 데이터베이스가 저장이 되어야 하고, 3대의 wordpress 컨테이너들 은 워커에서 동작 해야한다
<docker-compose.yml>
********
version: "3"
services:
wp:
image: wordpress
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
restart_policy:
condition: on-failure
max_attempts: 3
environment:
SERVICE_PORTS: 80
WORDPRESS_DB_HOST: "db"
WORDPRESS_DB_USER: "wpuser"
WORDPRESS_DB_PASSWORD: "1234"
WORDPRESS_DB_NAME: "wordpress"
# links:
# - "db"
depends_on:
- "db"
networks:
- web
proxy:
image: dockercloud/haproxy
depends_on:
- wp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
networks:
- web
deploy:
mode: global
placement:
constraints: [node.role == manager]
db:
image: mariadb
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
restart_policy:
condition: on-failure
max_attempts: 3
environment:
MYSQL_ROOT_PASSWORD: "1234"
MYSQL_DATABASE: "wordpress"
MYSQL_USER: "wpuser"
MYSQL_PASSWORD: "1234"
volumes:
- "/mdb:/var/lib/mysql"
networks:
- web
networks:
web:
external: true
********
<worker 1,2 에서 wordpress 이미지가 있어야 함>
<--with-registry-auth 옵션을 사용해 deploy 해야함>