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