Docker Compose 容器編排的實(shí)現(xiàn)

一、Docker Compose 概述
Compose 是Docker公司推出的一個(gè)軟件,可以管理多個(gè)Docker容器組成一個(gè)應(yīng)用。我們只需要定義一個(gè)YAML格式的配置文件 docker-compose.yaml 配置好多個(gè)容器之間的調(diào)用關(guān)系,最后只需要一個(gè)命令,就可以同時(shí)控制這些容器進(jìn)行啟動(dòng) / 關(guān)閉。Compose 允許用戶通過一個(gè)單獨(dú)的 docker-compose.yaml 模板文件定義一組容器為一個(gè)項(xiàng)目。
舉個(gè)例子:
假設(shè)我們一個(gè)項(xiàng)目中使用到了Redis、Mysql、nginx等等很多組件技術(shù),那么對應(yīng)的Docker容器的實(shí)例也會(huì)變得非常雜亂。如果其中有一個(gè)訂單的微服務(wù)需要運(yùn)行,那么就需要前面Redis、Mysql....所有容器都必須啟動(dòng)之后,訂單服務(wù)才可以正常運(yùn)行。 至此,就面臨到了兩個(gè)問題:
① 容器實(shí)例非常繁多,復(fù)雜② 容器的啟停以及他們之間的啟動(dòng)順序需要合理的管理
這時(shí),我們就需要一個(gè)介質(zhì)去管理容器實(shí)例之間的協(xié)作方式,Docker Compose就為我們合理的解決掉了所面臨的問題。當(dāng)我們要進(jìn)行啟動(dòng)容器時(shí),只需要執(zhí)行一條命令,就可以啟動(dòng)全部實(shí)例,不需要每個(gè)容器都再去一遍一遍 的docker run.....
PS:最新版本的Docker本身已經(jīng)自帶了Compose 這個(gè)工具,直接使用即可。

二、使用 Docker Compose
Docker Compose使用的步驟如下:
① 編寫Dockerfile定義各個(gè)微服務(wù)應(yīng)用并構(gòu)建出對應(yīng)的鏡像文件
② 使用docker-compose.yaml 定義一個(gè)完整的業(yè)務(wù)單元,安排好整體應(yīng)用中的各個(gè)容器服務(wù)
③ 執(zhí)行docker-compose up命令來啟動(dòng)并運(yùn)行整個(gè)程序,完成一鍵部署

三、常用命令
創(chuàng)建并啟動(dòng)docker-compose服務(wù)
docker-compose up # 后臺運(yùn)行 docker-compose up -d
停止并刪除容器、網(wǎng)絡(luò)、卷、鏡像
docker-compose down
進(jìn)入容器實(shí)例內(nèi)部
docker-compose exec <yml里面的服務(wù)id> /bin/bash
展示當(dāng)前docker-compose編排過的運(yùn)行的所有容器
docker-compose ps
展示當(dāng)前docker-compose編排過的容器進(jìn)程
docker-compose top
查看容器輸出日志
docker-compose log <yml里面的服務(wù)id>
檢查配置
docker-compose config # 有問題才輸出 docker-compose config -q
重啟服務(wù)
docker-compose restart
啟動(dòng)服務(wù):(類似 docker start)
docker-compose start
停止服務(wù)
docker-compose stop
四、編排微服務(wù)
接下來通過一個(gè)案例學(xué)習(xí)使用Compose編排微服務(wù),具體操作如下:
Ⅰ、搭建微服務(wù)
① 創(chuàng)建測試數(shù)據(jù)庫表:t_user
CREATE TABLE `t_user` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用戶名', `password` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '密碼', `sex` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '性別 0=女 1=男 ', `deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '刪除標(biāo)志,默認(rèn)0不刪除,1刪除', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶表'
② 搭建SpringBoot測試工程

