docker-compose用於定義和運行多個docker容器。采用YAML文件配置應用服務,可從配置文件啟動相關服務,一條命令可以啟動多個容器。
docker-compose應用
compose將所管理的容器分為三層:工程(project)、服務(service)、容器(container)。compose運行目錄下的所有文件組成一個工程,一個工程包含多個服務,每個服務中定義了容器運行的鏡像、參數、依賴,一個服務可包含多個容器實例。
應用compose一般分為3步:
-
用Dockerfile定義app環境,使app可以在任何地方reproduced。
-
用docker-compose.yml定義services,使相關services在隔離環境下一起運行。
-
docker-compose up,啟動compose和整個apps。
一個docker-compose.yml示例如下:
version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis
volumes: logvolume01: {}
compose特性:
-
單主機上隔離環境,compose工程間相互獨立。用命令行選項-p或COMPOSE_PROJECT環境變量定義工程名。
-
容器創建時保留volume上數據。
-
僅僅在容器改變時再創建容器。compose緩存了配置,restart時compose re-use存在的未改變的容器。
-
compose file支持變量,可以通過變量為不同環境定制composition。
docker-compose安裝
目前docker-compose可以安裝到macOS,Windows和64-bit Linux系統下。
linux下鏡像位於 Compose repository release page on GitHub,安裝方法如下:
sudo curl -L"https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)"-o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version docker-compose version 1.24.0, build 1110ad01
若要安裝其他版本可以修改版本號1.24.0。
或pip安裝:
pip install docker-compose
卸載compose:
sudo rm /usr/local/bin/docker-compose
或pip卸載(加入compose用pip安裝的話):
pip uninstall docker-compose
注:pip安裝時經常出錯,是因為docker-compose是用python開發的,不同版本的docker-compose對python版本有要求。可參考pypi中docker-compose需求:https://pypi.org/project/docker-compose/
Centos下直接安裝docker-compose指定版本:
wget -qO- https://get.docker.com | sh yum install -y epel-release yum install python-pip pip install --upgrade pip pip install docker-compose==1.24.1 # docker --version Docker version 19.03.8, build afacb8b # docker-compose --version docker-compose version 1.24.1, build 4667896
docker-compse命令行
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),env:COMPOSE_FILE -p, --project-name NAME Specify an alternate project name (default: directory name),env:COMPOSE_PROJECT_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 deploy keys in v3 files to their non-Swarm equivalent 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
最常用的命令是docker-compose up或docker-compose up -d(后台運行)。
docker-compose -f docker-compose.yaml up -d
docker-compose -f docker-compose.yaml up -d consul
up/run/start區別:
docker-compose up用於start或restart所有定義在docker-compose.yml內的服務。
docker-compose run用於一次性或臨時的任務,類似docker run -it(打開交互終端執行命令后退出並返回容器的退出狀態)。
docker-compose start用於restart原來創建但停止的容器,絕不會創建新容器。
logs:日志輸出信息
--no-color 單色輸出,不顯示其他顏. -f, --follow 跟蹤日志輸出,就是可以實時查看日志 -t, --timestamps 顯示時間戳 --tail 從日志的結尾顯示,--tail=200
更新容器
當服務的配置發生更改時,可使用docker-compose up命令更新配置。此時,compose會刪除舊容器並創建新容器,新容器會以不同的IP地址加入網絡,名稱保持不變,任何指向舊容器的連接都會被關閉,重新找到新容器並連接上去。
compose file
compose配置文件的格式有多個版本:1,2,2.x和3.x,不同docker版本對應不同版本compose file。Compose file是YAML文件,用於定義services、networks和volumes,默認為./docker-compose.yml。詳細語法介紹可參考:Compose file version 3 reference。
YAML(Yet Another Markup Language),是一個JSON的超集,意味着任何有效JSON文件也都是一個YAML文件。它規則如下:
1)大小寫敏感
2)使用縮進表示層級關系,但不支持tab縮進,只支持空格
3)縮進的數量不重要但至少一個空格,只要相同層級使用相同數量的空格即可
4)“#”表示注釋,從這個字符開始,直到行末,都會被解析器無視
compose的YAML只使用兩種類型:Maps和Lists,Maps的子項可以是Lists,Lists的子項也可以是Maps。
Maps:就是一個字典,即key:value的鍵值對。
image: postgres
Lists:就是一個列表。
ports: - "8000" - "8080" - "8090"
我們可以看到,可以有任何數量的項在列表中,項的定義以破折號(-)開頭,並且和父元素之間存在縮進。
版本3的compose file示例如下:
version: "3" 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:
一個標准配置文件應該包含version、services、networks、volumes四大部分,處於top層。其他包含的子項(sub-options)要相應縮進。
docker-compose.yml定義的每個服務都必須通過image指定鏡像或build指令(需要Dockerfile)來自動構建。在Dockerfile指定的選項,默認情況下會被compose自動獲取不需要在compose文件中指定。
》version:指定docker-compose.yml文件的寫法格式(版本)
》services:多個容器的集合
》image:指定服務的鏡像名稱或鏡像ID。如果鏡像在本地不存在,compose會嘗試拉取這個鏡像。
services:
web:
image: nginx
在 services 標簽下的第二級標簽是 web,這個名字是用戶自己自定義,它就是服務名稱。
》build:配置構建時,compose會利用它來自動構建鏡像,該值可以是一個路徑,也可以是一個對象,用於指定Dockfile參數。
build: ./dir --------------- build: context: ./dir dockerfile: Dockerfile args: buildno: 1
depends_on:容器依賴,解決啟動先后順序問題。
command:覆蓋容器啟動后默認執行的命令,可以是一個列表
command: bundle exec thin -p 3000 ---------------------------------- command: [“bundle”,”exec”,”thin”,”-p”,”3000”]
dns:配置 dns 服務器,可以是一個值或列表
dns: 8.8.8.8 ------------ dns: - 8.8.8.8 - 9.9.9.9
dns_search:配置 DNS 搜索域,可以是一個值或列表
dns_search: example.com ------------------------ dns_search: - dc1.example.com - dc2.example.com
environment:環境變量配置,可以用數組或字典兩種方式
environment: RACK_ENV: development SHOW: 'ture' ------------------------- environment: - RACK_ENV=development - SHOW=ture
env_file:從文件中獲取環境變量,可以指定一個文件路徑或路徑列表,其優先級低於 environment 指定的環境變量
env_file: .env --------------- env_file: - ./common.env
expose:暴露端口,只將端口暴露給連接的服務,而不暴露給主機
expose: - "3000" - "8000"
network:分為兩部分Top-level networks key和Service-level networks key。Service-level:Networks to join, referencing entries under the top-level networks key.
By default Compose sets up a single network for your app. Each container for a service joins the default network and
is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
在容器創建時會創建相應的網絡,容器創建后加入相應的網絡,即此網絡下可訪問到該容器。
Here’s an example Compose file defining two custom networks. The proxy service is isolated from the db service,
because they do not share a network in common - only app can talk to both.
version: "3" services: proxy: build: ./proxy networks: - frontend app: build: ./app networks: - frontend - backend db: image: postgres networks: - backend networks: frontend: # Use a custom driver driver: custom-driver-1 backend: # Use a custom driver which takes special options driver: custom-driver-2 driver_opts: foo: "1" bar: "2"
參考:https://docs.docker.com/compose/networking/。
network_mode:設置網絡模式
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
ports:對外暴露的端口定義,和 expose 對應,使用host:container格式或者只指定容器端口,宿主機會隨機映射端口。建議使用字符串格式,數字有時會解析錯誤。
ports: # 暴露端口信息 - "宿主機端口:容器暴露端口" - "8763:8763" - "8763:8763"
links:將指定容器連接到當前連接,可以設置別名,避免ip方式導致的容器重啟動態改變的無法連接情況
links: # 指定服務名稱:別名
- docker-compose-eureka-server:compose-eureka
volumes:卷掛載路徑,掛載一個目錄或一個已經存在的數據卷容器,可以直接使用host:container格式,或者host:container:ro,后者對於容器來說,數據卷是只讀的,可有效保護宿主機的文件系統。compose可以使用相對路徑。
volumes: // 只是指定一個路徑,Docker 會自動在創建一個數據卷(這個路徑是容器內部的)。 - /var/lib/mysql // 使用絕對路徑掛載數據卷 - /opt/data:/var/lib/mysql // 以 Compose 配置文件為中心的相對路徑作為數據卷掛載到容器。 - ./cache:/tmp/cache // 使用用戶的相對路徑(~/ 表示的目錄是 /home/<用戶目錄>/ 或者 /root/)。 - ~/configs:/etc/configs/:ro // 已經存在的命名的數據卷。 - datavolume:/var/lib/mysql
You can mount a host path as part of a definition for a single service, and there is no need to define it in the top level volumes key.
單個容器使用沒必要定義頂層volume。
But, if you want to reuse a volume across multiple services, then define a named volume in the top-level volumes key.
多個服務要共用volume時需要定義頂層volumes。
Note: The top-level volumes key defines a named volume and references it from each service’s volumes list.
docker-compose指定網段
當通過docker network創建新的自定義網絡時,或者通過在docker-compose.yaml的網絡部分中定義網段IP時,即使指定/etc/docker/daemon.json的bip,默認網段仍是172,易於和局域網沖突。
使用docker-compose.yml 部署應用,docker 默認的網絡模式是bridge ,默認網段是172.17.0.1/16 ,多次執行docker-compose up -d 部署服務后,自動生成的網橋會依次使用: 172.18.x.x ,172.19.x.x ,直到增加到 172.22.x.x。
可通過如下兩種方法指定網段:
1. 在docker-compose.yml配置文件中明確的指定subnet和gateway
version: '2.3' networks: cow-cow5: driver: bridge ipam: driver: default config: - subnet: 10.88.12.0/24 gateway: 10.88.12.1 services: cowrie: ...... networks: - cow-cow
使用上面這個配置之后,當docker-compose up的時候,會創建名為filename-cow-cow5的網橋,並且這個filename-cow-cow5網橋的子網和網段是我們設置的這個 10.88.12.*。
2. docker版本大於18.09.1時指定在daemon.json中指定
{ "debug" : true, "default-address-pools" : [ { "base" : "12.11.0.0/16", "size" : 24 } ] }
參考:
