5. Docker編排三劍客之Compose
Docker-Compose
一、 Docker Compose簡介
Compose為Python編寫的,後期Docker官方又用 GO語言重寫了Docker Compose,並將其作為了docker cli的子命令,稱之為Compose V2
'Docker Compose 專案是Docker官方的開源專案,負責實現對Docker容器叢集的快速編排。從功能上看,跟OpenStack中的Heat十分類似' # Compose定位是 [定義和執行多個Docker容器的應用],其前身是開源專案Fig # Compose可以實現多個容器相互配合來完成某項任務的情況,例如要實現一個Web專案,除了Web伺服器容器本身,往往還需要再加上後端的資料庫服務容器,甚至包括負載均衡容器等,它允許使用者通過一個單獨的 docker-compose.yml模板檔案來定義一組相關聯的應用容器為一個專案 'Compose中有兩個重要的概念' 1. 服務(service): 一個應用的容器,實際上可以包括若干執行相同映象的容器例項 2. 專案(project): 由一組關聯的應用容器組成的一個完整業務單元,在Docker-compose.yml檔案中定義 # Compose的預設管理物件是專案,通過子命令對專案中的一組容器進行便捷地生命週期管理
二、安裝與解除安裝
Compose可以通過python的包管理工具pip進行安裝,也可以直接下載編譯好的二進位制檔案使用,甚至能夠直接在Docker容器上執行
Docker Desktop for Mac/Windows 自帶 docker-compose 二進位制檔案,安裝Docker之後可以直接使用
1) 二進位制包
在 Linux 上的也安裝十分簡單,從 官方 GitHub Release 處直接下載編譯好的二進位制檔案即可。
[root@docker ~]# curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose # 國內使用者可以使用以下方式加快下載 [root@docker ~]# curl -L https://download.fastgit.org/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose [root@docker ~]# chmod +x /usr/local/bin/docker-compose
2) PIP安裝
x86_64架構的linux建議使用二進位制包來安裝,如果你的計算機架構是ARM,在使用PIP安裝
這種方式是將 Compose當做一個Python應用來從pip源中安裝
[root@docker ~]# pip install -U docker-compose' '可以看到類似以下輸出,說明安裝成功' Collecting docker-compose Downloading docker-compose-1.27.4.tar.gz (149kB): 149kB downloaded ... Successfully installed docker-compose cached-property requests texttable websocket-client docker-py dockerpty six enum34 backports.ssl-match-hostname ipaddress
3) bash補全命令
[root@docker ~]# curl -L https://raw.githubusercontent.com/docker/compose/1.27.4/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
4) 解除安裝
'如果是二進位制包方式安裝的,刪除二進位制檔案即可'
[root@docker ~]# rm /usr/local/bin/docker-compose
'如果是通過pip安裝的,則執行 pip uninstall即可'
[root@docker ~]# pip uninstall docker-compose
三、Compose 的使用
1) 相關術語
1. 服務(service)
一個應用容器,實際可以執行多個相同映象的例項
2. 專案(project)
由一組關聯的應用容器組成的一個完整業務單元
'由此可見,一個專案可以由多個服務(容器)關聯而成, Compose面向專案進項管理'
2) 使用場景
# 最常見的專案是web網站,該專案包含web應用和快取
四、Compose的命令說明
1) 命令物件與格式
對於Compose來說,大部分的命令的物件既可以是專案本身,也可以指定為專案中的服務或者容器。如果沒有特別的說明,命令物件將是專案,這意味著專案中所有服務都會受到命令影響
'docker-compose命令的基本使用格式是'
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS]
2) 命令選項
-f: --file FILE 指定使用Compose模板檔案,預設為docker-compose.yml,可以多次指定
-p: --project-name NAME 指定專案名稱,預設將使用所在目錄名稱作為專案名。
--verbose: 輸出更多除錯資訊
-v: --version 列印版本並退出
3) 命令使用說明
# 1. build
'格式為 docker-compose build [options] [SERVICE...].''
構建(重新構建)專案中的服務容器
服務容器一旦構建後,將會帶上一個標記名,例如對於web專案中的一個DB容器,可能是web_db。
可以隨時在專案目錄下執行 docker-compose build來重新構建服務
'選項包括如下幾種'
--force-rm 刪除構建過程中的臨時容器
--no-cache 構建映象過程中不適用cache
--pull 始終嘗試通過pull來獲取更新版本的映象
# 2. config
驗證Compose檔案格式是否正確,若正確則顯示配置,若格式錯誤顯示錯誤原因
# 3. down
此命令將會停止up命令所啟動的容器,並移除網路
# 4. exec
進入指定的容器
# 5. help
獲得一個命令的幫助
# 6. images
列出Compose檔案中包含的映象
# 7. kill
'格式為 docker-compose kill [options] [SERVICE...]'
通過傳送SIGKILL訊號來強制停止服務容器
支援通過 -s 引數來指定傳送的訊號,例如通過如下指令傳送SIGINT訊號。
docker-compose kill -s SIGINT
# 8. logs
'格式為 docker-compose logs [options] [SERVICE...]'
檢視服務容器的輸出。預設情況下,docker-compose將對不同的服務輸出使用不同的顏色來區分。可以通過 --no-color 來關閉顏色
# 9. pause
'格式為 docker-compose pause [SERVICE...]'
暫停一個服務容器
# 10. port
'格式為 docker-compose port [options] SERVICE PRIVATE_PORT'
列印某個容器埠所對映的公共埠,選項如下
--protocol=proto 指定埠協議,tcp(預設)或者udp
--index=index 如果同一服務存在多個容器,指定命令物件容器的序號(預設為1)
# 11. ps
'格式為 docker-compose ps [options] [SERVICE...]'
列出專案中目前所有的容器,引數如下
-q 只打印容器的ID資訊
# 12. pull
'格式為 docker-compose pull [options] [SERVICE...]'
拉取服務依賴的映象,選項如下
--ignore-pull-failures 忽略拉取映象過程中的錯誤
# 13. push
推送服務依賴的映象到Docker映象倉庫
# 14. restart
'格式為 docker-compose [options] [SERVICE...]'
重啟專案中的服務,選項如下
-t, --timeout TIMEOUT 指定重啟前停止伺服器的超時時間(預設為10秒)
# 15. rm
'格式為 docker-compose rm [options] [SERVICE...]'
刪除所有(停止狀態的)服務容器。推薦先執行docker-compose stop命令來停止容器,選項如下
-f, --force 強制直接刪除,包括非停止狀態的容器
-v 刪除容器所掛載的資料卷
# 16. run
'格式為 docker-compose run [options] [-p PORT...] [-e KEY=VAL... ] SERVICE [COMMADN] [ARGS...]'
在指定服務上執行一個命令,如下所示
docker-compose run ubuntu ping docker.com
# 上面的命令將會啟動一個ubuntu容器,並執行ping命令
# 17. scale
'格式為 docker-compose scale [options] [SERVICE=NUM...]'
設定指定服務執行的容器個數
通過 service=num 的引數來設定數量。例如
docker-compose scale web=3 db=2
# 執行上面的命令將啟動三個容器執行web服務,兩個容器執行db服務
一般的,當指定數目多於該服務當前實際執行容器,將新建立並啟動容器;反之,將停止容器
# 18. start
'格式為 docker-compose stop [options] [SERVICE...]'
停止已經處於執行狀態的容器,但不刪除它。通過 docker-compose start 可以再次啟動這些容器
# 19. top
檢視各個服務容器內執行的程序
# 20. unpause
'格式為 docker-compose unpause [SERVICE...]'
恢復處於暫停狀態中的服務
# 21. up
'格式為 docker-compose up [options] [SERVICE...]'
它將嘗試自動完成包括構建映象,(重新)建立服務,啟動服務,並關聯服務相關容器的一系列操作
連結的服務都將會被自動啟動,除非已經處於執行狀態。
可以說,大部分時候都可以直接通過該命令來啟動一個專案
'選項如下'
-d 在後臺執行服務容器
--no-color 不使用顏色來區分不同的服務的控制檯輸出
--no-deps 不啟動服務所連線的容器
--force-recreate 強制重新建立容器,不能與 --no-recreate 同時使用
--no-recreate 如果容器已經存在了,則不重新建立
--no-build 不自動構建缺失的服務映象
-t, --timeout TIMEOUT 停止容器時候的超時
五、Compose模板檔案
1) 模板檔案的簡介
# 預設的模板檔名稱為 docker-compose.yml,格式為yaml格式
version: "3"
services:
webapp:
image: examples/web
ports:
- "80:80"
volumes:
- "/data"
# 需要注意得是每個服務都必須通過 image 指令指定映象或者 build 指令(需要Dockerfile) 等來自動構建生成映象
# 如果使用build指令,在Dockerfile中設定的選項(例如: CMD,EXPOSE,VOLUME,ENV)等將會自動被獲取,無需再docker-compose.yaml中重複設定
2) build指令
指定Dockerfile所在資料夾的路徑(可以是絕對路徑)。Compose將會利用它自動構建這個映象,然後使用這個映象
version: '3'
services:
webapp:
build: ./dir
# 也可以使用context指令指定Dockerfile所在資料夾的路徑
# 使用Dockerfile指令 指定 Dockerfile檔名
# 使用 arg指令指定構建映象時的變數
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile111
args:
buildno: 1
# 還可以使用cache_from指定構建映象的快取
build:
context:
cache_from:
- alpine:latest
- corp/web_app:3.14
3) cap_add ,cap_drop指令
指定容器的核心能力(capacity)的分配
'例如,讓容器擁有所有的核心能力可以指定為'
cap_add:
- ALL
# 去掉NET_ADMIN能力可以指定為:
cap_drop:
- NET_ADMIN
4) command指令
覆蓋容器啟動後 預設執行的命令
command: echo "hello world"
5) cgroup_parent指令
指定父cgroup組,意味著將繼承該組的資源限制
# 例如,建立了一個cgroup組名稱為 cgroups_1
cgroup_parent: cgroups_1
6) container_name指令
指定容器名稱
# 預設會使用 專案名稱_服務名稱_序號 這樣的格式
container_name: docker-web-container
'指定容器名稱後,該服務將無法進行擴充套件(scale),因為Docker不允許多個容器具有相同的名稱'
7) devices指令
指定裝置對映關係
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
8) depends_on指令
解決容器的依賴、啟動先後的問題
# 以下例子會先啟動redis db 在啟動 web
version: '3'
service:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
'web服務不會等待 redis 完全啟動之後才啟動'
9) dns指令
自定義DNS伺服器,可以是一個值,也可以是一個列表
dns: 114.114.114.114
dns:
- 114.114.114.114
- 8.8.8.8
10) dns_search指令
配置DNS搜尋域,可以是一個值,也可以是一個列表
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
11) tmpfs指令
掛載一個tmpfs檔案系統到容器
tmpfs: /run
tmpfs:
- /run
- /tmp
12) env_file指令
在檔案中獲取環境變數,可以為單獨的檔案路徑或列表
# 如果通過 docker-compose -f FILE 方式指定compose模板檔案,則env_file中變數的路徑會基於模板檔案路徑
# 如果有變數名稱與 environment 指令衝突,則按照管理,以後者為準
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
'環境變數檔案中每一行必須符合格式,支援 # 開頭的註釋行'
# common.env: Set development environment
PROG_ENV=development
13) environment指令
設定環境變數,你可以使用陣列或字典兩種格式
# 只給定名稱的變數會自動獲取執行Compose主機上對應變數的值,可以用來防止洩露不必要的資料
environment:
RACK_ENV: devleopment
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
14) expose指令
暴露埠,但不對映到宿主主機,只被連線的服務訪問
# 只可以指定內部埠為引數
expose:
- "3000"
- "8000"
15) extra_hosts指令
類似於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
16) healthcheck指令
通過命令檢查容器是否健康執行
healthcheck:
test: ["CMD","curl","-f","http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
17) image指令
指定為映象名稱或映象ID。如果映象在本地不存在,Compose將會嘗試拉取這個映象
image: ubuntu
image: orchardup/postgresql
image: a3bc65f2
18) labels指令
為容器新增Docker原資料(metadata)資訊。例如可以為容器新增輔助說明資訊
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com.startupteam.release: "rc3 for v1.0"
19) logging指令
配置日誌選項
logging:
driver: syslog
optios:
syslog-address: "tcp://192.168.0.42:123"
# 目前支援三種日誌驅動型別
1. driver: "json-file"
2. driver: "syslog"
3. driver: "none"
# options配置日誌驅動的相關引數
options:
max-size: "200k"
max-file: "10"
20) network_mode指令
設定網路模式,使用和 docker run的--network 引數一樣的值
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
21) networks指令
配置容器連線的網路
version: "3"
services:
some-service:
networks:
- some-network
- other-network
networks:
some-network:
other-network:
22) pid指令
跟主機系統共享程序名稱空間。開啟該選項的容器之間,以及容器和宿主機系統之間可以通過程序ID來相互訪問和操作
pid: "host"
23) ports指令
暴露埠資訊
# 使用宿主埠: 容器埠(HOST:CONTAINER)格式,或者僅僅指定容器的埠(宿主將會隨機選擇埠) 都可以
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001
24) secrets指令
儲存敏感資料,例如mysql服務密碼
version: "3.1"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
secrets:
- db_root_password
- my_other_secret
secrets:
my_secret:
file: ./my_secret.txt
my_other_secret:
external: true
25) security_opt指令
指定容器模板標籤(label)機制的預設屬性(使用者、角色、型別、級別等)。例如配置標籤的使用者名稱和角色名。
security_opt:
- label:user:USER
- label:role:ROLE
26) stop_signal指令
設定另一個訊號來停止容器。在預設情況下使用的是SIGTERM停止容器
stop_signal: SIGUSR1
27) sysctls指令
配置容器核心引數
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
28) ulimits指令
指令容器的ulimits限制值
# 例如,指定最大程序數 為65535,指定檔案控制代碼數為20000(軟限制,應用可以隨時修改,不能超過硬體限制)和4000(系統硬限制,只能root使用者提高)
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
29) volumes指令
資料卷所掛載路徑設定
# 可以設定為宿主機路徑(HOST:CONTAINER)或者資料卷名稱(VOLUME:CONTAINER),並且可以設定訪問模式(HOST:CONTAINER:ro)
'該指令中路徑支援相對路徑'
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
'如果路徑為資料卷名稱,必須在檔案中配置資料卷'
version: "3"
services:
my_src:
image: mysql:5.7
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
30) 其他指令
# 1. 指定服務容器啟動後執行的入口檔案
entrypoin: /code/entrypoint.sh
# 2. 指定容器中執行應用的使用者名稱
user: nginx
# 3. 指定容器中工作目錄
working_dir: /code
# 4. 指定容器中搜索域名、主機名、mac地址等
domainname: your_website.com
hostname: test
mac_address: 12-34-56-78-90-99
# 5. 允許容器中執行一些特權命令
privileged: true
# 6. 指定容器退出後的重啟策略為始終重啟。該命令對保持服務始終執行十分有效,在生產環境中推薦配置為always或者unless-stopped,d當docker重新啟動的時候,如果設定了此選項,容器也將自動重啟,如果沒有設定此選項,容器將不會再次啟動
restart: always
# 7. 以只讀模式掛載容器的root檔案系統,意味著不能對容器內容進行修改
read_only: true
# 8. 開啟標準輸入,可以接受外部輸入
stdin_open: true
# 9. 模擬一個偽終端
tty: true
六、讀取變數
Compose模板檔案支援動態讀取主機的系統環境變數和當前目錄下的.env檔案中的變數
# 例如,下面的Compose檔案將從執行它的環境中讀取變數 ${MONGO_VERSION} 的值,並寫入執行的指令中
version: "3"
services:
db:
image: "mongo:${MONGO_VERSION}"
# 如果執行 MONGO_VERSION=3.2 docker-compose up 則會啟動一個mongo:3.2映象的容器
# 如果執行 MONGO_VERSION=2.8 docker-compose up 則會啟動一個mongo:2.8映象的容器
'若當前目錄存在.env檔案,執行 docker-compose命令時將從該檔案中讀取變數'
# 在當前目錄新建 .env 檔案並寫入以下內容
MONGO_VERSION=3.6
此時執行docker-compose up 則會啟動一個 mongo:3.6映象的容器
七、實戰WordPress
1) 建立資料卷
[root@docker ~]# docker volume create db_data
2) 檢視資料卷詳細資訊
[root@docker ~]# docker volume inspect db_data
[
{
"CreatedAt": "2021-10-28T23:15:00-04:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/db_data/_data",
"Name": "db_data",
"Options": {},
"Scope": "local"
}
]
3) 編寫Dockerfile
version: "3"
services:
db:
image: mysql:5.7
command:
- --default_authentication_plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: 123456
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: 123456
volumes:
db_data:
4) 啟動容器
[root@docker wordpress]# docker-compose up -d
'瀏覽器訪問本機的8000埠測試'