0.前言
前段时间,考虑到要练习部署一套CI/CD的系统。一开始考虑到Jenkins,随着这两天的了解,发现最新版的GitLab已经提供有CI/CD集成了。所以本次博客,干脆一步到位,直接用GitLab里面的CI/CD模块。Jenkins可能需要更高级的应用场合。经过测试GitLab自带的功能完全符合我的需求。
1. 安装GitLab和GitLab-CI(gitlab-runner)
英语比较好的,可以直接看官方文档。https://docs.gitlab.com/omnibus/docker/#install-gitlab-using-docker-compose https://docs.gitlab.com/ee/ci/quick_start/README.html
下面提供我使用的 docker-compose.yml
1 version: '3'
2 services:
3 gitlab:
4 image: twang2218/gitlab-ce-zh:latest
5 #image: gitlab/gitlab-ce:rc
6 restart: always
7 hostname: '172.16.23.203'
8 environment:
9 GITLAB_OMNIBUS_CONFIG: |
10 external_url 'http://172.16.23.203:8929'
11 gitlab_rails["time_zone"] = "Asia/Shanghai"
12 ports:
13 - 8929:8929
14 - 1080:80
15 - 1443:443
16 - 1022:22
17 volumes:
18 - /root/workspace/docker/gitlab/1/config:/etc/gitlab
19 - /root/workspace/docker/gitlab/1/logs:/var/log/gitlab
20 - /root/workspace/docker/gitlab/1/data:/var/opt/gitlab
21 gitlab-runner:
22 image: gitlab/gitlab-runner:latest
23 restart: always
24 volumes:
25 - /root/workspace/docker/gitlab/2/config:/etc/gitlab-runner
26 - /var/run/docker.sock:/var/run/docker.sock
执行docker-compose up -d 就运行起来,几点需要说明的
1. gitlab的image,可以选择中文版或者英文版
2. hostname 这里指定本机IP地址
3. gitlab环境变量,external_url表示提供访问的IP和端口,时区配置上海
4. 端口映射,默认是80端口,由于我上面配置了8929,所以映射8929到Host主机
5. volumes 配置持久化数据
6. 这里的/var/run/docker.sock 要映射到主机,因为会用到主机的一些资源,同时还会在docker里面安装docker
下面是运行效果,第一次运行会比较久,因为要拉取镜像和初始化GitLab
2. 登录使用GitLab
首次登录,设置密码。 登录默认用户名是root
利用模版,新建一个Spring项目
利用IDE,或者其他工具,或者直接在GitLab修改代码
3. 配置CI/CD,把机器(gitlab-runner)注册到GitLab中
可以在项目配置CI/CD机器,也可以在个人所有项目下配置,也可以由管理员配置所有项目下CI/CD机器。原理和流程都是一样的,只是比Jenkins更加细粒度控制而已。
进入gitlab-runner的Docker,执行初始化命令 gitlab-ci-multi-runner register,完整命令如下:
1 sudo docker exec -it gitlab-runner gitlab-ci-multi-runner register
需要录入的信息,安装上图进行,填写,后续还可以修改。
如果需要修改,可以修改之前volumes配置的路径下, config/config.toml
1 concurrent = 1
2 check_interval = 0
3
4 [session_server]
5 session_timeout = 1800
6
7 [[runners]]
8 name = "myRunner"
9 url = "http://172.16.23.203:8929/"
10 token = "96beefdaa54832b0c8369ffa3811c9"
11 executor = "docker"
12 [runners.custom_build_dir]
13 [runners.docker]
14 tls_verify = false
15 image = "docker:latest"
16 privileged = true
17 disable_entrypoint_overwrite = false
18 oom_kill_disable = false
19 disable_cache = false
20 volumes = ["/cache", "/root/.m2:/root/.m2", "/var/run/docker.sock:/var/run/docker.sock"]
21 shm_size = 0
22 [runners.cache]
23 [runners.cache.s3]
24 [runners.cache.gcs]
上面这个是配置文件,里面有几个注意点
1. privileged 这里要配置 true,因为要在docker里面安装docker
2. /root/.m2 这个是配置maven的仓库使用宿主主机的缓存,这样就不用每次CI都要下载依赖
3. /var/run/docker.sock 这个也要配置,在构建dockerfile的时候会用到
还有一个需要配置的就是,这个Runner需要设置tag,这个是标识Runner的名称。在.gitlab-ci.yml中会用到
4. 配置CI/CD
默认GitLab是启用该功能的,根目录配置新增 .gitlab-ci.yml 文件,然后每次git push,都会触发CI持续集成。当然可以在yml配置,在主线master触发。
来个简单的配置,测试一下
1 image: maven:3-jdk-8
2 cache:
3 paths:
4 - .m2/repository
5 test:
6 stage: test
7 script:
8 - mvn package
9 tags:
10 - tag
上面这个配置,写到.gitlab-ci.yml然后提交到repo,我们提交该文件到gitlab对应项目上去。
1 git add .gitlab-ci.yml
2 git commit -m "Add .gitlab-ci.yml"
3 git push origin master
如果嫌慢,pom.xml 可以换个阿里源
1 <repository>
2 <id>maven-ali</id>
3 <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
4 <releases>
5 <enabled>true</enabled>
6 </releases>
7 <snapshots>
8 <enabled>true</enabled>
9 <updatePolicy>always</updatePolicy>
10 <checksumPolicy>fail</checksumPolicy>
11 </snapshots>
12 </repository>
一提交,就会触发自动构建
可以看到整个构建过程,如果出现错误,也是到这个日志里面排查问题。
5. 测试、打包、发布
这一步,我们实现一个简单的测试、打包、发布
5.1 增加 Dockerfile
1 FROM openjdk:8-jdk-alpine
2 VOLUME /tmp
3 COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
4 ENV PORT 5000
5 EXPOSE $PORT
6 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dserver.port=${PORT}","-jar","/app.jar"]
5.2 修改 .gitlab-ci.yml
1 image: maven:3-jdk-8
2
3 variables:
4 DOCKER_TAG: test/demo-spring:0.1
5
6 cache:
7 paths:
8 - .m2/repository
9
10 stages:
11 - test
12 - package
13 - deploy
14
15 test:
16 stage: test
17 tags:
18 - tag
19 script:
20 - mvn test
21
22 package:
23 stage: package
24 tags:
25 - tag
26 script:
27 - mvn clean package -Dmaven.test.skip=true
28 artifacts:
29 paths:
30 - target/*.jar
31
32 deploy:
33 image: docker:latest
34 stage: deploy
35 services:
36 - docker:dind
37 tags:
38 - tag
39 script:
40 - docker version
41 - docker build -t $DOCKER_TAG .
42 - docker rm -f test || true
43 - docker run -d --name test -p 5000:5000 $DOCKER_TAG
那个artifacts.paths 配置,提交target目录下的文件到下一个流水线,因为不同流水线,由于是基于Docker,所以每一步都是隔离的。同时,上传的附件还可以在构建成功后,在流水线pipelines界面进行下载。每一步的image都是可以指定的,那个tags也是可以指定的。可以提交到不同的机器进行构建。
上面一共就三步流程,先test(测试),然后package(打包编译),最后deploy(发布测试)。前两个比较好理解,就是maven的基本命令。最后那个deploy就是利用docker里面的docker来进行打包成docker,然后运行起来,作为测试发布。
更新代码.gitlab-ci.yml,然后提交,触发持续集成。
查看构建日志
查看宿主机镜像和运行状态
查看浏览器,已经发布到测试环境了
5.3 钉钉通知
1 image: maven:3-jdk-8
2
3 variables:
4 DOCKER_TAG: test/demo-spring:0.1
5
6 cache:
7 paths:
8 - .m2/repository
9
10 stages:
11 - test
12 - package
13 - deploy
14 - notify
15
16 test:
17 stage: test
18 tags:
19 - tag
20 script:
21 - mvn test
22
23 package:
24 stage: package
25 tags:
26 - tag
27 script:
28 - mvn clean package -Dmaven.test.skip=true
29 artifacts:
30 paths:
31 - target/*.jar
32
33 deploy:
34 image: docker:latest
35 stage: deploy
36 services:
37 - docker:dind
38 tags:
39 - tag
40 script:
41 - docker version
42 - docker build -t $DOCKER_TAG .
43 - docker rm -f test || true
44 - docker run -d --name test -p 5000:5000 $DOCKER_TAG
45
46 notify:
47 image: appropriate/curl:latest
48 stage: notify
49 tags:
50 - tag
51 script: "curl 'https://oapi.dingtalk.com/robot/send?access_token=d6c15304c1***************************************' -H 'Content-Type: application/json' -d '{\"msgtype\": \"text\", \"text\": {\"content\": \"功能已更新部署至测试环境\"}}' "
有了这个通知,就可以做很多事情了,写个脚本,封装成一个Docker 镜像,可以发送钉钉,发送邮件,可以对接到第三方系统等。
更多高级应用,如集成之前了解的Harbor,Rancher。使整个系统更加强大,更加智能化。
参考资料
https://cloud.tencent.com/developer/article/1010595
https://docs.gitlab.com/omnibus/docker/#install-gitlab-using-docker-compose https://docs.gitlab.com/ee/ci/quick_start/README.html