Gitlab的CI/CD[1]是通过Gitlab runner执行器实现的,它作为执行器运行我们在.gitlab-ci.yml
中定义的一些逻辑行为。前面三篇讲述的是Gitlab的安装、通过一个flask web
框架服务进行代码兼容性检查、编译、部署的整个pipeline.
此处,介绍一下通过Gitlab的template实现类似如Jenkins share library[2]的功能。Gitlab template
将一些CICD
中共有的方法提取出来作为一个公共的模块提供给其他的需要的项目使用,这些原理与Github Action
里面的uses
指令类似,不了解Gitlab Action
的同学如果想学习基础并快速上手的可以参考官方Github Action使用文档[3]
在当前项目引入其他的构建模块你需要了解file
,template
,remote
,extends
这些pipeline语法的支持:
当前项目的.gitlab-ci.yml
可以从另一个项目下引入
include:
- project: DevOpsTeam/cicdtemplate
ref: master
file: '.gitlab-ci.yml'
template
只能使用官方提供的模板[4],你可以在此地址仓库下查看更多的使用细节;如果你对template还是不太熟悉,你可以参考template官方文档[5]
image-20200606202508256
用于通过http/https
类似的schema包含来自其他位置可以公开访问的文件,
include:
- remote: 'https://gitlab.kubemaster.top/DevOpsTeam/cicdtemplate/blob/master/.gitlab-ci-speedtest.yml'
继承同一文件上的模板 jobs
.tests:
script: rake test
stage: test
only:
refs:
- branches
rspec:
extends: .tests
script: rake rspec
only:
variables:
- $RSPEC
现在我们准备一个.git
仓库作为GitLab Runner的模板仓库,这里假定为https://gitlab.kubemaster.top/DevOpsTeam/cicdtemplate
,然后在仓库中创建两个目录,分别为jobs
,templates
,其中jobs目录内包含build
,test
,deploy
模块,template里面的包含不同语言相关的逻辑行为定义,比如整个CICD的过程的书顺序是如何执行,先执行哪一部分,后执行哪一部分。此处以BASH
方式为主,分享一下如何通过Gitlab runner执行基于BASH命令执行的持续构建和发布。
首选在templates目录下创建一个bash-pipeline.yml
的文件,在里面定义CICD的逻辑行为:
image: busybox:latest
include:
- project: 'DevOpsTeam/cicdtemplate'
ref: master
file: '/jobs/build.yml' # 引入构建阶段单元模块的操作
- project: 'DevOpsTeam/cicdtemplate'
ref: master
file: '/jobs/test.yml' # 引入测试阶段单元模块的操作
- project: 'DevOpsTeam/cicdtemplate'
ref: master
file: '/jobs/deploy.yml' # 引入部署阶段的单元模块的操作
stages: # 模板中定义如何通过
- build
- buildimage
- deploy-qa
- test
- deploy-prod
before_script: # 定义在每个job执行前先要执行的命令
- $GLOBAL_BEFORE_SCRIPT # 这里是从调用该文件的.gitlab-ci.yml中传递过来的变量
after_script: # 定义在每个job执行完后要执行的命令
- echo "这是在bash-pipeline.yml模板中的after_script"
- $GLOBAL_AFTER_SCRIPT
在构建阶段单元模块做的内容为: jobs/build.yml
before_script: # 将无密clone代码的私钥存在ssh-agent内
- "which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )"
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
build:
stage: build
tags:
- DevOpsTeam
script: # 构建阶段执行的命令
- $BUILD_SHELL
build-docker: # 构建镜像阶段的行为
stage: buildimage
tags:
- DevOpsTeam
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWD $CI_REGISTRY
- docker build -t ${IMAGE_NAME} -f ./Dockerfile .
- docker push ${IMAGE_NAME}
- docker rmi ${IMAGE_NAME}
在测试阶段单元模块做的内容: jobs/test.yml
test:
stage: test
tags:
- DevOpsTeam
script:
- $TEST_SHELL
# artifacts:
# reports:
# junit: ${JUNIT_REPORT_PATH}
when: on_success
helthcheck:
stage: test
retry: 2
tags:
- DevOpsTeam
script: |
if [ $HEALTH_CHECK_URL ];then
curl -I -m 2 -o /dev/null -s -w %{http_code}"\n" $HEALTH_CHECK_URL
else
echo
fi
when: on_success
在部署阶段单元模块做的内容: jobs/deploy.yml
variables:
SSH: "ssh -i ${SSH_SUOPER_KEY} -o StrictHostKeyChecking=no"
deploy-qa:
stage: deploy-qa
tags:
- DevOpsTeam
script: | # 对于多机器部署的时候,可以通过该方式进行。也可以引入ansible工具部署
for server in ${DEPLOY_HOST_QA};do
$SSH marionxue@${server} docker pull $IMAGE_NAME && docker stop $CI_PROJECT_NAME > /dev/null 2>&1 && docker rm $CI_PROJECT_NAME > /dev/null 2>&1 || true
$SSH marionxue@${server} ${DEPLOY_SHELL}
done
when: on_success
deploy-prod:
stage: deploy-prod
tags:
- DevOpsTeam
script: |
for server in ${DEPLOY_HOST_PROD};do
$SSH marionxue@${server} docker pull $IMAGE_NAME && docker stop $CI_PROJECT_NAME > /dev/null 2>&1 && docker rm $CI_PROJECT_NAME > /dev/null 2>&1 || true
$SSH marionxue@${server} ${DEPLOY_SHELL}
done
only:
- master
when: manual
最后,我们只需要在.gitlab-ci.yml
中引入templates/bash-pipeline.yml
然后配置上对应的环境变量就可以了: .gitlab-ci.yml
include:
- project: "DevOpsTeam/cicdtemplate" # 引入模板文件
ref: master
file: "/templates/bash-pipeline.yml"
variables:
BUILD_SHELL: |
echo "shell command in build stage and the command is received from .gitlab-ci.yml BUILD_SHELL"
TEST_SHELL: |
echo "run shell command in test stage and the command is received from .gitlab-ci.yml TEST_SHELL"
IMAGE_NAME: "registry-vpc.cn-beijing.aliyuncs.com/xingshulin/${CI_PROJECT_NAME}:${CI_COMMIT_BRANCH}.${CI_COMMIT_SHA}"
GLOBAL_BEFORE_SCRIPT: "echo 喜欢就关注【云原生生态圈】吧!"
GLOBAL_AFTER_SCRIPT: "echo hello,这里是从.gitlab-ci.yml里面传递来的after_script命令,【在每个job之后运行】"
DEPLOY_SHELL: ""
DEPLOY_HOST_QA: "192.168.99.129 192.168.99.130"
DEPLOY_HOST_PROD: "192.168.99.131"
HEALTH_CHECK_URL: ""
使用模板的好处就是我们可以直接通过这样的案例快速的完成其他项目的配置和使用,而不需要开发和其他人员过多的学习gitlab runner的学习成本,能快速的高效率引入和使用。下面我们配置一个简单的Dockerfile
来看一下运行一下使用template的gitlab pipeline的效果:Dockerfile
FROM busybox:latest
MAINTAINER 云原生生态圈 <marionxue@kubemaster.top>
下面我们看一下目录结构:cicdtemplate
☸️ devcluster? kube-ops ~/workspaces/cicdtemplate master ● ? ? tree -a -L 2
.
├── .git
│ ├── ...
├── .gitlab-ci.yml
├── Dockerfile
├── README.md
├── jobs
│ ├── build.yml
│ ├── deploy.yml
│ └── test.yml
└── templates
├── README.md
├── bash-pipeline.yml
然后提交到代码仓库,pipeline即可自动的运行了,我们看一下效果图:
到这里我们就完成了基于远程模板实现的gitlab pipeline的使用。
[1]
Gitlab的CI/CD: https://docs.gitlab.com/ee/ci/
[2]
Jenkins share library Docs: https://www.jenkins.io/doc/book/pipeline/shared-libraries/
[3]
Github Action Docs: https://help.github.com/cn/actions
[4]
GitLab官方的templates地址: https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates
[5]
官方template使用文档: https://docs.gitlab.com/ee/ci/yaml/#includetemplate