編寫配置文件
server.port=6001 # ========================alibaba.druid相關(guān)配置===================== spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://47.109.24.39:3306/docker_boot?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.druid.test-while-idle=false # ========================redis相關(guān)配置===================== spring.redis.database=0 spring.redis.host=47.109.24.39 spring.redis.port=6379 spring.redis.password= spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 # ========================mybatis相關(guān)配置=================== mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.zhao.docker.entities # ========================swagger===================== spring.swagger2.enabled=true
搭建好服務(wù)后,我們編寫兩個(gè)測試Controller(這里主要介紹Compose 相關(guān)使用,具體Java代碼不過多糾結(jié)):
@Api(description = "用戶User接口")
@RestController
@Slf4j
public class UserController {
@Resource
private UserService userService;
@ApiOperation("新增用戶 新增3條")
@RequestMapping(value = "/user/add",method = RequestMethod.POST)
public void addUser(){
for (int i = 0; i <=3 ; i++) {
User user = new User();
user.setDeleted((byte)0);
user.setUpdateTime(new Date());
user.setCreateTime(new Date());
user.setUsername("zp"+i);
user.setPassword(IdUtil.simpleUUID().substring(0,6));
user.setSex((byte) new Random().nextInt(2));
userService.addUser(user);
}
}
@ApiOperation("查詢用戶")
@RequestMapping(value = "/user/find/{id}",method = RequestMethod.GET)
public User findUser(@PathVariable Integer id){
return userService.findUserById(id);
}
}③ 使用maven將編好的SpringBoot工程進(jìn)行打包,放至linux服務(wù)器中

Ⅱ、編寫Dockerfile構(gòu)建鏡像
編寫Dockerfile將SpringBoot工程構(gòu)建為鏡像,命令如下:
# 基礎(chǔ)鏡像 java FROM java:8 # 作者 xiaozhao MAINTAINER xiaozhao # 指定臨時(shí)文件位 /temp VOLUME /temp # 將jar包添加到容器 更名為zp_docker ADD docker_boot-0.0.1-SNAPSHOT.jar zp_docker.jar # 運(yùn)行 jar RUN bash -c 'touch /zp_docker.jar' ENTRYPOINT ["java","-jar","/zp_docker.jar"] # 暴露6001端口 EXPOSE 6001
將編寫好的Dockerfile文件放至SpringBoot工程同一目錄下

執(zhí)行命令構(gòu)建鏡像


Ⅲ、啟動(dòng)容器,測試服務(wù)
啟動(dòng)容器,使用Swagger進(jìn)行測試

訪問Swagger成功,搭建微服務(wù)完成。

Ⅳ、使用Compose編排容器
① 在Dockerfile同級目錄下編寫docker-compose.yml文件
# 版本
version: "3"
#服務(wù)容器實(shí)例
services:
# 服務(wù)名
microService:
# 鏡像名 + 版本號
image: zp_docker:1.0
# 容器名稱
container_name: my01
# 端口配置
ports:
- "6001:6001"
# 容器數(shù)據(jù)卷
volumes:
- /app/microService:/data
# 網(wǎng)絡(luò)(一下容器運(yùn)行在同一個(gè)網(wǎng)段內(nèi))
networks:
- xiaozhao_net
# 依賴的容器,服務(wù)的啟動(dòng)依賴
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- xiaozhao_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'docker_boot'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- xiaozhao_net
command: --default-authentication-plugin=mysql_native_password #解決外部無法訪問
networks:
xiaozhao_net : 
② 修改微服務(wù)中的配置,將mysql和redis的IP地址換為docker-compose.yml文件中的服務(wù)名。避免宕機(jī)重啟IP變更引發(fā)問題。
server.port=6001 # ========================alibaba.druid相關(guān)配置===================== spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver #spring.datasource.url=jdbc:mysql://47.109.24.39:3306/docker_boot?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.url=jdbc:mysql://mysql:3306/docker_boot?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.druid.test-while-idle=false # ========================redis相關(guān)配置===================== spring.redis.database=0 #spring.redis.host=47.109.24.39 spring.redis.host=redis spring.redis.port=6379 spring.redis.password= spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 # ========================mybatis相關(guān)配置=================== mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.zhao.docker.entities # ========================swagger===================== spring.swagger2.enabled=true
③ 重新將微服務(wù)打包放至linux服務(wù)器中

