서비스 배포

Woojin Cho·2023년 4월 30일
0

teamcho

목록 보기
1/1

기본 환경

Traefik을 Reverse Proxy로 사용 중

Docker overlay network "traefik"이 external network로 정의되어 있고, traefik은 이 네트워크와 연결되어 있음.
따라서, Traefik을 사용하는 서비스의 네트워크는 항상 "traefik"을 포함하고 있어야 함.

  some-service:
    ...
    networks:
      - traefik
      - ...

Traefik은 Docker label을 읽어서 reverse proxy 설정을 업데이트함.

배포 전 확인!

기본
Stack 이름 겹치지 않는지 확인

deploy
replicas - DB가 2개 이상의 replicas를 갖지 않도록 확인
placement.constraints - 적절하게 정의되었는지 (대부분 서비스는 node.role == worker 명시 필요)
resources.limits - 테스트 배포에서는 넉넉히, 운영 배포에서는 필요 수준으로만 (서비스 비용 청구 근거)
labels
..router, service, middleware 이름 겹치지 않는지 확인
..도메인이 겹치지 않는지
..(참고) 운영 배포 시에는 Stack Name을 도메인 네임으로 사용하도록 유도

docker-compose.yml 작성 예제

Volume을 사용하지 않는 서비스의 배포

예시

################################################################
# 볼륨을 사용하지 않는 서비스의 배포
################################################################
version: "3.8"

# SERVICES
services:
  # your-service
  your-service:
    image: registry-url/image-name:image-tag
    environments:
      IF_YOU_NEED: your-environment
    command: if command required --port=80
    # note this!
    deploy:
      mode: replicated
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 12
      update_config:
        parallelism: 1
        order: start-first
        delay: 30s
        failure_action: rollback
      placement:
        constraints:
          - node.role == worker
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
      labels:
        - "traefik.enable=true"
        - "traefik.network=traefik"
        # http
        - "traefik.http.routers.web-your-service.entrypoints=web"
        - "traefik.http.routers.web-your-service.rule=Host(`your-service.example.com`)"
        - "traefik.http.routers.web-your-service.middlewares=http-redirect"
        # https
        - "traefik.http.routers.websecure-your-service.entrypoints=websecure"
        - "traefik.http.routers.websecure-your-service.tls=true"
        - "traefik.http.routers.websecure-your-service.rule=Host(`your-service.example.com`)"
        - "traefik.http.routers.websecure-your-service.service=your-service"
        # service
        - "traefik.http.services.your-service.loadbalancer.server.port=80"
    logging:
      driver: "json-file"
      options:
        max-size: "64M"
        max-file: "4"
    networks:
      - traefik

# NETWORKS
networks:
  traefik:
    external: true

볼륨을 사용하는 서비스의 배포

예시

################################################################
# 볼륨을 사용하는 서비스의 배포
################################################################
version: "3.8"

# SERVICES
services:
  # your-service
  your-service:
    image: registry-url/image-name:image-tag
    environments:
      IF_YOU_NEED: your-environment
    command: if command required --port=80
    # note this!
    deploy:
      mode: replicated
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 12
      update_config:
        parallelism: 1
        order: start-first
        delay: 30s
        failure_action: rollback
      placement:
        constraints:
          - node.role == worker
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
      labels:
        - "traefik.enable=true"
        - "traefik.network=traefik"
        # http
        - "traefik.http.routers.web-your-service.entrypoints=web"
        - "traefik.http.routers.web-your-service.rule=Host(`your-service.example.com`)"
        - "traefik.http.routers.web-your-service.middlewares=http-redirect"
        # https
        - "traefik.http.routers.websecure-your-service.entrypoints=websecure"
        - "traefik.http.routers.websecure-your-service.tls=true"
        - "traefik.http.routers.websecure-your-service.rule=Host(`your-service.example.com`)"
        - "traefik.http.routers.websecure-your-service.service=your-service"
        # service
        - "traefik.http.services.your-service.loadbalancer.server.port=80"
    logging:
      driver: "json-file"
      options:
        max-size: "64M"
        max-file: "4"
    volumes:
      # bind는 container가 가동하는 host의 disk를 사용 - placement에서 node를 특정하지 않은 경우 사용하지 말 것
      - type: bind
        source: /host/directory
        target: /docker/dicrectory-1
      - type: volume
        source: your-external-volume-name
        target: /docker/directory-2
      - type: volume
        source: nfs-name__dir1__dir2__dir3
        target: /docker/dir1/dir2/dir3
    networks:
      - traefik
      
