https://github.com/zq2599/blog_demosjava
內容:全部原創文章分類彙總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;node
在《體驗SpringBoot(2.3)應用製做Docker鏡像(官方方案)》一文中,我們掌握了SpringBoot官方推薦的鏡像構建方案,接下來要體驗的是GitLab的CI能力,它負責把代碼變成私有倉庫中的鏡像,我們能夠專心編碼了;git
GitLab CI的做用以下圖,開發者提交代碼到GitLab後,就會觸發編譯、構建、製做鏡像、推送到倉庫這些事情,而後K8S環境就能用上最新的鏡像了:
程序員
本文繼續堅持實戰的風格,和你們一塊兒完成如下操做:github
實戰前須要您準備好如下環境:web
本次實戰用的是普通的SpringBoot工程,若是您不打算寫代碼,也能夠從GitHub上下載本次實戰的源碼,地址和連接信息以下表所示:spring
名稱 | 連接 | 備註 |
---|---|---|
項目主頁 | https://github.com/zq2599/blog_demos | 該項目在GitHub上的主頁 |
git倉庫地址(https) | https://github.com/zq2599/blog_demos.git | 該項目源碼的倉庫地址,https協議 |
git倉庫地址(ssh) | git@github.com:zq2599/blog_demos.git | 該項目源碼的倉庫地址,ssh協議 |
這個git項目中有多個文件夾,本章的應用在dockerlayerdemo文件夾下,以下圖所示:
docker
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.bolingcavalry</groupId> <artifactId>dockerlayerdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dockerlayerdemo</name> <description>Demo project for Spring Boot layer docker image</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.0.RELEASE</version> <configuration> <layers> <enabled>true</enabled> </layers> </configuration> </plugin> </plugins> </build> </project>
package com.bolingcavalry.dockerlayerdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; @SpringBootApplication @RestController public class DockerlayerdemoApplication { public static void main(String[] args) { SpringApplication.run(DockerlayerdemoApplication.class, args); } @RequestMapping(value = "/hello") public String hello(){ return "hello " + new Date(); } }
# 指定基礎鏡像,這是分階段構建的前期階段 FROM openjdk:8u212-jdk-stretch as builder # 執行工做目錄 WORKDIR application # 配置參數 ARG JAR_FILE=target/*.jar # 將編譯構建獲得的jar文件複製到鏡像空間中 COPY ${JAR_FILE} application.jar # 經過工具spring-boot-jarmode-layertools從application.jar中提取拆分後的構建結果 RUN java -Djarmode=layertools -jar application.jar extract # 正式構建鏡像 FROM openjdk:8u212-jdk-stretch WORKDIR application # 前一階段從jar中提取除了多個文件,這裏分別執行COPY命令複製到鏡像空間中,每次COPY都是一個layer COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
image: maven:3.6.3-jdk-8 variables: MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" # 定義緩存 # 若是gitlab runner是shell或者docker,此緩存功能沒有問題 # 若是是k8s環境,要確保已經設置了分佈式文件服務做爲緩存 cache: key: dockerlayerdemo-ci-cache paths: - .m2/repository/ - target/*.jar # 本次構建的階段:build package stages: - package - build # 生產jar的job make_jar: image: maven:3.6.3-jdk-8 stage: package tags: - k8s script: - echo "=============== 開始編譯源碼,在target目錄生成jar文件 ===============" - mvn $MAVEN_CLI_OPTS clean compile package -Dmaven.test.skip=true - echo "target文件夾" `ls target/` # 生產鏡像的job make_image: image: docker:latest stage: build tags: - k8s script: - echo "從緩存中恢復的target文件夾" `ls target/` - echo "=============== 登陸Harbor ===============" - docker login 192.168.50.43:5888 -u admin -p Harbor12345 - echo "=============== 打包Docker鏡像 : " gitlabci-java-demo:$CI_COMMIT_SHORT_SHA "===============" - docker build -t 192.168.50.43:5888/common/gitlabci-java-demo:$CI_COMMIT_SHORT_SHA . - echo "=============== 推送到鏡像倉庫 ===============" - docker push 192.168.50.43:5888/common/gitlabci-java-demo:$CI_COMMIT_SHORT_SHA - echo "=============== 登出 ===============" - docker logout - echo "清理掉本次構建的jar文件" - rm -rf target/*.jar
關於以上pipeline腳本,有下面五點須要注意:shell
第一:關於cache,若是您的gitlab runner是shell或者docker類型就無需關注,cache是直接生效的,但若是您的gitlab runner是K8S那就要注意了,須要在gitlab runner中填寫cache相關的配置,讓分佈式文件服務做爲cache的底層實現;數據庫
第二:一共定義了兩個stage:package和build,順序是先package再build,注意生成jar的job必定要是package,使用jar構建鏡像的job要是build,這樣在構建鏡像的時候才能順利從緩存中取得jar;
第三:make_image這個job的腳本中,會執行登陸私有鏡像倉庫的操做,爲了操做方便,登陸的帳號密碼都是直接寫在腳本里面的,實際使用時請不要這樣作,建議使用Harbor的機器人帳號密碼,而且寫入GitLab CI的環境變量配置頁面,而不是直接寫在pipeline腳本中
第四:tags參數用來和已有的GitLab Runner匹配,請按照您本身的runner的狀況設置;
第五:生成docker鏡像的tag等於$CI_COMMIT_SHORT_SHA,這是本次提交的commit id,所以,每次提交都會致使鏡像倉庫中多一個鏡像,其tag等於commit id;
至此,全部開發工做已經完成,接下來驗證執行狀況;
2. 先來看make_jar的執行狀況,以下圖,SpringBoot工程成功構建出jar文件:
3. 再看make_image執行狀況,以下圖:
4. 鏡像製做成功後,開始推送到harbor:
5. 最終完成推送,而且清理殘留文件:
6. 最後看看pipeline的總體狀況,以下圖:
7. 從上圖可知commit id是02307851,所以Harbor中應該有tag等於02307851的鏡像,登陸Harbor查看,以下圖紅框:
接下來要在K8S環境驗證以前的鏡像能夠正常運行:
kubectl create deployment dockerlayerdemo \ --image=192.168.50.43:5888/common/gitlabci-java-demo:02307851
kubectl create service nodeport \ dockerlayerdemo --tcp 8080:8080
文章看到這裏,我們pipeline腳本也寫了,鏡像有了,K8S上部署的服務也驗證了,這就結束了嗎?
---尚未,我們來感覺一下從修改代碼到K8S環境上生效的流程:
4. 在K8S環境執行如下命令便可完成鏡像更新:
kubectl set image deployment dockerlayerdemo \ gitlabci-java-demo=192.168.50.43:5888/common/gitlabci-java-demo:8735c78d
可見藉助GitLab CI,編碼到部署之間的過程已被簡化,能夠更加專一的擼碼了;
除了持續集成(CI),還能夠把持續部署(CD)也加入到pipeline腳本中,這樣咱們只需提交代碼,對應的鏡像會被自動部署到K8S環境;
stages: - package - build - deploy
# 生產鏡像的job deploy_k8s: # 禁用cache,避免上傳、下載、壓縮、解壓縮帶來的開銷 cache: {} image: ictu/sshpass:latest stage: deploy tags: - k8s script: - export TAG=$CI_COMMIT_SHORT_SHA - echo "TAG is "$TAG - sshpass -p 888888 ssh -o "StrictHostKeyChecking no" root@192.168.50.135 "kubectl set image deployment dockerlayerdemo gitlabci-java-demo=192.168.50.43:5888/common/gitlabci-java-demo:$TAG"
5. 提交代碼後,能夠在CI頁面觀察新增job的執行過程;
6. 腳本完成後,打開瀏覽器試試,果真已經更新:
至此,CI和CD都驗證經過,可見GitLab的CI能力給咱們的平常開發帶來了很多便利,也但願本文能給您帶來一些參考;
微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demos