1. 程式人生 > >Docker Compose 之進階篇

Docker Compose 之進階篇

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

應用多個 compose 配置檔案

docker-compose 命令預設使用的配置檔案是當前目錄中的 docker-compose.yml 檔案,當然我們可以通過 -f 選項指定一個其它名稱的配置檔案,比如:

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

更酷的是我們可以新增多個 -f 選項,docker-compose 會自動合併它們,當然也會根據先後順序把一些重複的配置項覆蓋掉。 下面我們來演示一個常見的使用場景,先建立一個名稱為 docker-compose-base.yml 的配置檔案,其內容如下:

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

然後再建立名稱為 docker-compose-dev.yml 的配置檔案:

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

下面的命令會同時應用這兩個配置檔案:

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

config 命令不會執行真正的操作,而是顯示 docker-compose 程式解析到的配置檔案內容:

很顯然,我們指定的兩個配置檔案的內容被合併了。接下來我們再來看看配置檔案覆蓋的情況。新建立一個名為 docker-compose-prod.yml 的配置檔案,編輯其內容如下:

複製程式碼

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

複製程式碼

然後執行下面的命令:

$ 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 中我們可以通過兩種方式來指定資料卷:

  • 使用命名的資料卷
  • 直接指定主機上的路徑來建立資料卷

下面的 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

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

總結

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

作者:sparkdev

出處:http://www.cnblogs.com/sparkdev/

 

鄭州婦科醫院哪家好

鄭州無痛人流醫院

鄭州看婦科哪家好

鄭州哪個婦科醫院好