# VOLUMES
volumes:
  # External
  your-external-volume-name:
    external: true
  # New (NFS) - [규칙] <nfs 이름>__<directory>__<sub directory>__<...> ("/" 대신 "__" 사용)
  nfs-name__dir1__dir2__dir3:
    driver_opts:
      type: "nfs"
      o: "addr=your.nfs.example.com,rw,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,nfsvers=4.1"
      device: ":/dir1/dir2/dir3"

# NETWORKS
networks:
  traefik:
    external: true

하나의 Stack에 여러 서비스 배포

예시

################################################################
# Frontend (볼륨 X)와 DB (볼륨 O)을 하나의 Stack에서 배포
# [NOTE] 
#  Frontend는 Traefik과 your-db-network에 모두 연결
#  DB는 your-db-network에만 연결 ~ Reverse Proxy 사용하지 않아서
################################################################
# SERVICES
services:
  # your-frontend
  your-frontend:
    image: registry-url/your-frontend-image:image-tag
    environments:
      IF_YOU_NEED: your-environment
    command: if command required --port=80
    # note this!
    deploy:
      mode: replicated
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 12
      update_config:
        parallelism: 1
        order: start-first
        delay: 30s
        failure_action: rollback
      placement:
        constraints:
          - node.role == worker
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
      labels:
        - "traefik.enable=true"
        - "traefik.network=traefik"
        # http
        - "traefik.http.routers.web-your-frontend.entrypoints=web"
        - "traefik.http.routers.web-your-frontend.rule=Host(`your-frontend.example.com`)"
        - "traefik.http.routers.web-your-frontend.middlewares=http-redirect"
        # https
        - "traefik.http.routers.websecure-your-frontend.entrypoints=websecure"
        - "traefik.http.routers.websecure-your-frontend.tls=true"
        - "traefik.http.routers.websecure-your-frontend.rule=Host(`your-frontend.example.com`)"
        - "traefik.http.routers.websecure-your-frontend.service=your-frontend"
        # service
        - "traefik.http.services.your-frontend.loadbalancer.server.port=80"
    logging:
      driver: "json-file"
      options:
        max-size: "64M"
        max-file: "4"
    networks:
      - traefik
      - your-db-network

  # your-db
  your-db:
    image: registry-url/your-db-image:image-tag
    environments:
      IF_YOU_NEED: your-environment
    command: if command required --port=80
    # note this!
    deploy:
      mode: replicated
      # DB는 replicas = 1이어야 함 (cluster 구성하려면 volume 대신 bind를 사용!)
      replicas: 1
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 12
      update_config:
        parallelism: 1
        # DB는 
        order: stop-first
        delay: 30s
        failure_action: rollback
      placement:
        constraints:
          - node.role == worker
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
    logging:
      driver: "json-file"
      options:
        max-size: "64M"
        max-file: "4"
    volumes:
      - type: volume
        source: volume-for-your-db__var__lib__your-db
        target: /var/lib/your-db
    networks:
      - traefik
      - your-db-network

# VOLUMES
volumes:
  # External
  volume-for-your-db__var__lib__your-db:
    external: true
  
# NETWORKS
networks:
  traefik:
    external: true
  your-db-network:
    driver: overlay

고급 docker-compose.yml

yaml-anchor

go template

profile
digital platform

0개의 댓글