第六部分、Docker Compose

1、Docker Compose 介紹

1.一、Docker Compose 簡介

        Compose 是用於配置和運行多個 Docker 容器的工具。經過Compose,你可使用 YAML 文件來配置應用程序,而後使用 docker-compose 命令,就能夠從配置文件中建立並啓動全部服務。php

        說通俗點,Docker Compose 就是一個容器編排工具(固然了,容器編排工具不知這一種,事後咱們要學習的 Kubernetes 就是一種使用很普遍的容器編排工具)。好比你如今要使用 Docker 部署一套 lnmp 環境,以前的方案是分別拉取 NginxMySQLPHP 三個鏡像,而後基於這三個鏡像分別啓動三個容器,這期間你還得考慮數據持久化、網絡互通等問題,這個過程是有點麻煩的;那麼有沒有什麼辦法能夠簡化這些步驟? Docker Compose 的出現解決了這個問題,經過 YAML 格式的配置文件,你能夠一步到位的部署好你的 lnmp 環境,後面咱們將手動操做,以便加深理解。html

        經過 Dockerfile 能夠管理一個單獨的容器,而經過 Docker Compose 你能夠更方便的管理一組相關聯的容器。前端

        使用Compose基本上是一個三步的過程:node

  1. 使用 Dockerfile 定義應用程序的環境;
  2. docker-compose.yml 中定義組成您的應用程序的服務,以便不一樣的容器能夠相互通訊;
  3. 經過執行 docker-compose up 啓動並運行您的整個應用程序。

        Docker Compose 的核心就是這個 YAML 文件,當你建立好這個 YAML 文件後,你能夠經過 docker-compose 命令來同時管理(建立、啓動、中止、刪除等)一組相關聯的容器。python

1.二、Docker Compose YAML 文件

        隨着 Docker 的發展,Docker 迭代了不少個版本,那麼對應的 Docker Compose 的 YAML 文件的書寫格式也進行了幾回升級,目前最新版爲 3.7,支持 Docker 18.06.0 以上的版本,也是咱們用的比較多的格式版本。mysql

        YAML 文件書寫格式能夠參考此連接linux

       Docker Compose 的  YAML 文件一般由三大部分組成的(固然還有其餘模塊),分別是:nginx

  • Services:一個 Server 表明一個/組 Container(能夠來自 DockerHub 的 image 來建立,也能夠來自本地的 Dockerfile Build 來建立),Service 模塊中能夠引用如下的 Networks 模塊和 Volumes 模塊 定義的 network 和 volume;
  • Networks:要加入的網絡;
  • Volumes:volume 掛載路徑設置,能夠設置宿主機路徑 (HOST:CONTAINER) 或加上訪問模式 (HOST:CONTAINER:ro)。
         docker run -v HOST:CONTAINER 若是未指定 「 rw」 或 「 ro」,則默認爲 」 rw「,即 」 read-write「 模式——」 docker run -v HOST:CONTAINER:rw「,若是你但願掛載文件爲只讀,則可使用 」 ro「 選項,即 」 docker run -v HOST:CONTAINER:ro「        

        Services 很像 docker container create ;一樣地,NetworksVolumes 相似於docker network createdocker volume creategit

2、安裝 Docker Compose

        不一樣平臺安裝方法不一樣,若是你是 Mac 平臺,那麼你安裝 Docker 時,就已經安裝好了 docker-compose 工具;下面以經常使用的 CentOS 爲例,介紹安裝 docker-compose 的過程,其餘平臺安裝方法參考 https://docs.docker.com/compose/install/github

2.一、pip 方式安裝 docker-compose

        Docker Compose 是使用 python 編寫的,你可使用 pip 的方式安裝;這種安裝方式相比於下面另外一種安裝方式要快一點,國內服務器可使用這種方式安裝。

# 安裝epel和pip以及python-devel
$ sudo yum -y install epel-release
$ sudo yum -y install python-pip python-devel

# 經過pip安裝 docker-compose
$ sudo pip install docker-compose --ignore-installed requests

2.二、curl 方式安裝docker-compose

        國內用戶訪問 github.com 巨慢,能夠用pip的方式安裝

# 下載 docker-compose 工具,並指定下載路徑
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 賦予可執行權限
$ sudo chmod +x /usr/local/bin/docker-compose

