Gitlab动态子流水线实践

开发
本文是一个小型的技术分享,内容涉及Gitlab动态子流水线、Gitlab流水线模板、Shell脚本处理文件等。

Gitlab动态子流水线

Gitlab的多项目流水线支持由一个项目的流水线触发另一个项目的流水线,并可以在一个可视化整个流水线及流水线间的相互依赖关系,解决了项目间协同的问题。

Gitlab从12.7版本开始引入了父子流水线特性,在12.9版本引入动态子流水线特性。子流水线可以根据阶段顺序自由地执行,不用等待父流水线不相干的工作,配置被拆分得更小,减少了理解整体配置的认知负担,同时由于导入在子流水线完成,也减少了命名空间冲突的可能,界面体验也有改善。

Gitlab动态子流水线实践

Gitlab子流水线

项目背景

项目组有一个专门用于生成自定义容器镜像的Gitlab项目,该项目下很多目录,每个目录对应于一种自定义镜像,目录下有Dockerfile及相关文件,通过运行目录下的名称类似buildXXX.sh这样的脚本来构建和上传镜像。

为了有一个具备权威性、稳定性、方便性的地方来构建这些镜像,想到了利用Gitlab动态子流水线的特性,通过搜索项目里所有镜像构建shell脚本文件,并提取脚本里的镜像名称和标签,再生成以各镜像名称和标签命名的动态步骤,最后由人员手动触发构建镜像。

这可能不是一个很好的方案,比如会生成很多并不需要的Job、没有全部自动化、缺少对镜像间依赖关系的处理等,但也不失为一种思路,而且这些问题也可以通过进一步分析Dockerfile之间的关系、本次变更涉及的文件等优化解决,下面两张图为最终呈现的效果。

Gitlab动态子流水线实践

流水线

Gitlab动态子流水线实践

Job列表

整体结构

父流水线和Gitlab官网提供的案例一样,由generate-config、child-pipeline两个Job(名称可自定)构成,前一个名为generate-config的Job会生成名为generated-config.yml的Gitlab流水线定义文件,该文件包含了需要动态运行的Job,通过artifacts机制传递给后续名为child-pipeline的Job,并触发它。

为了演示清楚,生成generated-config.yml文件Shell脚本在下面的代码中暂时省略掉了,下文将补上。

stages:
- prepare
- image

generate-config:
stage: prepare
script:
- 这里会生成generated-config.yml,暂时省略
artifacts:
paths:
- generated-config.yml

child-pipeline:
stage: image
trigger:
include:
- artifact: generated-config.yml
job: generate-config

模板

由于动态生成的每个Job的定义都是一样的,所以在生成的generated-config.yml中利用Gitlab流水线模板机制定义了一个Job模板,以复用和精简代码。

下面的代码片段来自generated-config.yml文件的最前面部分,我们可以看到定义了一个名为build_image的模板,该模板定义的job将手动触发,并启动一个带有docker、oc命令的镜像来运行构建脚本,构建脚本中首先为脚本授予执行权限,然后进入脚本所在目录,最后运行该脚本。具体脚本文件将由SCRIPT_PATH变量在每个具体Job中提供,比如从第11行开始的名为redis-cluster:5.0.7-ocp的job,引入了build_image模板,提供了SCRIPT_PATH变量的值。

.job_template: &build_image
stage: build
when: manual
image: nexus.yourcompany.com/tools/docker-18.09.7/oc:4.6.21
script:
- chmod +x ${SCRIPT_PATH}
- cd ${SCRIPT_PATH%/*}
- /bin/sh ./${SCRIPT_PATH##*/}


redis-cluster:5.0.7-ocp:
variables:
SCRIPT_PATH: /tmp/TBzsZA42/0/docker-images/redis-cluster/build-openshift.sh
<<: *build_image

生成配置

在生成动态子流水线的脚本中,首先生成模板部分,创建并输出到文件。

generate-config:
stage: prepare
script:
- |-
echo -e "
.job_template: &build_image
stage: build
when: manual
image: nexus.yourcompany.com/tools/docker-18.09.7/oc:4.6.21
script:
- chmod +x \${SCRIPT_PATH}
- cd \${SCRIPT_PATH%/*}
- /bin/sh ./\${SCRIPT_PATH##*/}

