Docker Compose
前言
Docker系列文章:
此篇是Docker系列的第十一篇,大家一定要按照我做的Demo都手敲一遍,印象會更加深刻的,馬上就開始Kubernetes,加油!一起前行!
-
為什麼要學習Docker -
Docker基本概念 -
Docker鏡像基本原理 -
Docker容器數據卷 -
Dockerfile -
Docker單機網絡上 -
Docker單機網絡下 -
Docker單機網絡實戰 -
Docker隔離技術 -
Docker限制
為什麼需要Docker Compose
Docker幫助我們解決服務的打包安裝的問題,隨着而來的問題就是服務過多的帶來如下問題,
-
多次使用Dockerfile Build Image或者DockerHub拉取Image; -
需要創建多個Container,多次編寫啟動命令; -
Container互相依賴的如何進行管理和編排;
當我們服務數量增多的時候,上面三個問題就會更加的被放大,如果這三個問題不解決,其實從虛擬機到容器化除了機器減少一些浪費以外,好像沒有更多的變化。Docker有沒有什麼好的方法,可以讓我們通過一個配置就搞定容器編排和運行呢?這個時候Docker Compose就站出來了。
Docker Compose可以做到以下幾點:
-
提供工具用於定義和運行多個docker容器應用; -
使用yaml文件來配置應用服務(docker-compse.yml); -
可以通過一個簡單的命令docker-compse up可以按照依賴關係啟動所有服務; -
可以通過一個簡單的命令docker-compose down停止所有服務; -
當一個服務需要的時候,可以很簡單地通過–scale進行擴容;
Docker Compose有以下特徵:
-
更高的可移植性,Docker Compose僅需一個docker-compse up可以完成按照依賴關係啟動所有服務,然後使用docker-compose down輕鬆將其拆解。幫助我們更輕鬆地部署複雜的應用程序; -
單個主機上的多個隔離環境,Compose可以使用項目名稱將環境彼此隔離,這帶可以在一台計算機上運行同一環境的多個副本,它可以防止不同的項目和服務相互干擾;
Docker Compose介紹
-
Docker Compose是一個工具,用於定義和運行多容器應用程序的工具;
-
Docker Compose通過yml文件定義多容器的docker應用;
-
Docker Compose通過一條命令根據yml文件的定義去創建或管理多容器;
image.png
Docker Compose 是用來做Docker 的多容器控制,是一個用來把 Docker 自動化的東西。有了 Docker Compose 你可以把所有繁複的 Docker 操作全都一條命令,自動化的完成。
Docker Compose安裝
Docker Compose安裝的最新的版本1.29.2,對於Mac和Windows安裝好Docker以後,就已經安裝好Docker Compose,不需要手動安裝,這裡的安裝方式是基於Linux的Cnetos的,大家也可以參考官方網站去安裝,
具體步驟如下:
-
下載 Docker Compose 二進制文件,版本1.29.2是目前最新最穩定的版本,要下載舊版本的大家可以更改版本號,可以參考github的版本號進行選擇;
sudo curl -L "//github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
-
對二進制文件應用可執行權限;
sudo chmod +x /usr/local/bin/docker-compose
-
安裝以後通過docker-compose –version命令檢查是否安裝成功;
image.png
Docker Compose版本介紹
Docker Compose版本與引擎的對應關係如下,可以看到中間主要有兩個版本2和版本3兩種格式,目前大家使用比較多也就是這兩種,對於這兩個版本的差別給大家介紹一下:
-
v3 版本不支持 volume_from 、extends、group_add等屬性; -
cpu 和 內存屬性的設置移到了 deploy 中; -
v3 版本支持 Docker Swarm,而 v2 版本不支持;
注意:官方目前在 1.20.0 引入了一個新–compatibility標誌,幫助開發人員輕鬆的過渡到v3,目前還有些問題官方還不建議直接使用到生產,建議大家直接上手v3版本。