2.三、使用幫助

        安裝完成後你可使用 docker-compose --help 命令來查看 docker-compose 命令的使用幫助,看不懂不要緊,後期使用此命令時天然會理解這些參數的意義。

$ sudo docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

3、使用 Docker Compose

3.一、一個簡單的 docker-compose.yml 文件示例

        在存在 docker-compose.yml 的目錄下使用 docker-compose up 命令,能夠直接建立並啓動配置文件中的容器;通常狀況下,docker-compose.ylm 文件與項目文件放在同一個目錄,此目錄名稱爲默認的項目名稱,固然你也能夠在 docker-compose up 的時候加上 -p 參數來自定義項目名稱。

        如下示例來自 Wordpress,YAML 格式不瞭解的,建議花二分鐘看一下 此連接。如下示例中你能夠看到一些 」key「 ,好比 versionserviceswordpressimagerestart 等,你能夠在 這裏 找到這些 」key「 的具體意義,若是你對 docker 有必定的瞭解的話,下面這個示例文件內的 」key「 你應該是能夠看得明白的。

version: "3.7"
services:

 wordpress:
   image: wordpress:latest
   restart: always
   ports:
     - 8080:80
   environment:
     WORDPRESS_DB_HOST: db
     WORDPRESS_DB_USER: userwp
     WORDPRESS_DB_PASSWORD: pwdwp
     WORDPRESS_DB_NAME: wordpress
   volumes:
     - wordpress:/var/www/html
   networks:
     - db-net
     - web-net

 db:
   image: mysql:8.0.18
   command: --default-authentication-plugin=mysql_native_password
   restart: always
   environment:
     MYSQL_ROOT_PASSWORD: password
     MYSQL_DATABASE: wordpress
     MYSQL_USER: userwp
     MYSQL_PASSWORD: pwdwp

   volumes:
     - mysql8_db:/var/lib/mysql
   networks:
     - db-net

volumes:
  mysql8_db:
  wordpress:
networks:
  web-net:
  db-net:

        解釋一下上面這個配置文件,docker-compose.yml 配置文件內部結構由三部分組成:

  • Services:此例中包含 wordpress 和 db 兩個 service
  • Volumes:此例中包含 wordpress 和 mysql8_db 兩個 volume
  • Networks:此例中包含 web-net 和db-net 兩個 network

        你能夠這樣理解,Volumes 和 Networks 都屬於容器(Services)的一部分,或者說容器(Services)調用 Volumes 和 Networks 標籤聲明的 volumes 和 networks,因此,調用的 volumes 和 networks 的名稱須要與聲明的名稱相同,畫了個簡單的圖,你能夠對照代碼看一下。

3.二、使用 docker-compose 工具

        以上配置文件建立好之後,咱們即可以經過 docker-compose 命令來進行一番體驗了。

$ sudo pwd
/docker/myblog

# Create and start containers, -d 後臺運行
$ sudo docker-compose up -d
Creating network "myblog_web-net" with the default driver
Creating network "myblog_db-net" with the default driver
Creating volume "myblog_mysql8_db" with default driver
Creating volume "myblog_wordpress" with default driver
Creating myblog_db_1        ... done
Creating myblog_wordpress_1 ... done
        實際上 docker-compose create 已經不建議使用,若是你只想建立容器而不啓動,官方建議使用 docker-compose up --no-start ,而後再經過 docker-compose start 來啓動這些容器。

        另外注意,docker-compose scale 這個命令已經廢棄,不建議使用

        執行 docker-compose --help 後能夠看到 docker-compose 工具的詳細用發,都是些基礎的 IT 英文,我就不翻譯了,請務必自行練習如下命令:

  • docker-compose up
  • docker-compose stop
  • docker-compose start
  • docker-compose down
  • docker-compose images
  • docker-compose log
  • docker-compose ps
  • docker-compose top

4、docker-compose.yml 文件

4.一、官方示例文件

        如下爲官方 docker-compose.yml 示例文件

version: "3.7"
services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]

  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  frontend:
  backend:

volumes:
  db-data:

