gitlab ci + k8s(kubesphere) + springcloud微服务部署及使用经验
使用gitlab ci发布springboot 项目到k8s环境实践
1. 总览
关键字: k8s, gitlab, kubesphere, kubenetes, springboot, springcloud, .gitlab-ci.yml, minio
1.1 服务版本信息
| 服务名 | 版本 | 备注 |
|---|---|---|
| gitlab | GitLab Community Edition 11.3.5 | 公司自建服务,非k8s体系 |
| kubesphere | v3.3.2 | |
| kubernetes | v1.23.10 | 使用kubesphere搭建k8s服务 |
| minio | RELEASE.2023-09-30T07-02-29Z | 使用helm部署, 作为gitlab ci的外部缓存; 可以不使用minio,使用gilab ci自带缓存也可以 |
| registry | - | 使用阿里云镜像库个人版,可以用harbor等私有部署代替 |
1.2 CI/CD流程图

此流程图是一个简易的流程示意图, 包含两个stage build和deploy, 每个stage中分别包含一个job,因此会触发初始化两个临时pod容器组
- 本地git推送到远程git服务器, 通过服务通过识别根目录的 .gitlab-ci.yml 决定是否启动gitlab ci流程
- 成功判断根目录 .gitlab-ci.yml 文件后, 通过only条件(分支,标签,表达式等)初步判断需要运行的job
- 将需要执行的job信息发送至k8s runner, 进行初始化执行pod调度
- 将环境变量,挂载卷, 挂载configmap信息传递到执行器pod进行初始化,进行【build】构建流程
- 构建结束后若job配置cache信息,会将指定目录cache存储到minio服务
- 完成构建会销毁pod, 需要传递到下一个job 执行器pod的内容需要通过cache缓存或者artifact制品进行传递,注意: 无法通过环境变量值变更传递到下一个pod
- build流程执行完毕, runner会调度执行初始化下一个【deploy】流程pod, 注意这里与步骤4一样, 会新启动一个新的pods容器组
- 若此job中配置了cache同时 cache:key与【build】job中相同, 则会从minio中拉取拉取缓存
- 同5一样,若执行无错误, 流程完成, 执行结果为pass,runner调度流程结束,构建流程及日志会同步在gitlab ci 中展示。
2. 需求及目标
2.1 需求
2.1.1 一句话需求
能够使用gitlab ci流程完成springboot项目前后端的持续集成及持续部署
2.1.2 具体需求
- 仅在merge_request到dev分支或push到dev分支时,触发构建流程
- springboot项目为微服务架构,存在多个子模块,均为独立部署的微服务,需要根据提交内容自动识别所在的模块并部署
- 多环境部署, 可以根据不同的分支,部署到不同的环境下
3. 实践流程
3.1 k8s(kubesphere) runner部署
3.1.1 runner分类
下图是官网对不同类型runner的能力描述,因为我们是k8s环境,因此我选择k8s类型runner

3.1.2 配置helm应用仓库

在企业空间页面,选择应用管理-应用仓库,点击添加

