系列:
spring-boot使用maven構建docker鏡像(單服務)
spring-boot使用maven構建docker鏡像(單服務+MySQL)
spring-boot使用maven構建docker鏡像(多服務)
文章目錄
多服務 構建docker鏡像 + 運行
使用Dockerfile構建鏡像,使用docker-compose.yml定義多個容器的啓動參數
前提:
- 開啓docker遠程管理端口(此案例演示暫不考慮安全問題,直接開啓2375端口)
參考鏈接:[…]
示例項目
項目模擬一般的分佈式項目,有多個服務(用戶服務、訂單服務)還有數據庫(MySQL)。
項目結構
實現方式
分別構建每個服務的鏡像,通過統一管理模塊(或父模塊)編寫docker-compose.yml管理多個服務容器的啓停。
正文
1. 編寫每個服務的 Dockerfile(基本相同)
Dockerfile官方文檔:https://docs.docker.com/engine/reference/builder/
FROM openjdk:8-jdk-alpine
ADD *.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Duser.timezone=GMT+08", "-jar", "/app.jar"]
2. 每個服務的 pom.xml 引入 io.fabric8/docker-maven-plugin 插件(基本相同)
io.fabric8/docker-maven-plugin官方文檔:http://dmp.fabric8.io/
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.33.0</version>
<configuration>
<verbose>true</verbose>
<!-- docker遠程管理url -->
<dockerHost>tcp://192.168.121.129:2375</dockerHost>
<images>
<image>
<!-- 鏡像名稱 -->
<name>${project.artifactId}:${project.version}</name>
<build>
<!-- 使用Dockerfile定義鏡像構建流程 -->
<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
<assembly>
<name>/</name>
<!-- artifact是預定義的值,表示將項目打包後的jar拷貝到編譯上下文中,便於Dockerfile ADD指令 -->
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
</plugin>
3. 新增一個模塊(或用父模塊)用來統一管理容器啓停,編寫 docker-compose.yml
Compose file官方文檔:https://docs.docker.com/compose/compose-file/
version: "2"
services:
database:
image: mysql:5.7
ports:
- 3306:3306
volumes:
- /home/mysqldata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test-db #默認創建數據庫名
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] #指定MySQL的編碼(覆蓋CMD指令)
networks:
my-custom-network:
aliases:
- mysql-server #在同個網絡的其他服務可以通過此別名訪問此服務
user-service:
image: user-service:1.0.0
ports:
- 8081:8080
environment:
MYSQL_SERVER: mysql-server:3306 #在同個網絡,可以通過服務名/別名訪問
depends_on:
- database
networks:
my-custom-network:
aliases:
- user-service
order-service:
image: order-service:1.0.0
ports:
- 8082:8080
environment:
MYSQL_SERVER: mysql-server:3306 #在同個網絡,可以通過服務名/別名訪問
USER_SERVICE: user-service:8081 #在同個網絡,可以通過服務名/別名訪問
depends_on:
- database
- user-service
networks:
my-custom-network:
aliases:
- order-service
networks:
my-custom-network:
driver: overlay
4. maven 命令
- 構建鏡像
mvn clean package docker:build
- 刪除鏡像
mvn docker:remove
- 啓動容器
mvn docker:run
- 停止容器(自動刪除容器)
mvn docker:stop
4.1 一般流程
- 在每個服務中執行構建鏡像命令
mvn clean package docker:build
- 在同一管理模塊啓動所有服務:
mvn docker:run
- 在同一管理模塊停止所有服務:
mvn docker:stop
要點說明
- 數據庫是由MySQL容器拉起時自動創建的。(MYSQL_DATABASE環境變量)
- 數據庫初始化是由Spring框架自動執行SQL腳本功能完成的。(spring.datasource.initialization-mode屬性)
後期維護需求
當項目第一次構建鏡像運行時,按照上面的流程基本沒什麼問題。但是,當第二次構建鏡像時,可能會有以下需求。
更新項目時,不想銷燬MySQL容器,使用已有歷史數據
默認情況下,docker:stop,docker:run會操作所有在docker-compose.yml定義的服務。
所以,我們只需要將docker-compose.yml裏關於MySQL服務的配置註釋掉,這樣就不會重新拉起或關閉MySQL容器。(可能還需要將其他服務的 depends_on 註釋掉)
version: "2"
services:
# database:
# image: mysql:5.7
# ports:
# - 3306:3306
# volumes:
# - /home/mysqldata:/var/lib/mysql
# environment:
# MYSQL_ROOT_PASSWORD: root
# MYSQL_DATABASE: test-db #默認創建數據庫名
# command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] #指定MySQL的編碼(覆蓋CMD指令)
# networks:
# my-custom-network:
# aliases:
# - mysql-server #在同個網絡的其他服務可以通過此別名訪問此服務
省略...
還有一點要注意,上文’關鍵要點’提到,數據庫初始化是由Spring框架完成的,所以如果想保留MySQL的歷史數據,則要把自動初始化SQL腳本功能關閉。
(設置spring.datasource.initialization-mode = never)
常見問題
2375 端口不通問題排查
- 是否開啓docker遠程訪問(lsof -i 2375)
- 是否關閉防火牆(systemctl status firewalld)
- systemct stop firewalld && systemct disable firewalld //關閉&禁用防火牆
注
使用插件引用docker-compose.yml文件啓動容器的方式和直接使用命令引用docker-compose.yml啓動容器是不一樣的。
docker swarm init
docker stack deploy -c docker-compose.yml stack-demo
reference:
Docker Compose是什麼?
Docker Compose https://docs.docker.com/compose/
Docker Swarm https://docs.docker.com/engine/swarm/