4.二、Services 配置參數

        這部分至關於 Google 翻譯官方文檔了,稍微整理了一下,感受不經常使用的參數我就沒列出來,因此不是很全面,以爲看着彆扭的話你能夠直接看官方文檔。

4.2.一、build - 構建

4.2.1.一、build - 構建

        容器的建立能夠來自 Docker Hub 的鏡像,也能夠來自本地使用 Dockerfile 構建的鏡像,build 即是指定容器爲本地構建的 Dockerfile 文件的路徑;

        指定構建鏡像的上下文路徑:

        例如 webapp 服務,指定爲從上下文路徑 ./dir/dockerfile 所構建的鏡像:

version: "3.7"
services:
  webapp:
    build: ./dir

        或者,指定具體的 Dockerfile 文件:

version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate

4.2.1.二、context - 上下文

        構建鏡像的上下文(Dockerfile 的目錄),能夠是相對路徑(相對於 docker-compose.yml 文件的相對路徑)和絕對路徑。

build:
  context: ./dir

4.2.1.三、dockerfile - dockerfile 文件

build:
  context: .
  dockerfile: Dockerfile-alternate

4.2.1.四、args - 構建參數

        添加構建參數,這是隻能在構建過程當中訪問的環境變量。

        前提是你須要在 Dockerfile 中指定參數,

ARG buildno
ARG gitcommithash

RUN echo "Build number: $buildno"
RUN echo "Based on commit: $gitcommithash"

        而後在 docker-compose 的 build 下指定參數,您能夠傳遞映射或列表:

build:
  context: .
  args:
    buildno: 1
    gitcommithash: cdc3b19
build:
  context: .
  args:
    - buildno=1
    - gitcommithash=cdc3b19
    注意:在Dockerfile中,若是在FROM指令以前指定ARG,則在FROM下的構建指令中ARG不可用。若是您須要一個參數在兩個地方均可用,請在FROM指令下指定該參數。有關用法的詳細信息,請參閱瞭解 ARGS和FROM的交互方式

4.2.1.五、cache_from - 緩存images

        默認狀況下,在構建 Docker 鏡像時,Docker 使用它的構建緩存來檢查它是否能夠跳過Dockerfile 中的任何步驟,該 cache_from 參數告訴 docker,可用緩存的鏡像是什麼;若是提供的鏡像和當前版本具備相同的層(以前提過層的概念),則能夠得到與在同一臺計算機上構建鏡像時以相同層構建出更快的速度。

build:
  context: .
  cache_from:
    - alpine:latest
    - corp/web_app:3.14

4.2.1.六、labels - Docker 標籤

        格式有下面兩種:

build:
  context: .
  labels:
    com.example.description: "Accounting webapp"
    com.example.department: "Finance"
    com.example.label-with-empty-value: ""
build:
  context: .
  labels:
    - "com.example.description=Accounting webapp"
    - "com.example.department=Finance"
    - "com.example.label-with-empty-value"

4.2.1.七、target - 構建階段

        根據Dockerfile中的定義構建指定的階段。 有關詳細信息,請參見以前提過的多階段構建。

build:
  context: .
  target: prod

4.2.二、command - 覆蓋命令

        覆蓋容器啓動時的默認命令

command: bundle exec thin -p 3000
command: ["bundle", "exec", "thin", "-p", "3000"]

4.2.三、container_name - 指定容器名稱

        指定自定義容器名稱,而不是生成的默認名稱。

container_name: my-web-container
        因爲Docker容器名稱必須惟一,所以若是您指定了自定義名稱,則不能將服務擴展到1個以上的容器。

4.2.四、deploy - 集羣部署

4.2.4.一、deploy - 集羣部署

        指定與服務的部署和運行有關的配置,只在 swarm 模式下才會有用,會被 docker-compose updocker-compose run 忽略.

version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

4.2.4.二、endpoint_mode - 訪問集羣服務的方式

        兩種模式:

  • endpoint_mode: vip - Docker爲服務分配了一個虛擬IP(VIP),該虛擬IP充當客戶端訪問網絡上服務的前端。 Docker在客戶端和服務的可用工做節點之間路由請求,而無需客戶端知道有多少節點正在參與服務或其IP地址或端口。 (這是默認設置。)
  • endpoint_mode: dnsrr- DNS輪詢(DNSRR)服務發現不使用單個虛擬IP。 Docker設置服務的DNS條目,以便對服務名稱的DNS查詢返回IP地址列表,而且客戶端直接鏈接到其中之一。在想要使用本身的負載平衡器或混合Windows和Linux應用程序的狀況下,DNS輪詢頗有用。
