我的docker随笔37:使用gitlab和jenkins实现CICD

1,233 阅读5分钟

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

本文涉及一种利用容器部署 gitlab 和 jenkins 服务实现持续集成(CICD)的方法,其目的是为了在实际工作中使用代码托管及自动化操作。

一、引言

因工作需要,需部署 gitlab 和 jenkins 服务器进行 CICD 测试,换个高大上的名称,叫“组织革新”。本文记录个人的实践,但不涉及部署的具体步骤。

二、技术小结

  • 不同工程,配置不同,本文使用 C++ 工程为例进行实验。
  • 在配置 jenkins 时,建议经常使用页面下方的“应用”,随时保存设置好的参数,以防不测。

三、gitlab和jenkins联调

3.1 概述

实现CICD分几个阶段:使用 gitlab 托管代码,使用 jenkins 进行编译、打包以及发布。两个服务器各有项目对应,同时要进行必要的配置。不同项目,配置方式不尽相同。本节的配置原则上按顺序进行,因此会在 gitlab 和 jenkins 之间来回切换,故先行说明。

3.2 前置条件

3.2.1 允许本地网络请求

使用 root 用户登录 gitlab 服务器,在管理员配置选项选择网络(Setting) 页面,在外发请求(Outbound requests) 中,选择“允许Webhook和服务对本地网络的请求(Allow requests to the local network from web hooks and services) ”,保存。如图1所示。

进行该设置的目的是因为本文的 gitlab 和 jenkins 服务均在同一物理服务器上使用 docker 部署。如果不设置,则在 gitlab 中设置 webhooks 时会提示Url is blocked: Requests to the local network are not allowed

1.png

说明:如果jenkins和gitlab不在同一服务器,则不需要进行此设置。

3.2.2 关闭 CSFR

进入 jenkins 容器,找到/usr/local/bin/jenkins.sh文件,找到 exec java 行,在-Duser.home="$JENKINS_HOME"后添加-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true,完整的一行语句如下:

exec java -Duser.home="$JENKINS_HOME" -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true "${java_opts_array[@]}" -jar ${JENKINS_WAR} "${jenkins_opts_array[@]}" "$@

说明:在笔者定制的 jenkins 镜像中已经进行该修改了。

进行该设置,是因为高版本 Jenkins 无法在界面关闭跨站请求伪造保护(CSRF),因此在 gitlab 进行 webhooks 时会认证失败。提示:

 Hook executed successfully but returned HTTP 403

关闭之后,再次进入 CSFR 页面,提示:

This configuration is unavailable because the System property hudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION is set to true.

image-20211020161017526.png

说明修改成功。

对于物理机部署的 jenkins,则在 /etc/sysconfig/jenkins 文件中找到 JENKINS_JAVA_OPTIONS, 设置如下:

JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true"

3.3 准备 gitlab 仓库

本文使用仓库地址为 http://10.8.18.168:8888/latelee/ci_test

3.4 配置 jenkins 项目

3.4.1 新建项目

在 jenkins 首页左侧,点击“新建任务”,输入项目项目,选择第一项“自由风格软件项目”。 2.png

点击“确定”进入配置页面。

3.4.2 指定git仓库

源码管理选项页面中,输入 gitlab 仓库地址,注意,URL 地址后须添加.git后缀。

3.png

点击“添加”->Jenkins,添加凭据,默认类型为用户名和密码。

4.png

添加后,选择添加的凭据,红色错误提示消失。

5.png

3.4.3 设置触发条件

构建触发器页面进行触发器的选择。此处有多种方式可选,如定时构建和指定 gitlab 方式。

6.png

勾选“Build when a change is pushed to GitLab.”。注意,该项后面的 URL 地址需要记住,将在 gitlab 中使用。点击“高级”,在“Secret token”处点击“Generate”,生成 token,该 token 亦需要记住。

7.png

进行此设置目的是,当提交代码到 gitlab 仓库时,会自动触发 jenkins 执行 一次构建。触发条件在对应 gitlab 仓库中进行设置。如果不需要自动触发,则可以不触发条件。

3.4.4 指定构建步骤

构建页面,点击“增加构建步骤”,选择“执行shell”,输入构建的命令。

8.png

3.4.5 指定构建后的步骤

构建后操作页面,点击“增加构建后操作步骤”。选择“send build artifacts over SSH”。选择服务器、源目录、目标目录及执行的命令。注意,在本文实践前已经设置好服务器及目标,故只指定源文件和执行命令即可。

9.png

在笔者实践中发现,在“构建环境”、“构建”、“构建后操作”三个页面均可以选择将文件通过 SSH 发送服务器。

3.5 设置 gitlab 的 webhooks

在 gitlab 项目http://10.8.18.168:8888/latelee/ci_test页面, 选择“Settings”->“Webhooks”,输入上小节生成的 URL 和 token。

10.png

点击页面下方“Add webhook”,添加。

11.png

注:同一个gitlab仓库,可支持多个 webhook。

点击“Test”,选择“Push events”,进行测试验证。为保证触发成功,强烈建议在此处先行测试

12.png

触发类型有很多种,根据实际情况选择。

3.4 验证

提交代码到 gitlab 仓库(此处从略)。稍等片刻,在 jenkins 工程的看到进行了触发。

13.png

输出日志如下:

14.png

编译、运行、执行ssh远程服务均成功。在远程服务器的/tmp目录出现a.outlog.txt

四、其它的配置

4.1 邮件通知

jenkins系统设置。见前面文章。此处关注项目配置。

注意,邮件通知需要根据不同应用情况设置,此处作为示例,只关注是否能在构建时发邮件。至于何时何条件触发,非本文范围。

定位到构建后操作页面,添加Editable Email Notification

15.png

在该插件配置处选择高级,在“Always”处输入接收者邮件,其它保持不变(即使用默认的模板)。

16.png

保存即可。

4.2 未登录时可查看构建信息

进入“系统管理”->“全局安全配置”页面,勾选“匿名用户具有可读权限”。如下:

17.png

此时,无须登录,即可查看项目的构建构建,可根据情况决定是否勾选。

五、进阶

构建的工程位于/var/lib/jenkins/workspace/,可以先在工程目录进行测试,再使用 Jenkins 进行集成。

六、问题

在构建阶段直接启动bash执行脚本,能启动,但随后被jenkins停止。终端提示:

Process leaked file descriptors. See https://www.jenkins.io/redirect/troubleshooting/process-leaked-file-descriptors for more information

官方解释:

To reliably kill processes spawned by a job during a build, Jenkins contains a bit of native code to list up such processes and kill them.