④ 重新構(gòu)建鏡像

⑤ 執(zhí)行命令,檢查docker-compose.yml配置
docker-compose config -q

沒有出現(xiàn)報(bào)錯(cuò),配置正常。
⑥ 執(zhí)行啟動(dòng)命令,一鍵啟動(dòng)所有容器
# 后臺啟動(dòng)所有容器 docker-compose up -d

當(dāng)在docker-compose.yml文件中不設(shè)置容器名稱時(shí),默認(rèn)為:當(dāng)前文件所處的目錄名稱_鏡像名_容器數(shù)量
⑦ 查看容器啟動(dòng)情況,可以看到所有容器啟動(dòng)成功

⑧ 使用Swagger測試服務(wù)
測試添加用戶功能


測試查詢功能

測試成功,功能接口正常,Mysql,redis服務(wù)正常??!
五、總結(jié)
在以上的測試項(xiàng)目中,我們用到了redis、Mysql組件,再加上搭建的SpringBoot工程鏡像,一共三個(gè)對應(yīng)容器。當(dāng)我們不使用Compose 去編排服務(wù)時(shí),我們總會(huì)遇到如下的問題:
- 啟動(dòng)容器的先后順序要求固定,必須先啟動(dòng)Mysql、Redis才能微服務(wù)訪問成功。
- 每次啟動(dòng)都要執(zhí)行多個(gè)run命令。
- 容器間的啟?;蝈礄C(jī),有可能導(dǎo)致IP地址對應(yīng)的容器實(shí)例變化,映射出錯(cuò)。
在有了Compose 后容器間的管理就非常絲滑了,到此這篇關(guān)于Docker Compose 容器編排的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Docker Compose 容器編排內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Docker 默認(rèn)bridge網(wǎng)絡(luò)中配置DNS的方法
這篇文章主要介紹了Docker 默認(rèn)bridge網(wǎng)絡(luò)中配置DNS的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03
使用docker搭建嵌入式Linux開發(fā)環(huán)境
本文主要介紹了使用docker搭建嵌入式Linux開發(fā)環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-08-08
docker images本地遷移的實(shí)現(xiàn)
這篇文章主要介紹了docker images本地遷移的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
docker容器無法訪問外網(wǎng),但宿主機(jī)卻可以訪問的解決方案
本文詳細(xì)介紹了Docker容器無法訪問外網(wǎng)的常見原因及其解決方法,包括檢查Docker服務(wù)狀態(tài)、網(wǎng)絡(luò)設(shè)置、宿主機(jī)網(wǎng)絡(luò)連接、防火墻設(shè)置、重建docker0網(wǎng)絡(luò)、開啟IP轉(zhuǎn)發(fā)功能、修改DNS設(shè)置以及使用--net=host模式等2024-11-11
docker從安裝入門到應(yīng)用部署及私有倉庫搭建基礎(chǔ)命令
這篇文章主要為大家介紹了docker從安裝入門到應(yīng)用部署及私有倉庫搭建基礎(chǔ)命令,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Visual Studio發(fā)布 Docker 鏡像的實(shí)現(xiàn)步驟
本文詳細(xì)指導(dǎo)如何在Visual Studio中為ASP.NET Core WebAPI項(xiàng)目集成Docker支持,包括配置步驟、編寫Dockerfile、測試代碼、launchSettings.json配置及docker-compose.yml編寫,感興趣的可以了解一下2026-04-04
理解Docker(1):Docker安裝和基礎(chǔ)用法詳細(xì)介紹
本篇文章主要是介紹了Docker 安裝和基礎(chǔ)用法,對于想要需要的Docker的同學(xué)可以了解一下。2016-11-11