version: "3.7"

services:
  wordpress:
    image: wordpress
    ports:
      - "8080:80"
    networks:
      - overlay
    deploy:
      mode: replicated
      replicas: 2
      endpoint_mode: vip

  mysql:
    image: mysql
    volumes:
       - db-data:/var/lib/mysql/data
    networks:
       - overlay
    deploy:
      mode: replicated
      replicas: 2
      endpoint_mode: dnsrr

volumes:
  db-data:

networks:
  overlay:

4.2.4.三、labels - 指定標籤

        指定服務標籤。這些標籤僅在服務上設置,而不在服務的任何容器上設置。

version: "3.7"
services:
  web:
    image: web
    deploy:
      labels:
        com.example.description: "This label will appear on the web service"

4.2.4.四、mode - 集羣模式

       global(每一個羣集節點一個容器) orreplicated(指定數量的容器). 默認爲 replicated.

version: "3.7"
services:
  worker:
    image: dockersamples/examplevotingapp_worker
    deploy:
      mode: global

4.2.4.五、replicas - replicated 模式的容器數量

        若是選擇了 replicated 模式,replicas 用來指定運行的容器數量

version: "3.7"
services:
  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 6

4.2.4.六、resources - 資源限制

        如下示例中,redis服務被限制爲使用不超過50M的內存和0.50(單核的50%)的可用處理(CPU),並有最低20M的內存和0.25的CPU資源使用。

version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M

4.2.4.七、restart_policy - 重啓規則

        配置如何在退出容器時從新啓動容器。

  • condition:可選 none,on-failure 或者 any(默認值:any)。
  • delay:設置多久以後重啓(默認值:0)。
  • max_attempts:嘗試從新啓動容器的次數,超出次數,則再也不嘗試(默認值:一直重試)。
  • window:設置容器重啓超時時間(默認值:0)。
version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s

4.2.4.八、rollback_config - 回滾規則

        配置在更新失敗的狀況下應如何回滾服務。

  • parallelism:一次要回滾的容器數。若是設置爲0,則全部容器將同時回滾。
  • delay:每一個容器組回滾之間等待的時間(默認爲0s)。
  • failure_action:若是回滾失敗,該怎麼辦。其中一個 continue 或者 pause(默認pause)。
  • monitor:每一個容器更新後,持續觀察是否失敗了的時間 (ns|us|ms|s|m|h)(默認爲0s)。
  • max_failure_ratio:在回滾期間能夠容忍的故障率(默認爲0)。
  • order:回滾期間的操做順序。其中一個 stop-first(串行回滾),或者 start-first(並行回滾)(默認 stop-first )。

4.2.4.九、update_config - 更新規則

        配置應如何更新服務,對於配置滾動更新頗有用。

  • parallelism:一次更新的容器數。
  • delay:在更新一組容器之間等待的時間。
  • failure_action:若是更新失敗,該怎麼辦。其中一個 continue,rollback 或者pause (默認:pause)。
  • monitor:每一個容器更新後,持續觀察是否失敗了的時間 (ns|us|ms|s|m|h)(默認爲0s)。
  • max_failure_ratio:在更新過程當中能夠容忍的故障率。
  • order:回滾期間的操做順序。其中一個 stop-first(串行回滾),或者 start-first(並行回滾)(默認stop-first)。
version: "3.7"
services:
  vote:
    image: dockersamples/examplevotingapp_vote:before
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first

4.2.五、devices - 設備映射

        指定設備映射列表。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

4.2.六、dns - 定義DNS

        自定義 DNS 服務器,能夠是單個值或列表的多個值。

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9

4.2.七、dns_search - 定義DNS搜索域

        自定義DNS搜索域,能夠是單個值或列表。

dns_search: example.com
dns_search:
  - dc1.example.com
  - dc2.example.com

4.2.八、entrypoint - 入口點

        覆蓋容器默認入口點。

