iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0
DevOps

Docker獸 究極進化 ~~ Kubernetes獸系列 第 13

Day-13 熟悉 Docker-Compose 進階功能

前言

這章節將會介紹一些docker-compose較為進階的功能,希望有特殊需求的小夥伴可以參考看看。

environment

可以透過environment進行單值的環境變數輸入

environment:
	- REDIS_HOST=redis
	- REDIS_PORT=6379

env_file

可以透過env_file來設定整個檔案的環境變數

env_file:
	- prd.env

volumes

能夠掛載特定的資料夾或是已存在的資料卷容器

volumes:
	- ./app/:/usr/src/app/app

此外,也能夠加上ro之類的參數,設定為唯讀

volumes:
	- ./app/:/usr/src/app/app:ro

volumes from

能夠從其他containers或volumes掛載特定資料,同樣也能加上讀寫的參數。

volumes_from:
	- service_name:ro
	- container:container_name:rw

config

$ docker-compose -f <docker-compose.yaml> config

使用config command會讓你顯示目前docker-compose所解析到的配置。

$ docker-compose -f docker-compose-prd.yaml config
networks:
  ironman-net:
    driver: bridge
services:
  ironman:
    container_name: ironman
    depends_on:
    - redis
    environment:
      REDIS_HOST: redis
      REDIS_PORT: '6379'
    image: ghjjhg567/ironman:latest
    logging:
      driver: json-file
      options:
        max-file: '3'
        max-size: 1M
    networks:
      ironman-net: null
    restart: always
    volumes:
    - /Users/shihjie/PycharmProjects/ironman_2020/app:/usr/src/app/app:rw
  nginx:
    container_name: nginx
    image: nginx
    networks:
      ironman-net: null
    ports:
    - 80:80/tcp
    restart: always
    volumes:
    - /Users/shihjie/PycharmProjects/ironman_2020/nginx/nginx.conf:/etc/nginx/nginx.conf:rw
    - /Users/shihjie/PycharmProjects/ironman_2020/nginx/default.conf:/etc/nginx/conf.d/default.conf:rw
  redis:
    container_name: redis
    image: redis:4.0
    networks:
      ironman-net: null
    ports:
    - 6379:6379/tcp
    restart: always
version: '3.0'

Base template

$ docker-compose -f <base.yaml> -f <extension.yaml>

還記得上個章節所說到的如何讓docker-compose因應不同環境啟動嗎?

更好的做法是有個base template,並且讓環境相關配置寫在extension當中。

Base

base.yaml(將原先yaml檔當中的env_file配置給拿掉當作base yaml)

version: '3'
services:
    nginx:
      container_name: nginx
      image: nginx
      ports:
        - "80:80"
      volumes:
        - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      restart: always
      networks:
        - ironman-net
    redis:
      container_name: redis
      image: redis:4.0
      ports:
        - "6379:6379"
      restart: always
      networks:
        - ironman-net
    ironman:
      container_name: ironman
      image: ghjjhg567/ironman:latest
      volumes:
        - ./app/:/usr/src/app/app
      restart: always
      networks:
        - ironman-net

networks:
  ironman-net:
    driver: bridge

之後依序建立stg與prd環境的yaml檔

Stg

stg.yaml

version: '3'
services:
    ironman:
      env_file:
        - stg.env

Prd

prd.yaml

version: '3'
services:
    ironman:
      env_file:
        - prd.env

Test

使用上面教過的config我們可以知道docker-compose已經吃到了環境設定檔了。

$ docker-compose -f base.yaml -f stg.yaml config
networks:
  ironman-net:
    driver: bridge
services:
  ironman:
    container_name: ironman
    environment:
      REDIS_HOST: redis
      REDIS_PORT: '6379'
    image: ghjjhg567/ironman:latest
    networks:
      ironman-net: {}
    restart: always
    volumes:
    - /Users/shihjie/PycharmProjects/ironman_2020/app:/usr/src/app/app:rw
  nginx:
    container_name: nginx
    image: nginx
    networks:
      ironman-net: {}
    ports:
    - 80:80/tcp
    restart: always
    volumes:
    - /Users/shihjie/PycharmProjects/ironman_2020/nginx/default.conf:/etc/nginx/conf.d/default.conf:rw
    - /Users/shihjie/PycharmProjects/ironman_2020/nginx/nginx.conf:/etc/nginx/nginx.conf:rw
  redis:
    container_name: redis
    image: redis:4.0
    networks:
      ironman-net: {}
    ports:
    - 6379:6379/tcp
    restart: always
version: '3.0'

Build

$ docker-compose -f up —build