将gitlab chart库填入(https://charts.gitlab.io), 点击确定即可保存,
保存成功后即可在项目中新建gitlab应用

选择gitlab-runner应用,版本影响不大, 我的gitlab是11, 选取最新16.4.1安装也没有事
接下来是很重要的应用设置文件,下面的应用配置是我的个人应用配置
image:
registry: registry.gitlab.com
image: gitlab-org/gitlab-runner
useTini: false
imagePullPolicy: IfNotPresent
gitlabUrl: 'https://git.xxx.cn'
image_pull_secrets:
1. 'aliyun-hangzhou-reg'
runnerRegistrationToken: "sdfsdfsdf"
terminationGracePeriodSeconds: 3600
privileged: true
concurrent: 10
checkInterval: 30
sessionServer:
enabled: false
rbac:
create: true
rules:
- resources:
- configmaps
- events
- pods
- pods/attach
- pods/exec
- secrets
- services
verbs:
- get
- list
- watch
- create
- patch
- update
- delete
- apiGroups:
- ''
resources:
- pods/exec
verbs:
- create
- patch
- delete
clusterWideAccess: false
serviceAccountName: lit
podSecurityPolicy:
enabled: false
resourceNames:
- gitlab-runner
metrics:
enabled: false
portName: metrics
port: 9252
serviceMonitor:
enabled: false
service:
enabled: false
type: NodePort
runners:
config: |
[[runners]]
environment = ["REG_USER_NAME=", "REG_PASSWD="]
cache_dir = "/cache"
[runners.cache]
Type = "s3"
Path = "/cache"
Shared = false
[runners.cache.s3]
ServerAddress = "minio-w1hko6-svc:9000"
AccessKey = "minio"
SecretKey = "minio"
BucketName = "runners-cache"
BucketLocation = "cn-hb-wh-1"
Insecure = true
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "ubuntu:22.04"
[[runners.kubernetes.host_aliases]]
ip = "192.168.10.128"
hostnames = ["lb.kubesphere.local"]
[[runners.kubernetes.volumes.config_map]]
name = "runner-config"
mount_path = "/runner-config"
[[runners.kubernetes.volumes.pvc]]
name = "gitlab-runner-local-pvc"
mount_path = "/root/.m2/repository"
[[runners.kubernetes.volumes.host_path]]
name = "docker-sock"
mount_path = "/var/run/docker.sock"
host_path = "/var/run/docker.sock"
configPath: ''
cache: {}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
privileged: false
capabilities:
drop:
- ALL
podSecurityContext:
runAsUser: 100
fsGroup: 65533
resources: {}
affinity: {}
nodeSelector: {}
tolerations: []
hostAliases: []
deploymentAnnotations: {}
deploymentLabels: {}
podAnnotations: {}
podLabels: {}
priorityClassName: ''
secrets: []
configMaps: {}
volumeMounts:
- mountPath: /maven
name: volume-runner
volumes:
- name: volume-runner
persistentVolumeClaim:
claimName: gitlab-runner-local-pvc
- image: 这部分配置了GitLab Runner使用的容器镜像信息。它从registry.gitlab.com拉取gitlab-org/gitlab-runner的镜像。useTini设置为false,表示不使用Tini作为PID 1进程。imagePullPolicy 设置为 IfNotPresent,表示仅在本地不存在镜像时才拉取。
- gitlabUrl: 设置GitLab的URL为https://git.quadimodo.cn,这是GitLab实例的URL。
- image_pull_secrets: 这里列出了用于从私有镜像仓库拉取镜像的密钥。在这个配置中,使用名为’aliyun-hangzhou-reg’的密钥。这里使用的是k8s secrets配置名称
- runnerRegistrationToken: 这是GitLab Runner注册时需要提供的令牌。注1:这个参数在group或project的settings—CI/CD—Runners-Setup a specific Runner manually 中获取。注2:不同版本gitlab使用的参数可能不同,可能高级版本中使用的是runnerToken参数, 但是值是一样的。
- concurrent: 设置GitLab Runner 的并发任务数为10。
- rbac: 启用RBAC(Role-Based Access Control),为GitLab Runner创建相关的RBAC角色和服务帐户。同时指定了相应的权限规则。
- serviceAccountName: 设置GitLab Runner使用的服务帐户的名称为’lit’。是k8s配置的账户
- runners: 这个部分包含GitLab Runner的配置信息,包括运行环境,缓存设置,Kubernetes相关配置等。这个部分很重要,后面会单独详细讲解
- securityContext: 定义了容器的安全上下文,包括不允许提权,只读根文件系统,以及不以root用户身份运行容器。
- podSecurityContext: 设置了Pod的安全上下文,包括运行用户和文件系统组。
- volumeMounts 和 volumes: 定义了容器的挂载卷和卷的声明,用于将数据或配置文件挂载到容器中。此处其实可以不用挂载maven配置, 只是为了看下build pods 下载依赖包后的效果,才挂载到runner pods上
- 最后的几个部分(resources、affinity、nodeSelector、tolerations、hostAliases、deploymentAnnotations、deploymentLabels、podAnnotations、podLabels、priorityClassName、secrets、configMaps)都为空,表示没有为GitLab Runner配置任何资源限制、亲和性、节点选择、容忍度、主机别名、注释、标签等其他选项。
总的来说,这个配置文件用于在Kubernetes上部署GitLab Runner,并指定了一些安全性、并发性、挂载卷以及GitLab连接信息等方面的配置。根据需要,可以根据实际情况进行修改和自定义。
3.1.2.1 runner配置
runners:
config: |
[[runners]]
environment = ["REG_USER_NAME=", "REG_PASSWD="]
cache_dir = "/cache"
[runners.cache]
Type = "s3"
Path = "/cache"
Shared = false
[runners.cache.s3]
ServerAddress = "minio-w1hko6-svc:9000"
AccessKey = "minio"
SecretKey = "minio"
BucketName = "runners-cache"
BucketLocation = "cn-hb-wh-1"
Insecure = true
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "ubuntu:22.04"
[[runners.kubernetes.host_aliases]]
ip = "192.168.10.128"
hostnames = ["lb.kubesphere.local"]
[[runners.kubernetes.volumes.config_map]]
name = "runner-config"
mount_path = "/runner-config"
[[runners.kubernetes.volumes.pvc]]
name = "gitlab-runner-local-pvc"
mount_path = "/root/.m2/repository"
[[runners.kubernetes.volumes.host_path]]
name = "docker-sock"
mount_path = "/var/run/docker.sock"
host_path = "/var/run/docker.sock"
-
[[runners]]: 这是GitLab Runner配置的起始点,表示一个GitLab Runner的配置块。通常,你可以有多个不同的[[runners]]块来配置不同的Runner。
-
environment: 这里可以指定一些环境变量,它们以形式"键=值"存在,会在每个执行job中均初始化此处环境变量信息
-
cache_dir: 指定了缓存的目录,缓存是用于存储构建和依赖的数据以加速构建过程的工具。默认缓存目录即为/cache
-
[runners.cache]: 这个块包含了关于缓存的详细配置 。
- Type: 指定了缓存类型,这里设置为"s3",表示使用Amazon S3作为缓存后端(minio兼容s3)。目前支持s3, gcs, azure三种分布式外部缓存配置。配置详见 Gitlab Runner Advanced configuration
- Path: 指定了缓存的路径,这里设置为"/cache"。
- Shared: 是否在不同的runner之间共享缓存,设置为false,表示不共享缓存。
- [runners.cache.s3]: 这个块包含了S3(minio)缓存的详细配置。
- ServerAddress: 设置minio服务器的地址为"minio-w1hko6-svc:9000"。该地址为minio服务地址
- AccessKey 和 SecretKey 分别是minio服务器的访问密钥和密钥。
- BucketName: 指定S3存储桶的名称为"runners-cache"。
- BucketLocation: 设置存储桶的位置为"cn-hb-wh-1"。测试不配置也可以
- Insecure 设置为true,表示允许不安全的HTTP连接到minio服务器。
- [runners.kubernetes]: 这个块包含了GitLab Runner在Kubernetes中的配置。
- namespace: 使用Helm模板{{.Release.Namespace}}来动态获取Runner所属的Kubernetes命名空间。
- image: 设置要用于默认运行作业的容器镜像,这里是"ubuntu:22.04"。
- [[runners.kubernetes.host_aliases]]: 这里定义了主机别名,指定了一个IP地址(“192.168.10.128”)和一个主机名(“lb.kubesphere.local”)。这可以用于在Runner容器内解析主机名到指定的IP地址。这个主要用来后续运行kubectl命令做准备,将master节点ip进行配置
- [[runners.kubernetes.volumes.config_map]]: 这个部分定义了一个挂载卷,将名为"runner-config"的ConfigMap挂载到容器中的"/runner-config"路径。自定义configmap,将各类需要在job调用的sh脚本进行配置。后续会详细讲解此处配置文件
- [[runners.kubernetes.volumes.pvc]]: 这里定义了一个挂载卷,将名为"gitlab-runner-local-pvc"的持久卷声明(PVC)挂载到容器中的"/root/.m2/repository"路径。由于用于构建的pods均为临时pods,运行后会销毁, 因此需要配置cache或者挂载持久卷对maven下载的包进行保存
- [[runners.kubernetes.volumes.host_path]]: 这个部分定义了一个挂载卷,将主机的"/var/run/docker.sock"文件挂载到容器中的"/var/run/docker.sock"路径。这是用于与主机上的Docker守护进程通信的典型设置。由于需要使用docker build及docker push命令,因此此处挂载docker.sock文件, 后续会详细讲解为何使用此种方式以及还有哪几种其他方式。
3.2 minio部署(非必选)
minio是部署分布式缓存的选择, 可以使用gitlab自带的缓存配置
3.2.1 配置minio仓库
与gitlab仓库类似, 将charts.min.io 到应用仓库中
新建应用,版本随意选择,我选择了最新版本
主要需要修改的参数
- rootUser: 默认账号
- rootPassword: 默认密码
- replicas: 3, 副本数, 我选择了3;1无法启动
- persistence.enabled: true, 持久化
- persistence.existingClaim: 已经存在的持久卷声明
3.3 配置.gitlab-ci.yml脚本文件
该脚本是该文章重点内容

如图所示该流程一共五个阶段,目前每个阶段均只有一个job。
- pre阶段:该阶段主要为预备阶段,首先是生成动态环境变量,其次是获取到本次提交的内容是属于那些子模块,获取到CHANGE_MODULES,为后续push及deploy阶段做准备工作
- build阶段: 该阶段为mavn 构建阶段,将maven构建制品放入缓存(注: 制品存储可以直接使用artifact, 我由于外部原因,只能使用cache缓存代替)
- push阶段: 构建docker镜像以及将镜像推送到镜像库
- deploy: 将微服务通过kubectl调度容器组镜像信息
- clear: 由于minio存储空间及其有限,因此最后手动进行了清理
stages:
- pre
- build
- push
- deploy
- clear
# 公共配置
.common: &common
# 触发流程的分支
only:
- dev
# 调试用
- litao-dev
variables:
TZ: Asia/Shanghai
# 测试环境
NAMESPACE: crm2
# 监听待发布服务列表
DEPLOY_MODULES: admin,authorization,bi,examine,gateway
# 预检查,查看待发布服务列表
pre-checking:
<<: *common
image: bitnami/git
stage: pre
before_script:
# 复制获取变化文件列表模型
- cp /runner-config/change_modules.sh .
- chmod +x change_modules.sh
script:
- export CHANGE_MODULES=$(sh change_modules.sh $CI_COMMIT_SHA $DEPLOY_MODULES)
- export BUILD_START_TIME=$(date +%Y%m%d%H%M%S)
# 存储环境变量
- echo "BUILD_START_TIME=$BUILD_START_TIME" >> share.env
- echo "CHANGE_MODULES=$CHANGE_MODULES" >> share.env
artifacts:
paths:
# job间共享环境变量
- share.env
# maven构建
building:
<<: *common
image: maven:3.6.3-jdk-8
stage: build
dependencies:
- pre-checking
cache:
key: build-cache
paths:
# 存储变更打包的制品
- target
#aliyun mvn配置文件准备,提高速度
before_script:
# 读取共享环境变量信息
- source share.env
- if [ -z "$CHANGE_MODULES" ]; then
echo "微服务未发生变动,跳过部署";
exit 0;
fi
# 将自定义阿里云xml复制到镜像中
- echo `ls $MAVEN_HOME/conf`
- cp -f /runner-config/setting.xml $MAVEN_HOME/conf/settings.xml
script:
- echo "=============== 开始编译源码,在target目录生成jar文件 ==============="
- mvn clean compile package -Dmaven.test.skip=true
- echo "=============== 完成源码编译打包 ==============="
# 将需要缓存的文件复制到target文件夹中
- cp /runner-config/copy_artifacts.sh .
- chmod +x copy_artifacts.sh
- echo $CHANGE_MODULES
- sh copy_artifacts.sh target $CHANGE_MODULES
- ls -lh target
artifacts:
paths:
# job间共享环境变量
- share.env
################-----push-----##########################
# push模块公共组件
push-service:
<<: *common
image: docker:latest
stage: push
dependencies:
- building
cache:
key: build-cache
policy: pull
paths:
- target/*tar.gz
before_script:
- cat share.env
- source share.env
# 提前登陆镜像库
- echo "password" | docker login -u "username" --password-stdin registry.cn-hangzhou.aliyuncs.com
# CHANGE_MODULES 变量不为空,执行构建操作
# 生成镜像名称
# 使用 $module 进行 Docker 构建操作
# CHANGE_MODULES 变量为空,跳过构建
script:
- |
if [ -n "$CHANGE_MODULES" ]; then
modules=$(echo "$CHANGE_MODULES" | tr ',' '\n')
for module in $modules; do
image_name="registry.cn-hangzhou.aliyuncs.com/quadimodo/crm-${module}:${CI_PIPELINE_IID}-${BUILD_START_TIME}"
docker build -t "$image_name" --build-arg SERVER_NAME="$module" .
docker push "$image_name"
done
else
echo "CHANGE_MODULES is empty, skipping build."
fi
artifacts:
paths:
# job间共享环境变量
- share.env
################-----push-----##########################
###############------deploy-----########################
# 部署公共模块
deploy-service:
<<: *common
image: bitnami/kubectl:latest
stage: deploy
dependencies:
- push-service
before_script:
- cat /runner-config/config.yml | base64 -d > ./config
# 获取环境变量信息
- source share.env
script:
- |
if [ -n "$CHANGE_MODULES" ]; then
modules=$(echo "$CHANGE_MODULES" | tr ',' '\n')
for module in $modules; do
image_name="registry.cn-hangzhou.aliyuncs.com/quadimodo/crm-${module}:${CI_PIPELINE_IID}-${BUILD_START_TIME}"
K8S_SERVER_NAME="crm-${module}-v1"
kubectl set image deployment ${K8S_SERVER_NAME} *=${image_name} --kubeconfig ./config --namespace $NAMESPACE
done
else
echo "CHANGE_MODULES is empty, skipping deploy."
fi
artifacts:
paths:
# job间共享环境变量
- share.env
###############------deploy-----########################
# 清除缓存信息
clear-cache:
<<: *common
image:
name: minio/mc
entrypoint: [ '' ]
stage: clear
after_script:
# 删除缓存
- mc rm --recursive --force minio/runners-cache/cache/runner
before_script:
# 对缓存进行配置
- export MINIO_HOST=$(cat /runner-config/MINIO_HOST)
- export MINIO_ACCESS_KEY=$(cat /runner-config/MINIO_ACCESS_KEY)
- export MINIO_SECRET_KEY=$(cat /runner-config/MINIO_SECRET_KEY)
- mc alias set minio $MINIO_HOST $MINIO_ACCESS_KEY $MINIO_SECRET_KEY
script:
# 删除所有文件, 避免再次缓存
- rm -rf */target/*tar.gz
逐段解释分析
- stages: 定义了CI/CD流程的不同阶段,包括"pre"(预检查)、“build”(构建)、“push”(推送)、“deploy”(部署)、“clear”(清除缓存)。
- .common: 这是一个YAML锚点,用于定义公共配置,这些配置可以在不同的任务中共享。在此锚点下,定义了一些公共变量和触发条件。
- variables: 在这里定义了一些环境变量,如时区、Kubernetes命名空间、待发布服务列表等。待发布服务列表是该springboot项目中所有可以发布成微服务的子模块列表
- pre-checking: 这是一个预检查阶段,用于检查待发布的服务列表。
- 它继承了.common的配置,包括环境变量和触发条件。
- 使用GitLab Runner中的bitnami/git镜像执行任务。使用自定义git镜像, 在change_modules.sh脚本中配置git脚本获取提交文件中发生文件变更的微服务,后续会对各个脚本进行详细说明。
- 在before_script中,将用于获取变更文件列表的脚本change_modules.sh复制到工作目录,并设置其可执行权限。
- 在script中,运行脚本来获取变更的服务列表,并存储在环境变量中。
- 使用artifacts部分,将共享环境变量文件share.env保存为构件工件。使用缓存进行保存也可以
- building: 这是构建阶段,用于构建应用程序。
- 继承了.common中的配置,包括环境变量和触发条件。
- 使用maven:3.6.3-jdk-8镜像执行任务,用于Maven构建。
- 依赖于pre-checking阶段。
- 使用缓存用于传递打包完成的压缩包。artifact默认有100M限制,我的项目打一个包就超过了100M, 可以修改系统对artifact的大小限制,但是gitlab我没有管理员权限,因此我选择使用外部minio作为缓存用来存储压缩包,更加可控
- 在before_script中,读取共享环境变量,并设置Maven的阿里云配置文件。
- 在script中,执行Maven构建,然后将构建的制品复制到目标目录,并保存共享环境变量。
- push-service: 这是推送镜像的阶段,用于构建和推送Docker镜像。
- 继承了.common中的配置,包括环境变量和触发条件。
- 使用docker:latest镜像执行任务,用于Docker构建和推送。
- 依赖于building阶段。
- 使用缓存获取build阶段中的压缩包文件。
- 在before_script中,登录到Docker镜像库。此处使用明文不太安全,可以考虑更换为configmap, 然后挂载到执行pods上, 此处可以读取挂载的configmap文件以提高安全性
- 在script中,根据变更的服务列表构建并推送Docker镜像。先前本来配置为一个微服务就配置一个push job,因此到了push阶段会同时出现大量push pods,占用大量计算资源,对集群有较大压力,因此换成了只有一个push job, 同时脚本使用if + for循环的配置来构建及推送镜像降低短时集群资源消耗
- 使用artifacts保存共享环境变量。
- deploy-service: 这是部署阶段,用于更新Kubernetes中的部署以使用新的镜像。
- 继承了.common中的配置,包括环境变量和触发条件。
- 使用bitnami/kubectl:latest镜像执行任务,用于使用kubectl更新Kubernetes部署。
- 依赖于push-service阶段。
- 在before_script中,解码Kubernetes配置文件并获取环境变量。
- 在script中,根据变更的服务列表更新Kubernetes部署以使用新的Docker镜像。
- 使用artifacts保存共享环境变量。
- clear-cache: 这是清除缓存的阶段,用于删除GitLab Runner的缓存。由于minio分配的比较克制的存储空间,因此添加单次对缓存的清理
- 继承了.common中的配置,包括环境变量和触发条件。
- 使用minio/mc镜像执行任务,用于删除缓存文件。
- 依赖于building阶段。
- 在before_script中,配置Minio/MC以连接到Minio服务器,并获取环境变量。
- 在script中,删除Minio服务器上的缓存文件。
- 使用after_script中的命令,删除本地的构建缓存文件。
3.3.1 k8s挂载配置文件及环境变量
在3.1.2.1 runner配置中, 添加了将configmap键值对挂载到工作pods指定目录/runner-config 下, 用于保存待执行的shell脚本及部分配置文件以及不方便放在gitlab脚本中的保密文件
3.3.1.1 configmap配置列表
- MINIO_ACCESS_KEY: minio配置
- MINIO_HOST: minio配置
- MINIO_SECRET_KEY: minio配置
- change_modules.sh: 使用git命令获取比对产生变化的模块列表用于发布
- config.yml: k8s配置信息
- copy_artifacts.sh: 复制maven制品到指定文件夹
- setting.xml: maven配置文件,用于加速下载
3.1.1.1 change_modules.sh
#!/bin/bash
# 接受两参数:Git提交的SHA和子模块列表
commit_sha=$1
submodules=$2
# 检查是否提供了足够的参数
if [ -z "$commit_sha" ] || [ -z "$submodules" ]; then
echo "Usage: $0 <commit_sha> <submodules>"
exit 1
fi
# 分割子模块列表为数组
# IFS=',' read -ra submodule_list <<< "$submodules"
submodule_list=$(echo "$submodules" | tr ',' '\n')
# 初始化变更的子模块列表
changed_submodules=""
# 使用Git命令获取指定提交与上一次提交之间的文件更改
changed_files=$(git diff-tree -r --name-only --no-commit-id --pretty=format:"%H %P %an %ad" $commit_sha| grep -v ".*\.\(swp\|bak\)")
# 检查每个文件是否以指定的文件夹前缀开头
for file in $changed_files; do
for submodule in $submodule_list; do
case "$file" in
"$submodule"*)
if [ -z "$changed_submodules" ]; then
changed_submodules="$submodule"
else
changed_submodules="$changed_submodules,$submodule"
fi
break ;;
esac
done
done
# 使用 awk 去除重复的前缀
changed_submodules=$(echo "$changed_submodules" | tr ',' '\n' | awk '!seen[$0]++' | tr '\n' ',' | sed 's/,$//')
# 输出变更的子模块列表
echo "$changed_submodules"
3.1.1.2 copy_artifacts.sh
#!/bin/bash
# 检查是否提供了正确数量的参数
if [ $# -lt 2 ]; then
echo "Usage: $0 <target_dir> <source_dirs>"
exit 1
fi
# 第一个参数是目标文件夹路径
target_dir="$1"
# 第二个参数是逗号分隔的源文件夹路径字符串,可以包含环境变量
source_dirs="$2"
# 创建目标文件夹,如果它不存在
mkdir -p "$target_dir"
# 使用逗号分隔符分割源文件夹字符串为数组
# IFS=',' read -ra source_dirs_array <<< "$source_dirs"
source_dirs_array=$(echo "$source_dirs" | tr ',' '\n')
# 循环遍历每个源文件夹
for source_dir in $source_dirs_array; do
target_dir_in_source="$source_dir/target"
done
# 检查source_dir/target目录是否存在,如果不存在则创建
if [ ! -d "$target_dir_in_source" ]; then
mkdir -p "$target_dir_in_source"
fi
# 使用find命令查找指定目录下的所有.tar.gz文件并复制到目标文件夹
find "$target_dir_in_source" -type f -name "*.tar.gz" -exec cp {} "$target_dir" \;
echo "复制完成"
3.1.1.3 settings.xml
<?xml version="1.0" encoding="utf-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!--本地仓库。该值表示构建系统本地仓库的路径。其默认值为~/.m2/repository。
<localRepository>F:\apache-maven-3.0.4\dependy\repository</localRepository>
-->
<!--Maven是否需要和用户交互以获得输入。如果Maven需要和用户交互以获得输入,则设置成true,反之则应为false。默认为true。
<interactiveMode>true</interactiveMode>
-->
<mirrors>
<!-- mirror | Specifies a repository mirror site to use instead of a given
repository. The repository that | this mirror serves has an ID that matches
the mirrorOf element of this mirror. IDs are used | for inheritance and direct
lookup purposes, and must be unique across the set of mirrors. | -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<id>net-cn</id>
<mirrorOf>central</mirrorOf>
<name>Nexus net</name>
<url>http://maven.net.cn/content/groups/public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<repositories>
<repository>
<id>nexus</id>
<name>local private nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>local private nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<!-- -->
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
3.1.1.4 config.yml


将以上config的yml文件base64后存储到config.yml中。也可以不经过base64,修改一下shell脚本内容即可,不过转换base64,可能会更安全一点😂
3.4 小结
以上流程均为自己经过N次尝试后能够完成需求及性能比较过得去的方案, 肯定不是最佳解决方案。比如, cache如此麻烦,是artifact大小限制问题, 可以直接修改artifact大小限制而不用cache配置及minio搭建。 又比如可以直接升级gitlab的版本,可以解锁一些高级特性,如 rules, only:changes 。不仅要看官网教程,同时也要对照本地gitlab 的help文档看,这样可以知道本地gitlab版本支持语法的界限,可以避免走很多坑
碰到的问题
低版本gitlab不支持高版本语法内容
gitlab11 已知没有的特性
- rules
- only:changes
具体可以点击如下链接查看
gitlab-ci yml关键字列表
不同类型runner对编写脚本的影响
在k8srunner中, 每次执行一个job都会启动一个新的指定镜像的容器组,因此job之间的信息共享和其他runner存在差异。
- 共享文件夹挂载或环境变量挂载
需要在[runners.kubernetes] 中进行指定配置, 在此配置的configmap或volumes都会在job 容器组初始化时进行挂载 - 环境变量分享
在job或者全局配置variables作为job中的环境变量, 在同一个job读取或者变更都没有任何问题。但是修改后不会传递到下一个job,因此k8s环境下variables实际上均只能在job内生效, 我的做法是将环境变量存储到文件(share.env),通过缓存的方式做到job之间共享环境变量信息,即在下一个job 的before_script中执行 source share.env 读取到pods中
执行docker build的类型方式
我通过挂载docker.sock的方式相对来说是最不安全也是最low的方式,但是我尝试另外两种方式都失败了。花了很长时间搜索错误还是没有头绪,无奈只能放弃
k8s using docker in builds
- expose /var/run/docker.sock
- docker:dind
- use kaniko to build docker images
大家可以点击以上链接自行尝试另外两种可以执行docker build操作的方式
参考资料
我将上文中出现的链接都放在此处进行统一展示
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)