entrypoint: /code/entrypoint.sh
entrypoint:
    - php
    - -d
    - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
    - -d
    - memory_limit=-1
    - vendor/bin/phpunit
        注意:設置入口點會覆蓋全部使用 Dockerfile ENTRYPOINT 指令在服務鏡像上設置的默認入口點,並清除鏡像上的任何默認 CMD ,這意味着若是Dockerfile中有CMD指令,則會將其忽略。

4.2.九、env_file - 環境變量文件

        從文件添加環境變量。能夠是單個值或列表的多個值。

env_file: .env
env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

        .env 文件格式爲 VAR=VAL

# Set Rails/Rack environment
RACK_ENV=development

4.2.十、environment - 添加環境變量

        添加環境變量。您可使用數組或字典、任何布爾值,布爾值須要用引號引發來,以確保 YML 解析器不會將其轉換爲 True 或 False。

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:
environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET
       若是你使用了 build 選項,則在構建過程當中不會自動顯示 environment 中定義的變量,可使用 buildargs 子選項來定義構建時環境變量。

4.2.十一、expose - 聲明端口

        暴露端口,但不映射到宿主機,只被鏈接的服務訪問,僅能夠指定內部端口爲參數:

expose:
 - "3000"
 - "8000"

4.2.十二、external_links - 連接容器

        連接到在docker-compose.yml以外甚至在Compose以外啓動的容器,特別是對於提供共享或公共服務的容器。

external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql

4.2.1三、external_host - 添加主機映射

        添加主機名映射,相似 docker client --add-host

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

        實如今容器內修改host /etc/hosts 文件的效果

162.242.195.82  somehost
50.31.209.229   otherhost

4.2.1四、healthcheck - 健康檢查

        配置運行檢查,以肯定此服務的容器是否「健康」。

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"] # 設置檢測程序
  interval: 1m30s # 設置檢測間隔
  timeout: 10s # 設置檢測超時時間
  retries: 3 # 設置重試次數
  start_period: 40s # 啓動後,多少秒開始啓動檢測程序

4.2.1五、image - 指定鏡像

        指定要從中啓動容器的鏡像

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd

4.2.1六、labels - 標籤

        Services 容器標籤

labels:
  com.example.description: "Accounting webapp"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""
labels:
  - "com.example.description=Accounting webapp"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"

4.2.1七、logging - 日誌配置

        服務的日誌記錄配置。

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

        這個 driver 名稱爲服務的容器指定了日誌記錄驅動程序,與docker run --log-driver 選項相同,默認值爲 json-file,有如下三個選項:

driver: "json-file"
driver: "syslog"
driver: "none"

        僅在 json-file 驅動程序下,可使用如下參數,限制日誌得數量和大小;當達到文件限制上限,會自動刪除舊得文件。

logging:
  driver: json-file
  options:
    max-size: "200k" # 單個文件大小爲200k
    max-file: "10" # 最多10個文件

        syslog 驅動程序下,可使用 syslog-address 指定日誌接收地址。

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

4.2.1八、network_mode - 網絡模式

4.2.18.一、network_mode - 網絡模式

        設置網絡模式

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

        配置容器鏈接的網絡,引用一級 networks 下的條目 。

services:
  some-service:
    networks:
     - some-network
     - other-network

4.2.18.二、aliases - 別名

        網絡別名,能夠指定多個別名。

version: "3.7"

services:
  web:
    image: "nginx:alpine"
    networks:
      - new

  worker:
    image: "my-worker-image:latest"
    networks:
      - legacy

  db:
    image: mysql
    networks:
      new:
        aliases:
          - database
          - dbnet
      legacy:
        aliases:
          - mysql

networks:
  new:
  legacy:

4.2.18.三、ipv4_address、ipv6_address - 靜態網絡

        加入網絡後,爲此服務的容器指定一個靜態IP地址。

        一級 networks 部分中的相應網絡配置必須具備ipam塊,其子網配置覆蓋每一個靜態地址。

version: "3.7"

services:
  app:
    image: nginx:alpine
    networks:
      app_net:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10

networks:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "172.16.238.0/24"
        - subnet: "2001:3984:3989::/64"

