使用gitlab CI 对Springboot项目进行容器化持续发布
创建一个Springboot项目
可以使用如下多种方式创建项目:
- 使用idea的Springboot插件
- Maven
- Springboot CLI
我们只需要创建一个空项目,不需要写太多的代码。为了验证,我们给项目提供actuator的功能。
management.endpoint.beans.enabled=true
management.endpoint.info.enabled=true
management.endpoint.health.enabled=true
management.endpoints.web.exposure.include=health,info
2
3
4
5
项目创建完成后,启动项目测试一下:
# curl http://localhost:8080/actuator/health
{"status":"UP"}%
2
3
4
给项目提供gitlab CI功能
项目容器编译脚本
FROM openjdk:8u111-jdk-alpine
VOLUME /tmp
ADD /target/springbootci-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
2
3
4
springbootci-0.0.1-SNAPSHOT.jar
是项目pom文件声明的产物名称
<groupId>com.freshal.example</groupId>
<artifactId>springbootci</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootci</name>
<description>Demo project for Spring Boot</description>
2
3
4
5
6
7
创建CI pipeline 脚本
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay
SPRING_PROFILES_ACTIVE: gitlab-ci
stages:
- build
- package
maven-build:
image: maven:3-jdk-8A
stage: build
script: "mvn package -B"
artifacts:
paths:
- target/*.jar
docker-build:
stage: package
script:
- docker build -t freshal/springbootci .
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
image 和service
GitLab Runner可以使用容器镜像来支持流水线。image元素定义了我们要使用哪个镜像。 有效的镜像仅限于本地容器引擎和Docker Hub存储的。 service元素定义了额外的要使用的链接到主容器的镜像。在我们的例子中,主要容器是一个普通容器镜像,而链接容器是一个容器中的容器(Docker in Docker)
- 关于dind的说明:https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
Variables
变量可以定义编译环境使用的参数。 具体参考:https://docs.gitlab.com/ee/ci/yaml/#variables
GITALB已经预定义了一些变量,见:http://git.manystar.com/help/ci/variables/predefined_variables.md
Stages
stages元素定义了流水线的生命周期。我们给每一个stage都关联一个job。一个stage中的所有job并行运行,并按照我们定义的顺序依次触发各个stage,即,只有在上一个stage完成后才启动下一个stage。
maven build job
这个job是执行maven构建,所以使用了maven:3-jdk-8
作为执行构建的容器镜像。
script
是一个gitlab runner要执行的shell 命令。The mvn package -B
启动一个非交互式的maven构建过程。mvn package包括validate,compile,和test。
在不同的job之前持久化可执行的jar,我们声明job的产物。这些产物是每次成功构建后的输出文件,可以在gitlab流水线的界面上下载。
- maven 详细例子:https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Maven.gitlab-ci.yml
- gradle 详细例子:https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
容器创建
关于容器创建的详细例子参考:https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Docker.gitlab-ci.yml
缓存maven库
如果每次都新建容器,下载依赖,非常影响效率,为了解决这个问题,可以使用cache。
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay
SPRING_PROFILES_ACTIVE: gitlab-ci
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
cache:
paths:
- .m2/repository
stages:
- build
- package
maven-build:
image: maven:3-jdk-8A
stage: build
script: "mvn package -B"
artifacts:
paths:
- target/*.jar
docker-build:
stage: package
script:
- docker build -t freshal/springbootci .
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
关于cache的详细例子: https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Maven.gitlab-ci.yml
其他总结
gitlab runner配置模式
gitlab runner有三种配置方式
- shell执行
- Docker in Docker
- Docker socket bind 这三种模式没有一种更好,更多的需要权衡。dind模式会比较慢一些,因为每一个job都在一个干净的环境中,但是这允许并发且不会冲突。另外dind和socket bind模式不能混用。
config.toml里的concurrent字段的意义
concurrent限制了整个GitLab Runner能并发处理job的数量。特别注意concurrent与worker数量无任何关系,所有worker的工作是受GitLab Runner控制的,如果concurrent值为1并且有一个worker已经在工作了,那么即使其他worker达到了可以工作的条件也只能“pending”。
config.toml配置说明: https://docs.gitlab.com/runner/configuration/advanced-configuration.html
cache存储在哪里
https://docs.gitlab.com/ee/ci/caching/#where-the-caches-are-stored
这里讲了如何使用cache,以及cache的最佳实践:
- Tag your Runners and use the tag on jobs that share their cache.
- Use sticky Runners that will be only available to a particular project.
- Use a key that fits your workflow (for example, different caches on each branch). For that, you can take advantage of the CI/CD predefined variables.
怎样清除cache
注意cache是没有过期时间的,而且每一次新的push触发的pipeline,都会重新生成cache,重新生成的cache的名字为<cache-key>-<num>
,其中num是随着push数量递增的。如果不去清除cache,cache会永久保留在Runner上,日积月累会填满存储空间的,因此最好隔一段时间进行一次清除,清除方法请参考https://docs.gitlab.com/ee/ci/caching/#clearing-the-cache,或者使用clear_volumes.sh 这个简单脚本来处理它, 清除cache的原理是将相关的volume移除,当然,docker也有自带的清除命令,推荐将docker system prune -f --volumes加入到定时任务中。
mac上的docker volume在哪
~/Library/Containers/com.docker.docker/Data/vms/0/
使用screen 命令可以连接tty进入
Gitlab CI详解
- 基本概念:https://docs.gitlab.com/ee/ci/introduction/
- CI配置详解:https://docs.gitlab.com/ee/ci/yaml/
- Gitlab容器注册:https://docs.gitlab.com/ee/user/packages/container_registry/index.html#enable-the-container-registry-for-your-project
- 与Docker容器集成:https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
- pipeline详解:https://docs.gitlab.com/ee/ci/pipelines/index.html
- gitlab runner配置详细说明:https://docs.gitlab.com/runner/configuration/
maven的settings.xml
修改config.toml,加入volumes
volumes = ["/Users/marszhang/.m2/settings.xml:/mvn/.m2/settings.xml","/var/run/docker.sock:/var/run/docker.sock","/cache"]
修改.gitlab-ci.yml,加入before_script段
maven-build:
image: maven:3-jdk-8
stage: build
before_script:
- cp -f /mvn/.m2/settings.xml $HOME/.m2/settings.xml
script:
- "mvn package -B"
after_script:
- rm -f $HOME/.m2/settings.xml
2
3
4
5
6
7
8
9