Docker Compose 之進階篇

前文《Docker Compose 簡介》和《Dcoker Compose 原理》兩篇文章中分別介紹了 docker compose 的基本概念以及實現原理。本文咱們將繼續探索 docker compose,並經過 demo 介紹一些主要的用法。 
說明:本文的演示環境爲 ubuntu 16.04。html

應用多個 compose 配置文件

docker-compose 命令默認使用的配置文件是當前目錄中的 docker-compose.yml 文件,固然咱們能夠經過 -f 選項指定一個其它名稱的配置文件,好比:nginx

$ docker-compose -f docker-compose-dev.yml up

更酷的是咱們能夠添加多個 -f 選項,docker-compose 會自動合併它們,固然也會根據前後順序把一些重複的配置項覆蓋掉。 下面咱們來演示一個常見的使用場景,先建立一個名稱爲 docker-compose-base.yml 的配置文件,其內容以下:web

version: '3'
services:
  web:
    build: .
  redis:
    image: "redis:latest"

而後再建立名稱爲 docker-compose-dev.yml 的配置文件:redis

version: '3'
services:
  web:
    ports:
     - "5000:5000"

下面的命令會同時應用這兩個配置文件:docker

$ docker-compose -f docker-compose-base.yml -f docker-compose-dev.yml config

config 命令不會執行真正的操做,而是顯示 docker-compose 程序解析到的配置文件內容:數據庫

很顯然,咱們指定的兩個配置文件的內容被合併了。接下來咱們再來看看配置文件覆蓋的狀況。新建立一個名爲 docker-compose-prod.yml 的配置文件,編輯其內容以下:json

複製代碼

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

複製代碼

而後執行下面的命令:ubuntu

$ docker-compose -f docker-compose-base.yml -f docker-compose-prod.yml config

此次 docker-compose-prod.yml 文件中的 image 設置覆蓋了 docker-compose-base.yml 文件中的設置,而且映射的端口也改爲了 80:5000。
就像 demo 中演示的那樣,咱們能夠經過屢次指定 -f 選項的方式配置不一樣的環境,而且共用一份基礎的配置文件。後端

其實 docker-compse 還默認還支持一種合併、覆蓋配置文件的寫法,就是使用約定的文件名稱 docker-compose.yml 和 docker-compose.override.yml。下面咱們把 docker-compose-base.yml 文件更名爲 docker-compose.yml,把 docker-compose-prod.yml 文件更名爲 docker-compose.override.yml,並直接執行不帶 -f 選項的命令:安全

$ docker-compose config

結果和前面是同樣的,docker-compose 自動合併了配置文件 docker-compose.yml 和 docker-compose.override.yml。這種方式雖然省去了指定 -f 選項的麻煩但其缺點也是很明顯的,就是沒法指定更多不一樣的應用場景。

使用 network

Docker 提供的 network 功能可以對容器進行網絡上的隔離,下面的 demo 中咱們建立三個 service 和兩個虛擬網絡(注意,該 demo 主要是演示 network 的用法,因此筆者並無配置 proxy service 中的 nginx):

複製代碼

version: '3'
services:
  proxy:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frantnet
  webapp:
    build: .
    networks:
      - frantnet
      - endnet
  redis:
    image: redis
    networks:
      - endnet
networks:
  frantnet:
  endnet:

複製代碼

其中的 proxy 和 webapp 鏈接到網絡 frantnet 上,webapp 和 redis 鏈接在了 endnet 上(請使用《Docker Compose 簡介》一文中介紹的 web 應用和 Dockerfile 來建立 webapp service)。請使用下面的命令來啓動應用:

$ docker-compose -p testnet -f docker-compose-net.yml up -d

從上圖咱們能夠看到該命令一共建立了兩個 network 和 三個容器。而後咱們檢查一下這三個容器的網絡鏈接狀態。先從 testnet_webapp_1 中 ping 另外的兩個容器:

由於 webapp 服務同時鏈接到了 frantnet 和 endnet 兩個網絡中,因此它能夠同時鏈接這兩個網絡中的其它容器(proxy 和 redis)。接下來再看看容器 proxy 和 redis 是否能夠直接連通,咱們從容器 testnet_redis_1 中 ping proxy(注意,執行這個操做前須要在容器  testnet_redis_1 中經過 apt-get update && apt-get install iputils-ping 命令安裝 ping 命令):