4.2.1九、ports - 暴露端口

        使用宿主port:容器port(HOST:CONTAINER)格式或者僅僅指定容器的端口(宿主將會隨機選擇端口)均可以。

ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"

        長語法:長語法容許配置其餘不能以短格式表示的字段。

  • target: 容器內的端口
  • published: 公開暴露的端口
  • protocol: 端口協議 (tcporudp)
  • mode:host用於在每一個節點上發佈主機端口, 或ingress 用於羣模式端口以實現負載平衡
ports:
  - target: 80
    published: 8080
    protocol: tcp
    mode: host

4.2.20、restart - 重啓規則

        容器重啓規則

  • no:是默認的重啓策略,在任何狀況下都不會重啓容器。
  • always:容器老是從新啓動。
  • on-failure:在容器非正常退出時(退出狀態非0),纔會重啓容器。
  • unless-stopped:在容器退出時老是重啓容器,可是不考慮在Docker守護進程啓動時就已經中止了的容器
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

4.2.2一、secrets - 存儲敏感數據

        用來存儲敏感文件,如密碼等。

        短語法:如下示例使用短語法向redis服務授予對my_secretmy_other_secret機密的訪問權限。 將my_secret的值設置爲文件./my_secret.txt的內容,並將my_other_secret定義爲外部資源,這意味着它已經在Docker中定義,能夠經過運行docker secret create命令或其餘堆棧進行定義 部署。 若是外部secrets不存在,則堆棧部署將失敗,並顯示「未找到secrets」錯誤。

version: "3.7"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    secrets:
      - my_secret
      - my_other_secret
secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true

4.2.2二、security_opt - 修改概要標籤

        修改容器的概要標籤

security-opt:
  - label:user:USER   # 設置容器的用戶標籤
  - label:role:ROLE   # 設置容器的角色標籤
  - label:type:TYPE   # 設置容器的安全策略標籤
  - label:level:LEVEL  # 設置容器的安全等級標籤

4.2.2三、stop_grace_period

        在發送 SIGKILL 以前指定stop_signal,若是試圖中止容器(若是它沒有處理 SIGTERM(或指定的任何中止信號)),則須要等待的時間,默認狀況下,stop 在發送SIGKILL以前等待10秒鐘容器退出

stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒

4.2.2四、stop_signal - 容器中止信號

        設置中止容器的替代信號,默認狀況下使用 SIGTERM ;如下示例,使用 SIGUSR1 替代信號 SIGTERM 來中止容器。

stop_signal: SIGUSR1

4.2.2五、sysctls - 內核參數

        要在容器中設置的內核參數

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0
sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

4.2.2六、tmpfs - 臨時文件系統

        掛載臨時文件目錄到容器內部

tmpfs: /run
tmpfs:
  - /run
  - /tmp

4.2.2七、ulimit - 覆蓋容器默認ulimit

        覆蓋容器默認的 ulimit

ulimits:
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000

4.2.2八、volumes - 掛載volume

        將主機的數據卷或着文件掛載到容器裏。

        掛載一個目錄或者一個已存在的數據卷容器,能夠直接使用HOST:CONTAINER這樣的格式,或者使用HOST:CONTAINER:ro這樣的格式,後者對於容器來講,數據卷是隻讀的,這樣能夠有效保護宿主機的文件系統

version: "3.7"
services:
  web:
    image: nginx:alpine
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

  db:
    image: postgres:latest
    volumes:
      - "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
      - "dbdata:/var/lib/postgresql/data"

volumes:
  mydata:
  dbdata:

        數據卷的格式以下多種形式:

volumes:
  # 僅指定一個路徑時,Docker 會自動建立一個數據卷(此路徑是容器內部路徑)
  - /var/lib/mysql

  # 使用絕對路徑掛載數據卷
  - /opt/data:/var/lib/mysql

  # 以 Compose 配置文件爲中心的相對路徑做爲數據卷掛載到容器
  - ./cache:/tmp/cache

  # 使用用戶的相對路徑(~/ 表示的目錄是 /home/<用戶目錄>/ 或者 /root/)
  - ~/configs:/etc/configs/:ro

  # 掛載數據卷。
  - datavolume:/var/lib/mysql

4.2.2九、domainname, hostname, ipc, privileged, read_only, shm_size, stdin_open, tty, user, working_dir

        每一個值都只對應一個值,相似於其docker run的參數選項

