一、 概述 compose 是用來定義和運行一個或多個容器(通常都是多個)運行和應用的工具。使用 compose 可以簡化容器鏡像的構建以及容器的運行。 compose 使用 YAML 文件來定義多容器之間的關係。一個 docker-compose up 就可以把完整的應用跑起來。 本質上,comp ...
目錄
一、 概述
compose 是用來定義和運行一個或多個容器(通常都是多個)運行和應用的工具。使用 compose 可以簡化容器鏡像的構建以及容器的運行。
compose 使用 YAML 文件來定義多容器之間的關係。一個 docker-compose up 就可以把完整的應用跑起來。 本質上,compose 把 YAML 文件解析成 docker 命令的參數,然後調用相應的 docker命令行介面,從而將應用以容器化的方式管理起來。它通過解析容器間的依賴關係順序地啟動容器。而容器間的依賴關係由 YAML 文件中的 links標記指定。
二、安裝
1)二進位包安裝(推薦)
$ curl -L https://github.com/docker/compose/releases/download/1.23.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
$ docker-compose version
2)pip 安裝(安裝的是最新穩定版本)
# 環境centos8,先安裝python3
$ yum -y install python38
$ pip3 install docker-compose
# 做軟鏈接
$ ln -s /usr/bin/docker-compose /usr/local/bin/
三、Compose命令簡介
1)常看幫助
docker-compose [COMMAND] --help 或者docker-compose help [COMMAND]
$ docker-compose --help
$ docker-compose -h
使用格式
docker-compose [-f
...] [--profile ...] [options] [--] [COMMAND] [ARGS...]
Options參數選項
-f,--file file指定模板文件,預設是docker-compose.yml模板文件,可以多次指定
--profile 啟動具有配置文件的服務
-p,--project-name name指定項目名稱,預設使用所在目錄名稱作為項目名稱
--x-networking 使用Docker的後端可插拔網路特性
--x-networking-driver driver指定網路的後端驅動,預設使用bridge
--verbose 輸入更多的調試信息
-v,--version 輸出版本信息
COMMAND參數詳解
build Build or rebuild services (構建項目中的服務容器)
bundle Generate a Docker bundle from the Compose file (從Compose文件生成分散式應用程式包)
config Validate and view the Compose file (驗證並查看Compose文件)
create Create services (為服務創建容器)
down Stop and remove containers, networks, images, and volumes (停止容器並刪除由其創建的容器,網路,捲和圖像up)
events Receive real time events from containers (為項目中的每個容器流式傳輸容器事件)
exec Execute a command in a running container (這相當於docker exec。使用此子命令,您可以在服務中運行任意命令。預設情況下,命令分配TTY,因此您可以使用命令docker-compose exec web sh來獲取互動式提示。)
help Get help on a command (獲得一個命令的幫助)
images List images ()
kill Kill containers (通過發送SIGKILL信號來強制停止服務容器)
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 (輸出版本)
2)環境變數
COMPOSE_PROJECT_NAME 設置通過 Compose 啟動的每一個容器前添加的項目名稱,預設是當前工作目錄的名字。
COMPOSE_FILE 設置要使用的 docker-compose.yml 的路徑。預設路徑是當前工作目錄。
DOCKER_HOST 設置 Docker daemon 的地址。預設使用 unix:///var/run/docker.sock,與 Docker 客戶端採用的預設值一致。
DOCKER_TLS_VERIFY 如果設置不為空,則與 Docker daemon 交互通過 TLS 進行。
DOCKER_CERT_PATH 配置 TLS 通信所需要的驗證(ca.pem、cert.pem 和 key.pem)文件的路徑,預設是 ~/.docker
四、Docker-Compose YAML語法使用說明
- version
docker-compose文件使用哪個version的file格式
目前有三個版本的 Compose 文件格式1,2.x,3.x。version版本統一用3,其實3是相容2的,version版本1 就不要考慮了已經廢棄了,一定要往前看。
version: '3'
- build
這個是創建docker鏡像時的選項,通過本地的dockerfile來創建,而不是通過image id來pull。
build:
context: ./nginx # 指定構建鏡像的路徑
dockerfile: Dockerfile # 選項是備選的dockerfile
args: # 參數設置
- buildno=1
- user=someuser
- image
生成鏡像的ID,指定為鏡像名稱或鏡像 ID。如果鏡像在本地不存在,Compose 將會嘗試拉去這個鏡像。
image: ubuntu
image: orchardup/postgresql
- links
鏈接到其它服務中的容器,使一個容器可以主動的去和另外一個容器通訊。使用服務名稱(同時作為別名)或服務名稱:服務別名 (SERVICE:ALIAS) 格式都可以。
links:
- db
- db:database
- redis
使用的別名將會自動在服務容器中的 /etc/hosts 里創建,相應的環境變數也將被創建。例如
172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis
- external_links
鏈接到 docker-compose.yml 外部的容器,甚至 並非 Compose 管理的容器。參數格式跟 links 類似。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
- expose
這個是給link用的,將一些埠暴露給link到這個container上的containers。暴露埠,但不映射到宿主機,只被連接的服務訪問
expose:
- "3000"
- "8000"
- ports
暴露埠信息,這個是將埠和本機埠映射的選項,寫法如下,其實跟docker -p一樣。使用宿主:容器 (HOST:CONTAINER)格式或者僅僅指定容器的埠(宿主將會隨機選擇埠)都可以。
ports:
- "3000"
- "3000-3005"
- "80:80"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
註:當使用 HOST:CONTAINER 格式來映射埠時,如果你使用的容器埠小於 60 你可能會得到錯誤得結果,因為 YAML 將會解析 xx:yy 這種數字格式為 60 進位。所以建議採用字元串格式。
- environment
設置環境變數。你可以使用數組或字典兩種格式。
只給定名稱的變數會自動獲取它在 Compose 主機上的值,可以用來防止泄露不必要的數據。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
- env_file
從文件中獲取環境變數,可以為單獨的文件路徑或列表。
如果通過 docker-compose -f FILE 指定了模板文件,則 env_file 中路徑會基於模板文件路徑。
如果有變數名稱與 environment 指令衝突,則以後者為準。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
- volumes
將本機的文件夾掛載到container中。
volumes:
# Just specify a path and let the Engine create a volume
- /var/lib/mysql
# Specify an absolute path mapping
- /opt/data:/var/lib/mysql
# User-relative path
- ~/configs:/etc/configs/:ro
# Named volume
- datavolume:/var/lib/mysql
捲掛載路徑設置。可以設置宿主機路徑 (HOST:CONTAINER) 或加上訪問模式 (HOST:CONTAINER:ro)
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
- volumes_from
從另一個服務或容器掛載它的所有捲。
volumes_from:
- service_name
- container_name
- extends
基於已有的服務進行擴展。例如我們已經有了一個webapp服務,模板文件為 common.yml。
# common.yml
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
編寫一個新的 development.yml 文件,使用 common.yml 中的 webapp 服務進行擴展。
# development.yml
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
後者會自動繼承 common.yml 中的 webapp 服務及相關環節變數。
- net
設置網路模式。使用和 docker client 的 –net 參數一樣的值。
net: "bridge"
net: "none"
net: "container:[name or id]"
- pid
跟主機系統共用進程命名空間。打開該選項的容器可以相互通過進程 ID 來訪問和操作。
pid: "host"
- dns
配置 DNS 伺服器。可以是一個值,也可以是一個列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
- cap_add, cap_drop
添加或放棄容器的 Linux 能力(Capabiliity)。
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
- dns_search
配置 DNS 搜索域。可以是一個值,也可以是一個列表。
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
- command
覆蓋容器啟動後預設執行的命令。
command: bundle exec thin -p 3000
- restart
定義容器重啟策略(在使用 swarm 部署時將忽略該選項, 在 swarm 使用 restart_policy 代替 restart)。重啟策略如下:
- no,預設策略,在容器退出時不重啟容器
- on-failure,在容器非正常退出時(退出狀態非0),才會重啟容器
- on-failure:3,在容器非正常退出時重啟容器,最多重啟3次
- always,在容器退出時總是重啟容器
- unless-stopped,在容器退出時總是重啟容器,但是不考慮在Docker守護進程啟動時就已經停止了的容器
tomcat:
restart: always
- 其它選項
working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_sharesv 這些都是和 docker run 支持的選項類似。
cpu_shares: 73
working_dir: /code
entrypoint: /code/entrypoint.sh
user: postgresql
hostname: foo
domainname: foo.com
mem_limit: 1000000000
privileged: true
restart: always
stdin_open: true
tty: true
五、實戰講解
1)Docker-compose搭建Redis-jenkins
$ mkdir -p /opt/docker-composer-test/jenkins_home
$ cd /opt/docker-composer-test/jenkins_home
用docker-compose安裝,當然你也可以用docker run的方式,創建一個docker-jenkins-compose.yml文件。
version: "3"
services:
jenkins:
image: jenkins/jenkins:lts
ports:
- 8080:8080
- 50000:50000
restart: "always"
container_name: jenkins
environment:
JAVA_OPTS: -Duser.timezone=Asia/Shanghai
volumes:
- /opt/docker-composer-test/jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
privileged: true
user: root
啟動Jenkins容器
$ docker-compose -f docker-jenkins-compose.yml up -d
2)Docker-compose搭建Redis Sentinel(哨兵模式)
Redis Sentinel是針對原始Master/Slave模型而衍生的高可用模型。我們為便於靈活部署,先易後難,先搭建Redis Master/Slave模型,再搭建Redis Sentinel模型。
目錄結構如下,先創建如下目錄文件。
[root@Centos8-nat-bridge-168-182-153 redis_sentinel]# tree .
.
├── redis
│?? └── docker-compose.yml
└── sentinel
├── docker-compose.yml
├── sentinel1.conf
├── sentinel2.conf
├── sentinel3.conf
└── sentinel.conf
第一步:搭建Redis Master/Slave模型
下麵的Compose文件設置了redis的 一主兩從(Master-Slave)
1、創建redis/docker-compose.yml文件。
version: '3'
services:
master:
image: redis
container_name: redis-master
command: redis-server --requirepass redis_pwd --masterauth redis_pwd
ports:
- 6379:6379
slave1:
image: redis
container_name: redis-slave-1
ports:
- 6380:6379
command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
slave2:
image: redis
container_name: redis-slave-2
ports:
- 6381:6379
command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
註意,如果設置了Redis客戶端訪問密碼requirepass, 那麼也要設置相同的副本集同步密碼masterauth。
另外我們後面使用哨兵模式能夠完成故障轉移,現有的Master可能會變成Slave,故在當前Master容器中也要攜帶masterauth參數。
2、執行 以下命令 產生3個Redis容器,分別映射到宿主機6379、6380、6381埠, 預設連接在redis-default網橋。
$ docker-compose -f redis/docker-compose.yml up -d
3、使用docker ps查看redis三個容器
$ docker ps -a
4、查看redis容器使用的網橋信息
$ docker inspect -f {{.HostConfig.NetworkMode}} 262b42fb0c9f
5、驗證
Master/Slave副本集,進入Master容器,確認兩個Slave容器已經連接。
redis/docker-compose.yml裡面的redis密碼我改成了:123456
第二步:docker-compose 部署Redis Sentinel
我們即將搭建的Sentinel容器需要能訪問到以上3個容器,故需要在形成Sentinel容器時使用外置的redis-default網橋(Redis Master/Slave docker-compose 已經創建).
1、創建sentinel/docker-compose.yml,內容如下:
version: '3'
services:
sentinel1:
image: redis
container_name: redis-sentinel-1
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel-2
ports:
- 26380:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel-3
ports:
- 26381:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
default:
external:
name: redis_default
2、創建哨兵文件sentinel/sentinel.conf,內容如下:
port 26379
dir /tmp
sentinel monitor mymaster 172.19.0.3 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
註意,以上 172.19.0.3是之前Redis Master/slave啟動之後Master節點的IP,通過docker inspect [container]獲取, 這裡我們要配合設置Master/Slave訪問密碼:123456。
查看redis-master IP地址
$ docker inspect --format='{{.NetworkSettings.Networks.redis_default.IPAddress}}' redis-master
#或者
$ docker inspect redis-master
3、將哨兵文件複製三份
$ cp sentinel/sentinel.conf sentinel/sentinel1.conf
$ cp sentinel/sentinel.conf sentinel/sentinel2.conf
$ cp sentinel/sentinel.conf sentinel/sentinel3.conf
4、執行以下命令生成3個Sentinel容器。
$ docker-compose -f sentinel/docker-compose.yml up -d
5、此時docker ps顯示如下:
$ docker ps
6、驗證
進入其中一個redis-sentinel容器,確認Master、2個Slave、另外2個Sentinel.
$ docker exec -it redis-sentinel-1 /bin/bash
$ redis-cli -p 26379
$ sentinel master mymaster
- flags: master表明master正常運作,異常情況會顯示s-down,o-down
- num-slaves:偵測到2個Slave副本集
- num-other-sentinels:除此之外,還有2個哨兵
7、Redis Sentinel高可用驗證
停止 redis-master容器,等待10s,進入任意sentinel容器,使用sentinel master mymaster命令觀察主節點發生變化,觀察外掛的Sentinel*.conf主節點IP發生變化,然後重新啟動master節點,檢查集群狀態.
$ docker stop redis-master
$ docker exec -it redis-sentinel-1 /bin/bash
$ redis-cli -p 26379
$ sentinel master mymaster
發現master節點以及s_down狀態了。
六、Docker Compose 常用命令
命令 | 說明 |
---|---|
docker-compose build | 構建項目中的鏡像,--force-rm:刪除構建過程中的臨時容器;--no-cache:不使用緩存構建;--pull:獲取最新版本的鏡像 |
docker-compose up -d | 構建鏡像、創建服務和啟動項目,-d表示後臺運行 |
docker-compose run ubuntu ls -d | 指定服務上運行一個命令,-d表示後臺運行 |
docker-compose logs | 查看服務容器輸出日誌 |
docker-compose ps | 列出項目中所有的容器 |
docker-compose pause [service_name] | 暫停一個服務容器 |
docker-compose unpause [service_name] | 恢復已暫停的一個服務容器 |
docker-compose restart | 重啟項目中的所有服務容器(也可以指定具體的服務) |
docker-compose stop | 停止運行項目中的所有服務容器(也可以指定具體的服務) |
docker-compose start | 啟動已經停止項目中的所有服務容器(也可以指定具體的服務) |
docker-compose rm | 刪除項目中的所有服務容器(也可以指定具體的服務),-f:強制刪除(包含運行的) |
docker-compose kill | 強制停止項目中的所有服務容器(也可以指定具體的服務) |