Docker Compose基本命令介紹
Docker Compose命令基本上和Docker相差不多,主要就是對Docker Compose生命周期控制、日誌格式等相關命令,可以通過docker-compose –help進行幫助。
#構建建啟動nignx容器
docker-compose up -d nginx
#進入nginx容器中
docker-compose exec nginx bash
#將會停止UP命令啟動的容器,並刪除容器
docker-compose down
#顯示所有容器
docker-compose ps
#重新啟動nginx容器
docker-compose restart nginx
#構建鏡像
docker-compose build nginx
#不帶緩存的構建
docker-compose build --no-cache nginx
#查看nginx的日誌
docker-compose logs nginx
#查看nginx的實時日誌
docker-compose logs -f nginx
#驗證(docker-compose.yml)文件配置,
#當配置正確時,不輸出任何內容,當文件配置錯誤,輸出錯誤信息
docker-compose config -q
#以json的形式輸出nginx的docker日誌
docker-compose events --json nginx
#暫停nignx容器
docker-compose pause nginx
#恢復ningx容器
docker-compose unpause nginx
#刪除容器
docker-compose rm nginx
#停止nignx容器
docker-compose stop nginx
#啟動nignx容器
docker-compose start nginx
Docker Compose實戰
我們構建一個如下的應用,通過Nginx轉發給後端的兩個Java應用;

