Docker鏡像分層打包方案


一、背景

Docker鏡像采用了分層結構,如果所有的應用程序都使用了相同的基礎鏡像,就可以節省 Docker 注冊表的存儲空間,上傳和下載鏡像的速度也更快了,因為只需要傳輸更少的文件量(Docker 只會將新的層傳輸到注冊表中)。一般公司由於網絡條件限制,導致應用發布時傳輸速度較慢,因此需要考慮優化Docker鏡像構建。

以下是系統中典型的鏡像分層結構(通過docker history查看),其中每一行代表一個鏡像層,上半部分紅色框內的是應用程序構建的鏡像層,下半部分是源鏡像層。源鏡像層很少改動,每次構建都會復用,本文中所作的優化是針對上半部分的應用程序鏡像層。

二、優化方案

采用JIB工具對Spring Boot應用程序進一步分層,將其中的依賴項、資源文件和應用代碼構建為獨立的鏡像層,由於依賴項通常體積較大且改動較少,因此能充分利用鏡像分層復用的機制。

三、實施步驟

1.修改項目的父POM

  1. <properties>中加入以下自定義property:
<image.tag>default</image.tag>
<registry.username>default</registry.username>
<registry.password>default</registry.password>
  1. <pluginManagement>中加入JIB插件及相關配置,此處配置包含了Dockerfile中的內容(Dockerfile不再起作用,建議刪除)
  • 為方便起見,將鏡像構建過程綁定到Maven的install生命周期中;
  • configuration.from.image中配置源鏡像地址,configuration.to.image中配置目標鏡像推送地址,下圖中的xxxx對應於鏡像倉庫中各項目的namespace;
  • container.creationTime須配置符合DateTimeFormatter.ISO_DATE_TIME格式的時間,例如2019-07-15T10:15:30+08:00。如果設置為當前時間(USE_CURRENT_TIMESTAMP),則每次生成的鏡像就不相同,從而無法復用,因此,僅當依賴項改動時再去更新該時間。
<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.8.0</version>
    <executions>
        <execution>
            <phase>install</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <from>
            <image>registry.cn-hangzhou.aliyuncs.com/kancy/openjdk:8-jre-alpine</image>
            <auth>
                <username>${registry.username}</username>
                <password>${registry.password}</password>
            </auth>
        </from>
        <to>
            <image>registry.cn-hangzhou.aliyuncs.com/kancy/${project.artifactId}-jib</image>
            <auth>
                <username>${registry.username}</username>
                <password>${registry.password}</password>
            </auth>
            <tags>
                <tag>${latest}</tag>
                <tag>${image.tag}</tag>
            </tags>
        </to>
        <container>
            <!-- <creationTime>2020-05-01T10:00:00+08:00</creationTime>-->
            <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
            <volumes>/tmp</volumes>
            <workingDirectory>/home</workingDirectory>
            <environment>
                <TZ>Asia/Shanghai</TZ>
            </environment>
        </container>
    </configuration>
</plugin>	             

注意:

以上配置項僅包含了目前一般Springboot項目中典型的Dockerfile內容(如下所示),如果在原Dockerfile中有額外命令,需要在POM文件中添加相應的配置,或考慮包含到源鏡像中,詳情可參考官方文檔

3)docker registry 認證信息也可以配置在settings.xml

其中server.id為 docker registry倉庫地址

<servers>
	<server>
	  <id>registry.cn-hangzhou.aliyuncs.com</id>
	  <username>kancy1994</username>
	  <password>********</password>
	</server>
</servers>

2. 修改各應用的POM文件

在build.plugins內加入以下項即可,注意非應用類型的module不要添加。

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
</plugin>

3. 在Rancher管理界面中修改應用配置中的環境變量名稱

更新以下環境變量名稱:

JAVA_OPS替換為: JAVA_TOOL_OPTIONS
PROFILE 替換為: spring.profiles.active

或者

JAVA_TOOL_OPTIONS = "-Xmx1024m  -Dspring.profiles.active=sit"

注:原Dockerfile啟動命令中如果定義了其他環境變量,也需要在此添加。

四、查看效果

以下是JIB構建的鏡像,可以看到應用程序中的依賴項、資源文件和應用代碼被構建為獨立的鏡像層。應用重新構建時如果沒有改動依賴項,則只有極少的文件量需要傳輸。

五、注意事項

如果你的docker registry倉庫不支持https,那么maven打包的時候需要指定使用http模式,默認是https模式。
mvn clean package -DsendCredentialsOverHttp=true

六、參考

【1】不要把大型 JAR 包放進 Docker 鏡像
【2】案例spring-boot-docker-jib


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM