spring-boot使用maven構建docker鏡像(多服務)

系列:
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 一般流程

  1. 在每個服務中執行構建鏡像命令 mvn clean package docker:build
  2. 在同一管理模塊啓動所有服務:mvn docker:run
  3. 在同一管理模塊停止所有服務: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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章