DI/CD实现持续集成与交付
实现持续集成与交付主要分为五个步骤:配置 GitLab SSH 访问公钥,使得我们可以直接通过 SSH 拉取或推送代码到 GitLab。将代码通过 SSH 上传到 GitLab。在 Jenkins 创建构建任务,使得 Jenkins 可以成功拉取 GitLab 的代码并进行构建。配置代码变更自动构建流程,使得代码变更可以触发自动构建 Docker 镜像。配置自动部署流程,使得镜像构建完成后自动将镜
实现持续集成与交付主要分为五个步骤:
- 配置 GitLab SSH 访问公钥,使得我们可以直接通过 SSH 拉取或推送代码到 GitLab。
- 将代码通过 SSH 上传到 GitLab。
- 在 Jenkins 创建构建任务,使得 Jenkins 可以成功拉取 GitLab 的代码并进行构建。
- 配置代码变更自动构建流程,使得代码变更可以触发自动构建 Docker 镜像。
- 配置自动部署流程,使得镜像构建完成后自动将镜像发布到测试或生产环境。
一、配置 GitLab SSH 访问公钥,上传代码至Gitlab
在gitlab中创建工程hello-jenkins
为了能够从gitlab上传/下载代码,我们需要先生成 ssh 密钥。我们可以本地使用 ssh-keygen 命令来生成 2048 位的 ras 密钥。如下命令:
ssh-keygen -o -t rsa -b 2048 -C "email@example.com" #邮箱替换为自己的邮箱
按三次回车,使用默认的公钥/秘钥保存路径,以及不设置秘钥密码
执行完上述命令后 ,$HOME/.ssh/ 目录下会自动生成两个文件:id_rsa.pub 文件为公钥文件,id_rsa 文件为私钥文件
我们可以通过 cat 命令来查看公钥文件内容:
cat $HOME/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADASDBAAABAQClnVao+34t6CEWawIpYZQK6NmMcNDZGUYG0Op3B2abkqQpC5X8QKaFs5Jksw2KXc3D80FUHrDb6Nk3c/0Ueqcz30aCIzfUJ3Wi7MSlhaJtfrNC4T80ze5HyqP+ut60j05OaSJf34ew0XZ4WUNJGqu1NQczbX4FXLq/Hwc/vueVYSXMt3ZCq4AKF2foLx/Qilxv6wk4uev7oiVTxxHASCthY83WL2WNjFUF4IqW5Fm+wpjxe3PccIjyi71S/S05b9wOP9dD87vPe18GaHqti3ittOc9x62ossyv0FJjd8VPn1M/N7TPfNVfrZmLVkilPNRj2m3NaZ9a9D/t1A/6U0// email@example.com
然后将公钥文件拷贝到 GitLab 的个人设置 -> SSH Keys 中,点击添加按钮,将我们的公钥添加到 GitLab 中
二、将代码通过 SSH 上传到 GitLab
在本地创建一个名为hello-jenkins的文件夹
创建如下四个文件
-
main.go(不熟悉go语言的可以试用其他项目代码代替)
package main import ( "fmt" "net/http" ) func hello(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "hello\n") } func headers(w http.ResponseWriter, req *http.Request) { for name, headers := range req.Header { for _, h := range headers { fmt.Fprintf(w, "%v: %v\n", name, h) } } } func main() { http.HandleFunc("/hello", hello) http.HandleFunc("/headers", headers) http.ListenAndServe(":9090", nil) }
-
Dockerfile
FROM golang:1.14 as builder WORKDIR /root/projects/jenkins/ COPY main.go . RUN CGO_ENABLED=0 GOOS=linux go build -o ./http-server . FROM scratch WORKDIR /root/projects COPY --from=builder /root/projects/jenkins/http-server . CMD ["./http-server"]
-
.gitignore(非必须,使用idea编辑项目会产生.idea文件夹)
.idea/
-
README.md(非必须)
Docker+Gitlab+Jenkins CI/CD Demo.
执行以下命令将代码上传至Gitlab:
git init #创建本地git仓库
git add . #将工作区代码存到暂存区
git commit -m 'Init hello-jenkins' #将代码提交到本地仓库
git add remote origin git@ip:xxx.git #与远程仓库关联
git push --set-upstream origin master #将代码推送到远程仓库
三、在 Jenkins 创建构建任务
- 同时,参照步骤二在jenkins服务器生成公钥和私钥
在 Jenkins 中添加一个自由风格的任务
源码管理选择 Git,填写 GitLab 项目的 URL,Jenkins 会提示没有访问 GitLab 的相关权限,点击添加按钮将jenkins服务器私钥添加到 Jenkins 中
选择添加的密钥类型为 “SSH Username with private key”,Username 设置为 jenkins,然后将jenkins服务器私钥粘贴到 Private Key 输入框中,点击添加即可
同时需要把jenkins服务器公钥添加到gitlab SSH KEYS配置中
返回页面中选择刚刚添加的jenkins凭证
下面我们使用 shell 脚本来构建我们的应用镜像,在构建中增加一个 Shell 类型的构建步骤
填入以下信息:
# 第一步,登录镜像仓库,将 USER 替换为目标镜像仓库的用户名,将 PASSWORD 替换为镜像仓库的密码
docker login -u {USER} -p {PASSWORD}
# 第二步,使用 docker build 命令构建镜像(我这里镜像名为ntherd-docker/devops-demo)
docker build -t {USER}/devops-demo .
# 第三步, 使用 docker push 命令推送镜像
docker push {USER}/devops-demo
完成后点击保存,此时任务已经成功添加到 Jenkins 中。回到任务首页,点击构建按钮即可开始构建。第一次构建需要下载依赖的基础镜像,这个过程可能比较慢。构建过程中,我们也可以点击控制台输出查看构建输出的内容。
四、配置代码变更自动构建流程
点击上一步创建的任务,点击配置进入任务配置界面,到构建触发器下勾选 GitLab 相关的选项(如果没有此选项,检查一下是否安装了gitlab相关插件),点击 Generate 按钮生成一个 GitLab 回调 Jenkins 的 token。记录下 Jenkins 的回调地址和生成的 token 信息。
在 GitLab 项目设置中,选择 Webhooks,将 Jenkins 的回调地址和 token 信息添加到 Webhooks 的配置中,点击添加即可
后面我们的每次提交都会触发自动构建。
为了实现根据 git 的 tag 自动构建相应版本的镜像,我们需要修改 Jenkins 构建步骤中的 shell 脚本为以下内容:
# 需要推送的镜像名称
IMAGE_NAME="{USER}/devops-demo"
# 获取当前构建的版本号
TAG=`git describe --always --tag`
# 生成完整的镜像 URL 变量,用于构建和推送镜像
REPOSITORY=docker.io/${IMAGE_NAME}:${TAG}
# 构建Docker镜像
docker build -t $REPOSITORY -f Dockerfile .
# 登录镜像仓库,username 跟 password 为目标镜像仓库的用户名和密码
docker login --username={USER} --password={PASSWORD} docker.io
# 推送 Docker 镜像到目标镜像仓库
docker push $REPOSITORY
到此,我们已经完成了 GitLab -> Jenkins -> Docker 镜像仓库的自动构建和推送。当我们推送代码到 GitLab 中时,会自动触发 Webhooks,然后 GitLab 会根据配置的 Webhooks 调用 Jenkins 开始构建镜像,镜像构建完成后自动将镜像上传到我们的镜像仓库。
五、配置自动部署流程
镜像构建完成后,我们还需要将镜像发布到测试或生产环境中将镜像运行起来。发布到环境的过程可以设置为自动发布,每当我们推送代码到 master 中时,即开始自动构建镜像,并将构建后的镜像发布到测试环境中。
在镜像构建过程中,实际上 Jenkins 是通过执行我们编写的 shell 脚本完成的,要想实现镜像构建完成后自动在远程服务器上运行最新的镜像,我们需要借助一个 Jenkins 插件 Publish Over SSH,这个插件可以帮助我们自动登录远程服务器,并执行一段脚本将我们的服务启动。
下面我们来实际操作下这个插件。
第一步,在 Jenkins 中安装 Publish Over SSH 插件。 在 Jenkins 系统管理,插件管理中,搜索 Publish Over SSH,然后点击安装并重启 Jenkins 服务。
第二步,配置 Publish Over SSH 插件。 插件安装完成后,在 Jenkins 系统管理的系统配置下,找到 Publish Over SSH 功能模块,添加远程服务器节点,这里我使用密码验证的方式添加一台服务器。配置好后,我们可以使用测试按钮测试服务器是否可以正常连接,显示Success 代表服务器可以正常连接,测试连接成功后,点击保存按钮保存配置。
第三步,修改之前 shell 任务中脚本, 添加部署相关的内容:
# 需要推送的镜像名称
IMAGE_NAME="{USER}/devops-demo"
# 获取当前构建的版本号
TAG=`git describe --always --tag`
# 生成完整的镜像 URL 变量,用于构建和推送镜像
REPOSITORY=docker.io/${IMAGE_NAME}:${TAG}
# 构建Docker镜像
docker build -t $REPOSITORY -f Dockerfile .
# 登录镜像仓库,username 跟 password 为目标镜像仓库的用户名和密码
docker login --username={USER} --password={PASSWORD} docker.io
# 推送 Docker 镜像到目标镜像仓库
docker push $REPOSITORY
mkdir -p ./shell && echo \
"docker login --username={USER} --password={PASSWORD} \n" \
"docker pull $REPOSITORY \n" \
"docker kill hello-jenkins \n" \
"docker run --rm --name=hello-jenkins -p 8090:8090 -d $REPOSITORY" >> ./shell/release
我们在 docker push 命令后,增加一个输出 shell 脚本到 release 文件的命令,这个脚本会发送到远端的服务器上并执行,通过执行这个脚本文件可以在远端服务器上,拉取最新镜像并且重新启动容器。
第四步,配置远程执行。在 Jenkins 的 hello-jenkins 项目中,点击配置,在构建中增加构建步骤,点击添加Send files or execute commands over SSH的步骤,选择之前添加的服务器,并且按照以下内容填写相关信息:
- Source file 就是我们要传递的 shell 脚本信息,这里填写我们上面生成的 shell 脚本文件即可。
- Remove prefix 是需要过滤的目录,这里我们填写 shell。
- Remote directory 为远程执行脚本的目录。
最后点击保存,配置完成后,我们就完成了推送代码到 GitLab,Jenkins 自动构建镜像,之后推送镜像到镜像仓库,最后自动在远程服务器上拉取并重新部署容器。
如果你是生产环境中使用的 Kubernetes 管理服务,可以在 Jenkins 中安装 Kubernetes 的插件,然后构建完成后直接发布镜像到 Kubernetes 集群中。
更多推荐
所有评论(0)