如果在yaml當中同時有著image與build的話,則會在輸入—build的argument同時,去依照設定的Dockerfile在啟動前重新build image。

version: '3'
services:
    nginx:
      container_name: nginx
      image: nginx
      ports:
        - "80:80"
      volumes:
        - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      restart: always
      networks:
        - ironman-net
    redis:
      container_name: redis
      image: redis:4.0
      ports:
        - "6379:6379"
      restart: always
      networks:
        - ironman-net
    ironman:
      container_name: ironman
      image: ghjjhg567/ironman:latest
      build:
        context: .
        dockerfile: Dockerfile
      volumes:
        - ./app/:/usr/src/app/app
      restart: always
      networks:
        - ironman-net

networks:
  ironman-net:
    driver: bridge

links

能夠使compose內的container互相連結

links:
- nginx
- redis

external_links

能夠使compose外的containers也能與compose內的containers進行連結,但前提是還是要有一格以上的外部container連到compose內的network

external_links:
- postgres
- mongodb

depend on

depend on 可以讓你的containers有順序性的create,舉例來說,如果我想要讓redis container先create,這樣web service的cache才能將data丟進去,這時我就能讓web service depend on redis

depends_on:
        - redis

logging driver

通過logging為compose配置logs的儲存格式與容量大小。

version: '3'
services:
    nginx:
      container_name: nginx
      image: nginx
      ports:
        - "80:80"
      volumes:
        - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      restart: always
      networks:
        - ironman-net
    redis:
      container_name: redis
      image: redis:4.0
      ports:
        - "6379:6379"
      restart: always
      networks:
        - ironman-net
    ironman:
      container_name: ironman
      image: ghjjhg567/ironman:latest
      volumes:
        - ./app/:/usr/src/app/app
      env_file:
        - prd.env
      restart: always
      networks:
        - ironman-net

networks:
  ironman-net:
    driver: bridge

Resource limit

運用單值標籤,進行資源的配置與限制。這邊就不對其值一一解說。

cpu_shares: 73
cpu_quota: 50000
cpuset: 0,1
mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true
restart: always
read_only: true
shm_size: 64M
stdin_open: true
tty: true

Entrypoint

類似於Dockerfile中的entrypoint,而在yaml中設定entrypoint還能夠覆蓋掉dockerfile原先的entrypoint。

entrypoint: docker-entrypoint.sh

此外 compose的entrypoint還有另種書寫格式

entrypoint:
	- /usr/local/bin/uwsgi
	- --ini
	- /usr/src/app/uwsgi.ini

Health Check

能夠在Container啟動時進行健康檢查,檢查像是depend_on的服務是否能通、或是data initalize有沒有成功....等。此外,Health Check在每個Container只能出現一次。

那我簡單介紹一下healthCheck嚇得key-value吧:

  • test: healthCheck command: 為一個list,且list[0]必須為"CMD"或"CMD-SHELL"
  • interval: 執行HealthCheck的間隔時間
  • timeout: 超時時間
  • retires: 重試的次數
version: '3'
services:
    nginx:
      container_name: nginx
      image: nginx
      ports:
        - "80:80"
      volumes:
        - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      restart: always
      networks:
        - ironman-net
    redis:
      container_name: redis
      image: redis:4.0
      ports:
        - "6379:6379"
      restart: always
      networks:
        - ironman-net
    ironman:
      container_name: ironman
      image: ghjjhg567/ironman:latest
      volumes:
        - ./app/:/usr/src/app/app
      env_file:
        - prd.env
      restart: always
      networks:
        - ironman-net 
      depends_on:
        - nginx
        - redis
      healthcheck:
        test: ["CMD-SHELL", "curl", "-X", "GET", "http://nginx"]
        interval: 10s
        timeout: 5s
        retries: 5

networks:
  ironman-net:
    driver: bridge

以上面為例,健康檢查的commmand為

$ curl -X GET http://nginx

Github Repo

本篇章所有程式碼將放在下面的github project當中的branch day-13

https://github.com/Neskem/ironman_2020/tree/day-13

結語

這章節主要帶給大家較為進階與不為人知的compose功能以及功能的實作方式,那docker-compose的章節也就在這告一個段落了。下個章節開始會進入到Kubernetes的世界,敬請期待!!

https://ithelp.ithome.com.tw/upload/images/20200928/20129737ob8h1t5XOr.png

Docker-Compose獸發出了銀色光芒並開始放空,看來是要進化了。


上一篇
Day-12 煉成 Docker-Compose YAML
下一篇
Day-14 初觸 Kubernetes
系列文
Docker獸 究極進化 ~~ Kubernetes獸30

尚未有邦友留言

立即登入留言