沒法從容器 testnet_redis_1 中 ping 通 proxy 容器,這也就說明咱們經過不一樣的虛擬網絡實現了容器網絡之間的隔離,從而在最大程度上去保護後端網絡的安全。

按順序啓動容器

默認狀況下 compose 啓動容器的順序是不肯定的,可是有些場景下咱們但願可以控制容器的啓動順序,好比應該讓運行數據庫的程序先啓動。咱們能夠經過 depends_on 來解決有依賴關係的容器的啓動順序問題,看下面的 demo:

複製代碼

version: '3'
services:
  proxy:
    image: nginx
    ports:
      - "80:80"
    depends_on:
      - webapp
      - redis
  webapp:
    build: .
    depends_on:
      - redis
  redis:
    image: redis

複製代碼

啓動應用:

不管咱們執行多少次這樣的啓動操做,這三個容器的啓動順序都是不變的。若是不該用 depends_on,每次執行 up 命令容器的啓動順序可能都是不同的。
須要注意的是 depends_on 只是解決了控制容器啓動順序的問題,若是一個容器的啓動時間很是長,後面的容器並不會等待它完成啓動。若是要解決這類問題(等待容器完成啓動並開始提供服務),須要使用 wait-for-it 等工具。

配置數據卷(volume)

數據卷是處理容器中的持久化數據的主要方式,在 compose 中咱們能夠經過兩種方式來指定數據卷:

  • 使用命名的數據卷
  • 直接指定主機上的路徑來建立數據卷
  • 給你們推薦一個架構羣:698581634 進羣便可免費獲取資料。

下面的 demo 演示了這兩種數據卷的配置方式:

複製代碼

version: "3.2"
services:
  web:
    image: nginx:alpine
    volumes:
      - type: volume
        source: mydata
        target: /data
      - type: bind
        source: ./nginx/logs
        target: /var/log/nginx
  jenkins:
    image: jenkins/jenkins:lts
    volumes:
      - jenkins_home:/var/jenkins_home
      - mydata:/data
volumes:
  mydata:
  jenkins_home:

複製代碼

在這個例子中咱們一共建立了三個數據卷,分別是兩個命名的數據卷 jenkins_home 和 mydata:

其中的 jenkins_home 數據卷是給 jenkins 保存數據的。若是要在多個容器之間共享數據卷,就必須在頂級的 volumes 節點中定義這個數據卷,好比 mydata 數據卷,它被 web 和 jenkins service 共享了。好比咱們在 web service 中的 mydata 數據卷中建立一個名爲 hello 的文件,該文件會同時出如今 jenkins service 中:

咱們還建立了一個 bind 類型的 volume 在當前目錄下的 nginx/logs 目錄下保存 nginx 的日誌:

配置日誌驅動

咱們還能夠經過 logging 節點爲 service 指定日誌驅動及其相關的選項:

複製代碼

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"
  redis:
    image: "redis:latest"

複製代碼

上面的代碼指定日誌驅動爲 json-file,存儲日誌的最大文件 size 爲 200k,最多存儲 10 這樣大的文件。

在 compose file 文件中應用模板

從版本 3.4 開始,能夠在 compose file 文件中使用 extension fields,其實咱們能夠簡單的把它理解爲能夠重用的代碼模板。模板的定義必須以 x- 開頭,而後以 & 開頭的字符串爲模板命名,以後就能夠以 * 加上模板的名稱引用模板:

複製代碼

version: '3.4'
x-logging:
  &default-logging
  driver: json-file
  options:
    max-size: "200k"
    max-file: "10"

services:
  web:
    build: .
    ports:
     - "5000:5000"
    logging: *default-logging
  redis:
    image: "redis:latest"
    logging: *default-logging

複製代碼

運行下面的命令看看模板替換的狀況:

$ docker-compose -p template -f docker-compose-template.yml config

上圖顯示全部對模板的引用都被替換成了模板的內容。

原文連接:https://www.cnblogs.com/sparkdev/p/9803554.html

總結

Docker compose 是一件強有力的效率工具,本文只是介紹了一些常見的用法。若是你還想掌握更多內容,請參考 compose file 的官方文檔。

參考:
Compose file version 3 reference
Docker Compose from development to production
Networking in Compose
Control startup order in Compose
3 Docker Compose features for improving team development workflow

相關文章
相關標籤/搜索