手把手教你用 Gitlab 和 Jenkins 构建持续集成环境

Posted by Mike on 2020-05-24

最近用到持续集成顺便总结在这里,都是用的最新版。搭建过程中还有一个 Demo,提交代码到 Gitlab 自动触发 Jenkins 任务,自动编译代码和 Docker 镜像并上传。

安装运行 Gitlab

Gitlab 国内安装很麻烦,用官方的源装不了,因为在国外,太慢,链接会断掉。国内清华有 Gitlab 的 Apt 和 Yum 源,但是我试过安装 CentOS 7 的 Gitlab ,到最后都会一直卡住结束不了。直接下载清华 Gitlab 的 Rpm Mirror 安装也是一样,所以我还是选择用 Docker 启动 Gitlab(提前配好 Docker Hub 加速器)

  • 准备镜像
1
$ docker pull gitlab/gitlab-ee:latest
  • 准备 Gitlab 所需目录
1
2
3
$ mkdir gitlab
$ cd gitlab
$ mkdir config logs data
  • 准备启动脚本

替换想要的启动的端口,IP 地址替换为访问你的 Gitlab 的地址,也可以替换想要的挂载目录。

1
2
3
4
5
6
7
8
9
10
11
12
$ vi run
#! /bin/bash

sudo docker run -d --rm \
-p 8088:8088 \
--name gitlab \
--env GITLAB_OMNIBUS_CONFIG="external_url 'http://118.24.64.246:8088/'; gitlab_rails['lfs_enabled'] = true;" \
-v $PWD/config:/etc/gitlab \
-v $PWD/logs:/var/log/gitlab \
-v $PWD/data:/var/opt/gitlab \
gitlab/gitlab-ee:latest
EOF
  • 赋予执行权限
1
$ chmod +x run
  • 启动 Gitlab
1
$ ./run
  • 查看 Gitlab 控制台输出
1
$ docker logs -f gitlab

访问 Gitlab,打开脚本中配置的 external_url 地址,设置管理员密码和注册 Gitlab 账号,登录并添加自己的 SSH key 。创建 Repo ,git clone 到本地,后面我们提交代码到这个 Repo ,触发 Jenkins 的持续集成。

安装运行 Jenkins

Jenkins 建议直接安装在宿主机,不用 Docker 方式,因为持续集成需要安装各种我们用到的工具,这些工具可能后面根据需要才安装,重启不能让这些工具丢失。比如编译 Java 源码需要装 JDK 环境,编译和上传 Docker 镜像需要安装 Docker 环境,并且还需要提前 docker login 好,不然上传不了。

因为 Jenkins 用 JAVA 写的,所以确保机器上装有 JDK 或 OpenJDK 环境,准备一个 Jenkins 用的目录,下载 War 包。

1
2
$ mkdir jenkins 
$ wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war

运行

1
$ nohup java -jar jenkins.war --httpPort=8080 &> jenkins.log &

查看 jenkins 输出

1
$ tail -f jenkins.log

第一次打开 Jenkins Web 界面,要求输出管理员初始密码,生成在服务器上,界面上提示有路径。

查看密码

1
$ cat /root/.jenkins/secrets/initialAdminPassword

粘贴密码并继续,安装推荐的插件,等待安装完成

创建管理员,保存并完成。

至此,jenkins 安装完成

Jenkins 安装需要的插件

打开 Jenkins-系统设置-管理插件。

在可选插件里选择并安装需要的插件:Git 、 GitLab 、Build Authentication Token Root (Git 插件在默认推荐插件里已安装,在可选插件列表里可能没有)。

点击 “直接安装”,勾选 “安装完成后重启 Jenkins (空闲时)“,等待安装完成自动重启 Jenkins。

由于后面 Jenkins 的机器上需要用到 Docker,所以保证 Jenkins 所在机器安装好 Docker 并配好 Docker Hub 的加速器,并且 docker login 登录镜像要上传的仓库。

Gitlab 创建 Repo

我们这里就以一个简单的 Golang 程序做实例,实现提交代码自动编译代码,然后 Docker 编译镜像并上传至 CCR (腾讯云的 Docker 镜像仓库)。

在 Gitlab 上创建空 Repo,Clone 到本地,添加三个文件。

  • main.go (源码)
1
2
3
4
5
package main