" > generated-config.yml

加下来生成每个Job,依次为查找build*.sh文件、搜索docker push并提取镜像名称和Tag、改为用制表符分割为两列、遍历每行并读取到file和image遍历、在循环中用echo命令append到文件。

generate-config:
stage: prepare
script:
- 生成模板的脚本
- |-
find -iname 'build*.sh' \
| xargs grep -ios ".*docker\s*push\s*.*/[^/\\\$]*" \
| sed 's|\.sh:|.sh\t|g' \
| sed -e 's|\([^\t]*\)\t.*\/\([^\/]*\)|\1\t\2|g' \
| while read file image; do SCRIPT_PATH="$CI_PROJECT_DIR${file:1}"; \
echo -e "
$image:
variables:
SCRIPT_PATH: "${SCRIPT_PATH}"
<<: *build_image
" \
>> generated-config.yml ; \
done

下面是生成的generated-config.yml片段。

.job_template: &build_image
stage: build
when: manual
image: nexus.yourcompany.com/tools/docker-18.09.7/oc:4.6.21
script:
- chmod +x ${SCRIPT_PATH}
- cd ${SCRIPT_PATH%/*}
- /bin/sh ./${SCRIPT_PATH##*/}



redis-cluster:5.0.7-ocp:
variables:
SCRIPT_PATH: /tmp/TBzsZA42/0/docker-images/redis-cluster/build-openshift.sh
<<: *build_image


redis-cluster:5.0.7:
variables:
SCRIPT_PATH: /tmp/TBzsZA42/0/docker-images/redis-cluster/build.sh
<<: *build_image

完整定义

下面是完整的项目流水线定义:

stages:
- prepare
- image

generate-config:
stage: prepare
script:
- |-
echo -e "
.job_template: &build_image
stage: build
when: manual
image: nexus.yourcompany.com/tools/docker-18.09.7/oc:4.6.21
script:
- chmod +x \${SCRIPT_PATH}
- cd \${SCRIPT_PATH%/*}
- /bin/sh ./\${SCRIPT_PATH##*/}

" > generated-config.yml
- |-
find -iname 'build*.sh' \
| xargs grep -ios ".*docker\s*push\s*.*/[^/\\\$]*" \
| sed 's|\.sh:|.sh\t|g' \
| sed -e 's|\([^\t]*\)\t.*\/\([^\/]*\)|\1\t\2|g' \
| while read file image; do SCRIPT_PATH="$CI_PROJECT_DIR${file:1}"; \
echo -e "
$image:
variables:
SCRIPT_PATH: "${SCRIPT_PATH}"
<<: *build_image
" \
>> generated-config.yml ; \
done
artifacts:
paths:
- generated-config.yml

child-pipeline:
stage: image
trigger:
include:
- artifact: generated-config.yml
job: generate-config
责任编辑:赵宁宁 来源: 今日头条
相关推荐

2021-04-29 08:55:54

GitLabDevOps项目

2023-08-18 10:24:52

GitLabCI 流水线

2024-01-07 12:47:35

Golang流水线设计模式

2017-03-02 14:12:13

流水线代码Clojure

2021-12-24 08:02:48

GitLabCI模板库流水线优化

2023-12-11 18:35:37

测试流水线自动化

2017-02-28 16:00:45

DevOpsMarkdownreST

2023-05-10 15:08:00

Pipeline设计模式

2013-06-06 09:31:52

2017-02-28 15:40:30

Docker流水线Azure

2021-11-08 07:41:16

Go流水线编程

2020-10-25 11:28:12

开源端到端流水线

2022-01-26 08:12:42

Jenkins开源流水线

2021-06-26 14:22:34

Tekton流水线Kubernetes

2021-06-28 06:32:46

Tekton Kubernetes Clone

2021-06-18 05:48:02

Tekton DevopsKubernetes

2023-09-27 08:24:49

2018-10-23 16:35:19

华为云

2012-04-19 11:44:52

iPhone

2021-01-05 08:39:51

容器前端流水线
点赞
收藏

51CTO技术栈公众号