-
新建Spring Boot應用,增加一個HelloController,編寫一個hello方法,返回請求的端口和IP;
/**
* hello
*
* @author wangtongzhou
* @since 2021-07-25 09:43
*/
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(HttpServletRequest req) throws UnknownHostException {
return "hello";
}
}
-
指定Spring Boot的啟動入口;
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定該Main Class為全局的唯一入口 -->
<mainClass>cn.wheel.getway.WheelGetWay</mainClass>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依賴的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
打包Spring Boot應用;
mvn package
-
上傳文件到Linux服務器/usr/local/docker-compose-demo的目錄; -
在/usr/local/docker-compose-demo的目錄編輯Dockerfile;
#指定基礎鏡像
FROM java:8
LABEL name="docker-compose-demo" version="1.0" author="wtz"
COPY ./getway-1.0-SNAPSHOT.jar ./docker-compose-demo.jar
#啟動參數
CMD ["java","-jar","docker-compose-demo.jar"]
-
編輯docker-compose.yml文件;
version: '3.0'
networks:
docker-compose-demo-net:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
services:
docker-compose-demo01:
build:
#構建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
image: docker-compose-demo
container_name: docker-compose-demo01
#選擇網絡
networks:
- docker-compose-demo-net
#選擇端口
ports:
- 8081:8080/tcp
restart: always
docker-compose-demo02:
build:
#構建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
image: docker-compose-demo
container_name: docker-compose-demo02
#選擇網絡
networks:
- docker-compose-demo-net
#選擇端口
ports:
- 8082:8080/tcp
restart: always
nginx:
image: nginx:latest
container_name: nginx-demo
networks:
- docker-compose-demo-net
ports:
- 80:80/tcp
restart: always
volumes:
- /usr/local/docker-compose-demo/nginx.conf:/etc/nginx/nginx.conf:rw
volumes:
docker-compose-demo-volume: {}
-
編寫nginx.conf,實現負載均衡到每個應用,這裡通過容器名稱訪問,因此不需要管每個容器的ip是多少,這個也是自定義網絡的好處;
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
proxy_pass //docker-compose-demo;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
upstream docker-compose-demo{
server docker-compose-demo01:8080;
server docker-compose-demo02:8080;
}
include /etc/nginx/conf.d/*.conf;
}
-
查看/usr/local/docker-compose-demo目錄,有以下確保有以下四個文件;

image.png
-
檢查docker-compose.yml的語法是否正確,如果不發生報錯,說明語法沒有發生錯誤;
docker-compose config
-
啟動docker-compose.yml定義的服務;
docker-compose up

image.png
-
驗證服務是否正確;
#查看宿主機ip
ip add
#訪問對應的服務
curl //172.21.122.231/hello

img

image.png
Docker Compose Yml文件介紹
版本
對於版本沒什麼介紹的,就是指定使用的版本;
Services
每個Service代表一個Container,與Docker一樣,Container可以是從DockerHub中拉取到的鏡像,也可以是本地Dockerfile Build的鏡像。
image
標明image的ID,這個image ID可以是本地也可以是遠程的,如果本地不存在,Docker Compose會嘗試pull下來;
image: ubuntu
build
該參數指定Dockerfile文件的路徑,Docker Compose會通過Dockerfile構建並生成鏡像,然後使用該鏡像;
build:
#構建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
ports
暴露端口,指定宿主機到容器的端口映射,或者只指定容器的端口,則表示映射到主機上的隨機端口,一般採用主機:容器的形式來映射端口;
#暴露端口
ports:
- 8081:8080/tcp
expose
暴露端口,但不需要建立與宿主機的映射,只是會向鏈接的服務提供;
environment
加入環境變量,可以使用數組或者字典,只有一個key的環境變量可以在運行compose的機器上找到對應的值;
env_file
從一個文件中引入環境變量,該文件可以是一個單獨的值或者一個列表,如果同時定義了environment,則environment中的環境變量會重寫這些值;
depends_on
定義當前服務啟動時,依賴的服務,當前服務會在依賴的服務啟動後啟動;
depends_on:
- docker-compose-demo02
- docker-compose-demo01
deploy
該配置項在version 3里才引入,用於指定服務部署和運行時相關的參數;
replicas
指定副本數;
version: '3.4'
services:
worker:
image: nginx:latest
deploy:
replicas: 6
restart_policy
指定重啟策略;
version: "3.4"
services:
redis:
image: redis:latest
deploy:
restart_policy:
condition: on-failure #重啟條件:on-failure, none, any
delay: 5s # 等待多長時間嘗試重啟
max_attempts: 3 #嘗試的次數
window: 120s # 在決定重啟是否成功之前等待多長時間
update_config
定義更新服務的方式,常用於滾動更新;
version: '3.4'
services:
vote:
image: docker-compose-demo
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2 # 一次更新2個容器
delay: 10s # 開始下一組更新之前,等待的時間
failure_action:pause # 如果更新失敗,執行的動作:continue, rollback, pause,默認為pause
max_failure_ratio: 20 # 在更新過程中容忍的失敗率
order: stop-first # 更新時的操作順序,停止優先(stop-first,先停止舊容器,再啟動新容器)還是開始優先(start-first,先啟動新容器,再停止舊容器),默認為停止優先,從version 3.4才引入該配置項
resources
限制服務資源;
version: '3.4'
services:
redis:
image: redis:alpine
deploy:
resources:
#限制CPU的使用率為50%內存50M
limits:
cpus: '0.50'
memory: 50M
#始終保持25%的使用率內存20M
reservations:
cpus: '0.25'
memory: 20M
healthcheck
執行健康檢查;
healthcheck:
test: ["CMD", "curl", "-f", "//localhost"] # 用於健康檢查的指令
interval: 1m30s # 間隔時間
timeout: 10s # 超時時間
retries: 3 # 重試次數
start_period: 40s # 啟動多久後開始檢查
restart
重啟策略;
#默認的重啟策略,在任何情況下都不會重啟容器
restart: "no"
#容器總是重新啟動
restart: always
#退出代碼指示失敗錯誤,則該策略會重新啟動容器
restart: on-failure
#重新啟動容器,除非容器停止
restart: unless-stopped
networks
網絡類型,可指定容器運行的網絡類型;
#指定對應的網絡
networks:
- docker-compose-demo-net
networks:
docker-compose-demo-net:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
ipv4_address, ipv6_address
加入網絡時,為此服務指定容器的靜態 IP 地址;
version: "3.9"
services:
app:
image: nginx:alpine
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
- subnet: "2001:3984:3989::/64"
Networks
網絡決定了服務之間以及服務和外界之間如何去通信,在執行docker-compose up的時候,docker會默認創建一個默認網絡,創建的服務也會默認的使用這個默認網絡。服務和服務之間,可以使用服務的名字進行通信,也可以自己創建網絡,並將服務加入到這個網絡之中,這樣服務之間可以相互通信,而外界不能夠與這個網絡中的服務通信,可以保持隔離性。
Volumes
掛載主機路徑或命名卷,指定為服務的子選項。可以將主機路徑掛載為單個服務定義的一部分,無需在頂級volume中定義。如果想在多個服務中重用一個卷,則在頂級volumes key 中定義一個命名卷,將命名卷與服務一起使用。
結束
歡迎大家點點關注,點點贊!
