1. 程式人生 > 其它 >5. Docker編排三劍客之Compose

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埠測試'