user: postgresql
working_dir: /code

domainname: foo.com
hostname: foo
ipc: host

privileged: true

read_only: true
shm_size: 64M
stdin_open: true
tty: true

4.三、Volumes 配置參數

        容許您建立命名卷(不依賴volumes_from),這些卷能夠在多個服務中重用,而且可使用docker命令行或API。

        如下是兩種服務設置的示例,其中 db 的數據目錄做爲卷與另外一服務共享,以即可以按期備份它:

version: "3.7"

services:
  db:
    image: db
    volumes:
      - data-volume:/var/lib/db
  backup:
    image: backup-service
    volumes:
      - data-volume:/var/lib/backup/data

volumes:
  data-volume:

        一級volumes下的條目能夠爲空,在這種狀況下,它使用引擎配置的默認驅動程序(在大多數狀況下,這是 local驅動程序)。

4.3.一、labels - 標籤

        volume 的標籤

labels:
  com.example.description: "Database volume"
  com.example.department: "IT/Ops"
  com.example.label-with-empty-value: ""
labels:
  - "com.example.description=Database volume"
  - "com.example.department=IT/Ops"
  - "com.example.label-with-empty-value"

4.四、Networks 配置參數

        一級networks,容許您指定要建立的網絡。

4.4.一、driver - 網絡接入方式

    指定該網絡應使用哪一個驅動程序。

    默認驅動程序取決於您使用的Docker引擎的配置方式,可是在大多數狀況下,它bridge位於單個主機和overlaySwarm上。

4.4.1.一、bridge - 網橋

        Docker 默認的網絡接入方式

4.4.1.二、overlay - 覆蓋

        該overlay驅動程序建立一個跨多個節點命名的網絡

4.4.1.三、host 和 none

        使用主機的網絡,或者不使用網絡。等同於 docker run --network=hostdocker run --network=none,僅在使用docker stack命令時使用,若是使用docker-compose命令,請改用network_mode

4.4.二、IPAM - IP地址管理

        IP地址管理,有幾個屬性,每個屬性都是可選的:

  • driver:自定義IPAM驅動程序,而不使用默認的
  • config:有零個或多個配置塊的列表,每一個包含任何如下項:

    • subnet:子網CIDR格式表示一個網段

一個完整的例子:

ipam:
  driver: default
  config:
    - subnet: 172.28.0.0/16

4.4.三、labels - 網絡標籤

        網絡標籤

labels:
  com.example.description: "Financial transaction network"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""
labels:
  - "com.example.description=Financial transaction network"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"

4.4.四、name - 網絡名稱

        自定義網絡名稱

version: "3.7"
networks:
  network1:
    name: my-app-net

        它也能夠與external配合使用:

version: "3.7"
networks:
  network1:
    external: true
    name: my-app-net

4.五、configs 配置文件

        一級configs聲明定義或引用能夠授予此項目中的服務的配置。配置的來源是fileexternal

  • file:使用指定路徑中的文件內容建立配置
  • external:若是設置爲true,則表示此配置已建立,Docker不會嘗試建立它;若是它不存在,則會發生 config not found錯誤
  • name:Docker中配置對象的名稱,此字段可引用包含特殊字符的配置。

        在如下示例中,部署項目時建立了 my_first_config(as<stack_name> _my_first_config),而且Docker中已經存在my_second_config

configs:
  my_first_config:
    file: ./config_data
  my_second_config:
    external: true

        外部配置的另外一個方式是Docker中的config名稱與服務中存在的名稱不一樣時,如下示例修改了前一個示例,以使用名爲 redis_config 的外部配置。

configs:
  my_first_config:
    file: ./config_data
  my_second_config:
    external:
      name: redis_config

        配置好一級 configs 後仍然須要 將配置訪問權限授予 項目中的每一個服務。

4.六、secrets configuration reference

        頂級secrets聲明定義或引用的secrets,可在這個項目被授予服務。secrets 來源於fileexternal

  • file:使用指定路徑中的文件內容
  • external:若是設置爲true,則表示這個 secret 已經建立指定,Docker 不會嘗試建立它;若是它不存在,將報錯secret not found
  • name:Docker中 secret 的名稱

        在下面例子中,my_first_secret被建立爲<stack_name>_my_first_secret當堆棧被部署,並my_second_secret在多克爾已經存在。

        在此示例中部署項目時,將my_first_secret建立爲<stack_name> _my_first_secret,而且Docker中已經存在my_second_secret

