kakao Cloud school 2기 D+28

LEE EUI JOO·2022년 12월 8일
0

Docker

목록 보기
5/8
post-thumbnail

1. MSA (Micro Service Architecture)

단일 프로그램을 각 컴포넌트 별로 나누어 작은 서비스의 조합으로 구축하는 방법


  • docker_gwbridge = eth0 과 비슷하다고 보면된다.

1-1 docekr replicas (랜덤생성)

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

1-2 docker constraint

<랜덤 하게 생성하지 않고 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

<삭제  다시>

1-3 docker global

<각각의 노드마다 하나씩 올라오게 만드는 >

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

2. Rolling Update

  • 태스크(컨테이너)의 순차적 업데이트
  • 옵션 : --update -delay <시간>

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

  • 만약 업데이트를 했는데 문제가 생겼다 - 원상복구 rollback 이 가능하다
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

2-1 Parallelism

  • 여러개의 태스크를 병렬로 업데이트 하는 옵션

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

3. 실습 문제

현재 내 도커 허브에 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


  • create이나 update 할 때 이미지를 못 받아와서 --with-registry-auth를 붙여야 하는 이유
    시간 동기화 문제일 수도 있고, 자격증명 문제일 수도 있음!
    cat ~/.docker/config.json 자격증명 볼 수 있다. 앞쪽에 써야 잘 먹힌다!

4. 네트워크 만들기

  • 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

5. 로드 밸런싱 증명 (HAproxy)

  • 아무 worker 노드로 들어가서 테스트를 해본다/

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 화면이 번갈아 나올것임

6. Portainer / Visualizer

<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


6. 실습 문제

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 해야함>

profile
무럭무럭 자라볼까

0개의 댓글