前面的幾篇筆記中,只說明瞭如何使用單個鏡像和容器。然而,在平常工做中,常常會碰到須要多個容器相互配合來完成某項任務的狀況。例如要實現一個 Web 項目,除了 Web 服務容器自己,每每還須要再加上後端的數據庫服務容器,甚至還包括負載均衡容器等。python
那容器之間是怎樣通訊的呢?多個容器之間的管理、通訊也就是所謂的容器編排。容器編排常使用的工具備docker-compose、kubernetes、swarm等。其中docker-compose是面對單機容器編排最經常使用的工具。mysql
如今介紹docker-compose文件的語法及相關配置。基本配置同docker的run命令中的參數,如CMD、EXPOSE、VOLUME、EVN等等。web
一個docker—compose包含多個服務,每一個服務都必須經過 image 指令指定鏡像或 build 指令( 須要 Dockerfile) 等來自動構建生成鏡像。redis
指定 Dockerfile 所在文件夾的路徑( 能夠是絕對路徑,或者相對 docker-compose.yml 文件的路徑) 。 Compose 將會利用它自動構建這個鏡像,而後使用這個鏡像。sql
version: '2.0' services: app: build: .
args: - version: 3.0
在構建命令中使用: wget http://www.docker.com/some_so...$version, 構建參數和 ENV 的效果同樣,都是設置環境變量。所不一樣的是,ARG 所設置的構建環境的環境變量,在未來容器運行時是不會存在這些環境變量的。可是不要所以就使用 ARG 保存密碼之類的信息,由於 docker history 仍是能夠看到全部值的。docker
version: '2.0' services: app: build: context: ./dir dockerfile: your_docker_file_name args: arg_name: arg_value
使用 cache_from 指定構建鏡像的緩存shell
build: context: ./dir cache_from: - img1:tag1 - img2:tag2
覆蓋容器啓動後默認執行的命令數據庫
command: echo "hello world"
見 swarm modejson
制定父cgroup組,意味着將繼承該組的資源限制flask
cgroup_parent: cgroups_1
制定容器名稱
指定設備映射關係,即把外設掛載在某個目錄。
devices: - "/dev/ttyUSB1:/dev/ttyUSB0"
解決容器的依賴、啓動前後的問題。如下例子中會先啓動 redis db 再啓動 web
version: '3' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
注意: web 服務不會等待 redis db 「 徹底啓動」 以後才啓動。
從文件中獲取環境變量,能夠爲單獨的文件路徑或列表。
env_file: .env env_file: - ./common.env - ./apps/web.env - /opt/secrets.env
文件中的內容爲鍵值對:key=value,每行一條。 若是有變量名稱與 environment 指令衝突,則之後者爲準。這裏所說的環境變量是對宿主機的 Compose 而言的,若是在配置文件中有 build 操做,這些變量並不會進入構建過程當中,若是要在構建中使用變量仍是首選前面剛講的 arg 標籤。
設置環境變量。你可使用數組或字典兩種格式。
environment: key: value key: value environment: - key=value - key=value
若是變量名稱或者值中用到 true|false,yes|no 等表達 布爾 含義的詞彙,最好放到引號裏,避免 YAML 自動解析某些內容爲對應的布爾語義。咱們設置的這些環境變量,能夠在後面的命令中用到,用法同shell變量,如設置了一個叫VERSION的環境變量,咱們能夠在entrypoint的命令中使用,如bash echo $VERSION$
暴露端口
expose: - 4665 - 8796
映射端口,格式 宿主端口:容器端口。
ports: - 5421:5445
咱們能夠限制容器的內存使用
mem_limit: 1G //限制容器的內存使用量最大爲1G
相似 Docker 中的 --add-host 參數,指定額外的 host 名稱映射信息。
extra_hosts: - "googledns:8.8.8.8" - "dockerhub:52.1.157.61"
會在啓動後的服務容器中 /etc/hosts 文件中添加以下兩條條目。
8.8.8.8 googledns 52.1.157.61 dockerhub
經過命令檢查容器是否健康運行
healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 1m30s timeout: 10s retries: 3
制定基礎鏡像
鏈接其餘容器,不推薦使用,但抵不住它方便啊
links: - container1:alias1 - container2:alias2
在使用Docker過程當中,咱們會有許多單獨使用docker run啓動的容器,爲了使Compose可以鏈接這些不在docker-compose.yml中定義的容器,咱們須要一個特殊的標籤,就是external_links,它可讓Compose項目裏面的容器鏈接到那些項目配置外部的容器(前提是外部容器中必須至少有一個容器是鏈接到與項目內的服務的同一個網絡裏面)。 格式以下:
external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
配置日誌選項
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:133"
目前支持的日誌類型有:
options的參數除了syslog-address,還有max-size max-file
options: max-size: "200k" max-file: "10"
設置網絡模式。使用和 docker run 的 --network 參數同樣的值。
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
配置容器鏈接的網絡。
version: "3.0" services: some-service: networks: - network1 - network2 networks: network1: network2
數據卷所掛載路徑設置。能夠設置宿主機路徑 (HOST:CONTAINER ) 或加上訪問模式(HOST:CONTAINER:ro )
volumes: - host_dir:container_dir
以後,你在volume中的讀寫操做,本質上都是在host的文件系統進行讀寫的,所以哪怕你最後把容器刪除,你也能夠在主機目錄中訪問這些數據,除非你在刪除容器的同時把volume也顯式刪除。咱們通常用於存儲須要保證安全性的數據,如數據庫的data目錄
掛載臨時目錄到容器內部,與 run 的參數同樣效果:
tmpfs: /run tmpfs: - /run - /tmp
爲了讓容器可以訪問數據而不須要永久地寫入數據,可使用 tmpfs 掛載,該掛載僅存儲在主機的內存中(若是內存不足,則爲 swap)。當容器中止時,tmpfs 掛載會被移除。若是提交容器,則不會保存 tmpfs 掛載。
labels: - key:value
爲生成的鏡像添加描述信息。可使用inspect查看。
其餘設置如omainname, entrypoint, hostname, ipc, mac_address, privileged,read_only, shm_size, restart, stdin_open, tty, user, working_dir ,基本同run命令中的格式與功能。如
restart: always
表示當遇到任意退出的時候,都會自動重啓
Dockerfile
FROM python:3.6-alpine # 複製代碼到鏡像 ADD . /code # 設置後面的命令的pwd WORKDIR /code # 安裝依賴 RUN pip install redis flask # 運行服務的命令 CMD ["python", "app.py"]
docker-compose.yml
# docker版本 version: '2.0' services: # 一個服務,名字爲web web: # 指定從Dockerfile構建,並指定上下文 build: . # 指定端口映射,host_port:container_port ports: - 5000:5000 # 等待redis服務啓動後再啓動web服務 depends_on: - redis_srv # redis服務,基於鏡像redis redis_srv: image: "redis:latest"
運行
docker-compose up --build