secrets:
  my_first_secret:
    file: ./secret_data
  my_second_secret:
    external: true

        外部機密的另外一個方式是Docker中的secret名稱與服務中存在的名稱不一樣時,如下示例修改了前一個示例,以使用名爲redis_secret的外部secret。

# V3.5及以上
secrets:
  my_first_secret:
    file: ./secret_data
  my_second_secret:
    external: true
    name: redis_secret

5、Docker Compose 入門

        接下來咱們將使用 Docker Compose 構建一個簡單Python Web應用程序,該應用程序使用Flask框架,並在Redis中維護一個計數器程序(每訪問一次web應該,就給輸出的訪問次數+1)。儘管該示例使用Python,但並非說就須要你掌握 Python。

5.一、準備工做

        首先須要建立項目目錄,以及準備 Python 程序代碼,操做以下:

$ mkdir composetest
$ cd composetest

程序 app.py 的代碼以下:

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

        在 app.py 目錄下建立名爲 requirements.txt 的文件,文件內容以下

flask
redis

5.二、建立Dockerfile文件

        須要編寫一個構建 Docker鏡像 的 Dockerfile,該鏡像包含 Python 應用程序以及此演示項目所需的全部依賴關係;具體的 Dockerfile 文件內容以下:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]

        以上操做內容說明:

  • 以 Python 3.7 鏡像做爲基礎鏡像來構建新鏡像。
  • 將工做目錄設置爲/code
  • 設置flask命令使用的環境變量。
  • 安裝gcc,以便諸如MarkupSafe和SQLAlchemy之類的Python包能夠編譯加速。
  • 複製requirements.txt並安裝Python依賴項。
  • 將項目中的當前目錄複製到鏡像中的工做目錄。
  • 將容器的默認命令設置爲flask run

5.三、建立 docker-compose.yml 文件

version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

5.四、使用 docker-compose 構建啓動項目

        使用命令 docker-compose up 啓動這個項目,你將在執行命令後的輸出內容的最後一行看到以下信息:

web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

        接下來,經過curl命令來測試項目部署效果,此操做須要從新打開一個 shell 窗口,經過執行以下命令,來檢查部署結果(你將在執行 docker-compose up 命令的窗口看到一些訪問日誌):

$ curl http://0.0.0.0:5000
Hello World! I have been seen 1 times.
$ curl http://0.0.0.0:5000
Hello World! I have been seen 2 times.
$ curl http://0.0.0.0:5000
Hello World! I have been seen 3 times.

5.四、查看鏡像、容器詳情

        你能夠分別執行以下命令來查看此項目部署後產生了哪些鏡像,啓動了哪些容器,以及網絡、數據卷的狀況

$ docker image ls
$ docker ps
$ docker network ls
$ docker volume ls

5.五、補充

docker-compose.yaml 文件的編寫須要多練習才能熟悉,熟悉不了也不要緊,但最起碼得了解個大概,知道都能定義哪些標籤就行,遇到問題能夠快速查閱官方文檔或者我的筆記。

若是須要進一步瞭解 Docker Compose 的更多內容,建議去官方看文檔;說白了,它就是個用於配置和運行多個 Docker 容器的工具,可是若是後期業務拆分模塊較多,或者說微服務拆分較多的模塊,就須要部署更多的容器,並且還得考慮負載均衡、故障自愈、網絡通訊、數據存儲、容器管理等等問題,這時候 Docker Compose 就顯得有點力不從心了;

因此,接下來的幾個章節咱們要學習更專業的容器編排管理工具,如 Mesos(Apache下的,誕生於2013年)、kubernetes(Google家的,誕生於2014年6月)、Swarm(Docker自家的,2016年的面世),後面咱們會介紹Swarmkubernetes 這兩個工具,另一個本身去學習瞭解便可。

---

參考連接:

https://docs.docker.com/compose/

https://docs.docker.com/compose/compose-file/

https://docs.docker.com/compose/gettingstarted/

相關文章
相關標籤/搜索