cicd 01--构建通用的CI流程
cicd 01--构建通用的CI流程1 介绍2 CI构建过程2.1 参数配置说明2.2 pipeline 脚本2.3 测试流程3 注意事项4 说明1 介绍笔者在 docker笔记3–配置jenkins 和 k8s笔记7.3–基于gitlab、jenkins、helm、k8s的CI/CD 中介绍了jenkins的安装和基于helm 的k8s 流程。本文基于上述基础继续分享一个构建和发布镜像的通用je
cicd 01--构建通用的CI流程
1 介绍
笔者在 docker笔记3–配置jenkins 和 k8s笔记7.3–基于gitlab、jenkins、helm、k8s的CI/CD 中介绍了jenkins的安装和基于helm 的k8s 流程。本文基于上述基础继续分享一个构建和发布镜像的通用jenkins流程,以便于为企业中所有的服务实现镜像发布。
2 CI构建过程
本案例中涉及多种agent,比如普通的slave节点可以访问gitlab仓库,aliyun-build可以用来访问上传镜像,但是不能访问gitlab;因此需要通过多个节点协调操作,在slave节点上拉取镜像,然后拷贝到aliyun-build中,在build机器上build镜像并上传到仓库,最后在slave机器上给repo打一个tag。
本案例中为了实现一个通用的build流程,并没有为不同的镜像配置不同build环境,而是为其封装一个通用的build_docker.sh 脚本,用户按照需要改动即可。
若遇见不同的环境,例如A 镜像需要 java9、B镜像需要 java11 的打包环境,那么可以将其某个机器上build好生成可执行文件,然后在 build_docker.sh 中下载所需文件后再打包;也可以封装一个专用的build code的镜像,先运行该镜像build 可执行文件,然后再继续生成的文件build 处生产环境所需的镜像。
2.1 参数配置说明
- 拉取指定gitlab repo 代码
对应参数:gitlab_repo (sre设置为下拉选项目) - 切换到指定的分支
对应参数:branch_name (用户自填) - 确定镜像版本号, 格式最好为yyyymmddvx(x为具体数字,例如 20210814v1)
对应参数:image_version (用户自填) - 确定dockerhub仓库后缀, 格式为命名空间/仓库名称(例如 yourNamespace/xg_nginx)
对应参数:dockerhub_repo (用户自填) - 通过该分支根目录下的 build_docker.sh 和 Dockerfile 来构建镜像,并将镜像推送到对应的dockerhub中
build_docker.sh 案例
以下为build_docker.sh 案例,每个分支都要参考该方法写一个 build_docker.sh, 并确保执行 bash build_docker.sh dockerhub_repo image_version 后能正常推送到docker仓库
#!/bin/bash
docker_image_name=xg_nginx # 需要将此处的xg_nginx 替换为dockerhub_repo 中的后缀
function usage() {
cat <<_EOF
usage:
bash build_docker.sh -h|--help|dockerhub_repo image_version
for example, bash build_docker.sh yourNamespace/xg_nginx 20210816v1
_EOF
}
function build_docker() {
docker build -t $docker_image_name:$2 .
if [ $? -eq 0 ]; then
echo "build_docker $docker_image_name:$2, success"
else
echo "build_docker $docker_image_name:$2, failed"
exit 1
fi
docker tag $docker_image_name:$2 registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
if [ $? -eq 0 ]; then
echo "tag $docker_image_name:$2, success"
else
echo "tag $docker_image_name:$2, failed"
exit 1
fi
docker push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
if [ $? -eq 0 ]; then
echo "push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2, success"
else
echo "push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2, failed"
exit 1
fi
docker rmi $docker_image_name:$2
docker rmi registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
}
case "$1" in
-h)
usage
;;
--help)
usage
;;
*)
build_docker $1 $2
;;
esac
2.2 pipeline 脚本
gitlab_repo = "${params.gitlab_repo}"
def split = gitlab_repo.split("/")
def repo_name = split[1]
branch_name = "${params.branch_name}"
image_version = "${params.image_version}"
dockerhub_repo = "${params.dockerhub_repo}"
repo_url = "git@gitlab.yourCompany.com:${gitlab_repo}.git"
println("gitlab_repogitlab_repo branch=${gitlab_repo} ${branch_name}")
println("repo_name=${repo_name}, image_version=${image_version}")
println("dockerhub_repo=${dockerhub_repo}")
default_description = "${gitlab_repo} ${branch_name}:${image_version}"
currentBuild.description = "${default_description}"
pipeline {
agent any
environment {
repo_name1 = "${repo_name}"
}
stages {
stage('Clean workspace') {
agent {
node {
label 'aliyun-build'
}
}
steps {
sh """
rm -rf /nas/jenkins/sre_workspace/build_docker_sre/\${repo_name1}_\${branch_name} || true
"""
}
}
stage("Clone Repo"){
agent {
node {
label 'slave'
}
}
steps {
deleteDir()
dir("${repo_name1}_${branch_name}"){
git(
url: "${repo_url}",
credentialsId: '73d3xxxx-xxxx-xxxx-xxxx-xxxxxxxx9274',
branch: "${branch_name}"
)
}
}
}
stage('Scp to aliyun-build') {
agent {
node {
label 'slave'
}
}
steps {
sh """
pwd
scp -r \${repo_name1}_\${branch_name} aliyun-build:/nas/jenkins/sre_workspace/build_docker_sre/
if [ \$? -ne 0 ]
then
echo "Found some error when copy the repo"
fi
"""
}
}
stage('Build docker images') {
agent {
node {
label 'aliyun-build'
}
}
steps {
sh """
cd /nas/jenkins/sre_workspace/build_docker_sre/\${repo_name1}_\${branch_name}/
if [ ! -f Dockerfile ]
then
echo "No available dockerfile in workspace"
fi
if [ ! -f build_docker.sh ]
then
echo "No available build_docker.sh in workspace"
fi
bash build_docker.sh \${dockerhub_repo} \${image_version}
pwd
ls
"""
}
}
stage('Set tag') {
agent {
node {
label 'slave'
}
}
steps {
dir("${repo_name1}_${branch_name}"){
sh """
git tag -m "Build docker image ${image_version} for ${branch_name}/${image_version}" \${branch_name}/\${image_version}
git describe
git push origin \${branch_name}/\${image_version}
"""
}
}
}
}
post {
always {
echo 'I have finished'
}
success {
echo "build ${gitlab_repo} ${branch_name}:${image_version}, succeed!"
sh """
curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"build_docker_sre notify: ${gitlab_repo} ${branch_name}:${image_version}, succeed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/6caa4463-xxxx-xxxx-xxxx-89ac0e9e39c8
"""
}
failure {
echo "build ${gitlab_repo} ${branch_name}:${image_version}, failed!"
sh """
curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"build_docker_sre notify: ${gitlab_repo} ${branch_name}:${image_version}, failed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/6caa4463-xxxx-xxxx-xxxx-89ac0e9e39c8
"""
}
}
}
2.3 测试流程
jenkins 执行参数如下:
执行结果如下:
3 注意事项
- 涉及多个不同节点的时候需要配置不同节点的访问权限,也要配置 jenkins 拉取 gitlab 的权限。
4 说明
软件环境:
jenkins 版本:2.299
参考文档:
jenkins 官方文档
更多推荐
所有评论(0)