func main() {
println("hello world")
}
  • Dockerfile (编译镜像用的 Dockerfile)
1
2
3
4
5
6
7
FROM alpine:latest

MAINTAINER roc<rockerchen@tencent.com>

COPY bd-ci-test /bin/bd-ci-test

CMD ["bd-ci-test"]
  • build (编译源码、镜像和上传镜像的脚本,替换 IMAGE 地址为要上传的地址)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#! /bin/bash

# 编译代码
docker run --rm \
-v $PWD:/go/src/bd-ci-test \
-w /go/src/bd-ci-test \
golang:alpine go build

IMAGE="imroc/bd-ci-test:latest"

# 编译镜像
docker build -t $IMAGE .

# 上传镜像 (请提前登录好,docker login 只需登录一次)
docker push $IMAGE

# 清理
docker rmi $IMAGE
rm bd-ci-test
  • 给 build 脚本执行权限
1
$ chmod +x build

至此,我们的代码准备好了,先不忙提交,接下来配置 Jenkins 来做持续集成。

配置 Jenkins

新建 Jenkins 项目,选择 “构建一个自由风格的软件项目”。

源代码管理选 Git,Repository URL 填写你 Gitlab 上源码 Repo 的地址,Credentials 是拉取代码时需要用到的身份认证(如果你的Repo 不是公有的,没有身份认证就会报错)。

点击 Add 添加一个, Kind 选择 “Username with password”,输入 Gitlab 账号密码。

然后 Credentials 选择我们刚刚添加的(检测到账号密码正确就不会报错了),我们准备对 master 分支的代码做持续集成,所以 “Branches to build” 填 “*/master”。

构建触发器选择 “Build when a change is pushed to GitLab” (后面的 URL 是我们需要在 Gitlab 上配的 Webhook 地址),按照下面勾选。

点开高级,“Allowd branches” 勾选 “Filter branches by regex”,填写 “master”。点 “Generate” 生成 Token,这个 Token 用于填写到 Gitlab 的 Webhook 里,Gitlab 检测到代码提交,会通知 Webhook 里填写的 Jenkins 生成的回掉 URL,并带上这个 Token,防止其它人触发 Jenkins 的持续集成。

注: 复制出 URL 和 Token,我们后面配置 Gitlab 的 Webhook 会用到。

增加构建步骤 “execute shell”。

由于我们把持续集成的操作都写到 build 脚本了,所以直接填写执行 ./build 就可以了。

最后点击保存,至此,Jenkins 的持续集成配置好了,还需要配置 Gitlab 的 Webhook,用于代码提交通知 Jenkins。

配置 Gitlab Webhook

打开 Gitlab 的 Repo 的 Settings-Integrations。

URL 和 Secret Token 填写 Jenkins 项目中构建触发器部分生成的,点击 “Add webhook”,搞定!

测试

现在我们可以提交代码测试一下。

1
2
3
$ git add .
$ git commit -m "test"
$ git push

我们可以看 Jenkins 的输出来看是否触发任务,由于我使用了一些 Docker Hub 的镜像来编译代码和镜像,如果没有提前 Pull 下来,第一次运行任务可能会比较久,等待运行结束,刷新 Jenkins 主页。

如果运行成功,从 “上次成功” 下拉选择 “控制台输出”

可以看到运行任务过程的输出。

如果都没问题,你可以看看你的镜像仓库,镜像已经成功上传,至此,这个简单的持续集成搭建完毕。

附录

Git Submodule

如果你的项目里面还引用了其它项目,也就是 Git 的 Submodules,怎么办?甚至 Submodule 里面还要指定分支呢?

在创建 Jenkins 项目的时候,在 源码管理-Git-Additional Behaviours-Add 选择 Advanced sub-modules behaviours。

勾选下面两个选项。

Submodules 的分支靠 Git 本来支持的 .gitmodules 文件来控制,用法举例:

1
$ git submodule add -b v1 https://github.com/imroc/req.git ref/req

查看 .gitmodules 文件格式:

1
2
3
4
5
$ cat .gitmodules
[submodule "ref/req"]
path = ref/req
url = https://github.com/imroc/req.git
branch = v1

可以自己手动编辑或用 git submodule add 命令生成。

本文转载自:「I’m roc Blog」,原文:http://t.cn/AiWDsnzq,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com