利用gitlab+argocd来实现k8s里的cicd
术语说明CI(持续集成)持续集成,自动化的代码提交和测试流程,确保代码质量,快速发现问题。CD(持续交付/部署)代码通过测试后自动部署到生产环境或预发布环境。GitLab集成了代码托管、CI/CD 流水线的 DevOps 平台。ArgoCDKubernetes 原生的声明式 GitOps 持续交付工具,自动同步 Git 仓库中配置。Kubernetes容器编排平台,管理容器化应用部署和扩展。随便修
引言
随着云原生技术的迅猛发展,Kubernetes 已成为主流的容器编排平台。如何高效、自动化地构建与部署应用,成为开发与运维团队的关注重点。结合 GitLab 强大的 CI 能力与 ArgoCD 的 Kubernetes 原生 GitOps 持续交付方案,能够构建出高效且可靠的 CI/CD 流程。本文将深入探讨如何利用 GitLab 和 ArgoCD 实现 Kubernetes 环境下的 CI/CD 流程。
基础概念介绍
| 工具 | 优势 |
|---|---|
| GitLab | 提供代码管理、CI 流水线、镜像构建与推送,支持与 Kubernetes 集群的连接与部署。 |
| ArgoCD | GitOps 实践的代表,自动同步 Git 仓库中的 Kubernetes 配置到集群,支持便捷的回滚操作。 |
明确概念:GitLab 做 CI,ArgoCD 做 CD
在 Kubernetes 持续集成与持续交付的整体流程中,GitLab 和 ArgoCD 各自承担不同职责,协同完成自动化发布。
| 工具 | 主要职责 | 说明 |
|---|---|---|
| GitLab | 持续集成(CI) | 负责代码构建、依赖安装、单元与集成测试、镜像构建与推送等任务。 |
| ArgoCD | 持续交付(CD) | 负责监控 Git 仓库中 Kubernetes 配置变更,自动将新镜像部署或滚动更新到集群。 |
以前端项目发版为例
假设你的前端小程序项目通过 uniapp 构建,构建产物镜像托管在私有 Docker 镜像仓库,部署在 Kubernetes 集群中运行,整个 CI/CD 流程如下:
1. GitLab 负责 CI 过程
代码提交(例如修改某个页面文件)会触发 GitLab Runner 执行 CI 流水线:
| 阶段 | 具体操作 |
|---|---|
| 代码拉取 | 从 GitLab 仓库拉取最新代码 |
| 依赖安装 | 执行 npm install 或相关依赖安装命令 |
| 代码构建 | 执行 uniapp 编译生成静态文件 |
| 测试 | 运行单元测试、集成测试,确保构建产物质量 |
| 镜像构建 | 使用 Dockerfile 构建包含前端产物的镜像 |
| 镜像推送 | 将镜像推送到私有 Docker Registry,标签通常为 commit-sha 或 version |
CI 成功后,镜像和变更的 Kubernetes 配置(如新版本的镜像标签)会同步提交到 Git 仓库管理的部署配置中(例如 GitLab 的另一个仓库或者同仓库的 k8s/ 目录)。
2. ArgoCD 负责 CD 过程
ArgoCD 持续监控 Kubernetes 配置 Git 仓库:
| 步骤 | 具体操作 |
|---|---|
| 监控配置 | 监控 Git 仓库中的前端应用 Kubernetes 部署配置文件,如 deployment.yaml |
| 发现变更 | 检测到镜像标签更新为新版本时 |
| 自动同步 | 自动将最新的 deployment.yaml 配置同步到 Kubernetes 集群,触发滚动更新 |
| 状态反馈 | 通过 ArgoCD Web UI 反馈当前应用的部署状态 |
| 回滚支持 | 如果出现异常,支持回滚到之前的稳定版本 |
关键优势
职责分明,流程清晰:CI 专注构建与测试,CD 专注部署与版本管理。
自动化与可追溯:代码、镜像、部署配置均由 Git 管理,生成完整的审计链。
灵活扩展多环境:通过 Git 分支或子目录管理不同环境配置,ArgoCD 可轻松同步。
快速回滚保障:基于 Git 版本管理的 ArgoCD 实现快速回滚功能。
CI:gitlab ci部分
GitLab Runner 安装部署
以下示例以常用的 Linux 环境为例,你可以根据需要选择对应的操作系统安装方式。
2.1 安装 GitLab Runner
可以通过官方提供的二进制包或包管理器安装。
# 下载并安装
curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
chmod +x /usr/local/bin/gitlab-runner
如果这里下载失败,请自行下载gitlab-runner的rpm安装包进行安装,也可以私信博主要这个rpm包
注册 GitLab Runner
安装完毕后,需要在 GitLab 中注册 Runner,使其能接收你的项目任务。
gitlab-runner register --non-interactive \
--url "http://192.168.150.11/" \
--registration-token "XTKC4XgCb2FEH3h8UMdu" \
--executor "docker" \
--docker-image alpine:latest \
--description "docker-runner" \
--tag-list "ci220-0626" \
--run-untagged="true" \
--locked="false" \
--access-level="not_protected" \
--docker-privileged="true" \
--docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
--docker-volumes "/etc/docker:/etc/docker" \
--docker-volumes "/cache"
参数说明
| 参数 | 说明 |
|---|---|
--non-interactive |
非交互式注册,适合自动化脚本 |
--url |
GitLab 实例 URL |
--registration-token |
项目或组的注册 Token |
--executor |
Runner 执行器类型,这里使用 Docker |
--docker-image |
默认 Docker 镜像 |
--description |
Runner 描述名称 |
--tag-list |
Runner 标签,任务触发时指定 |
--run-untagged |
是否执行未打标签的任务,true 表示执行 |
--locked |
是否锁定 Runner,false 表示不锁定,允许多个项目共享 |
--access-level |
访问级别,not_protected 表示适用于非受保护分支 |
--docker-privileged |
以特权模式运行 Docker 容器,便于构建镜像等需要特权的操作 |
--docker-volumes |
挂载的 Docker 卷,支持多次指定 |
这边需要说明一下,–url 和 --registration-token两个参数从你的gitlab的这里获取


gitlab-runner注册完成以后,你应该可以在你的gitlab runner页面看到你刚刚注册的gitlab-runner
绿色代表可以正常使用
如果你能正常看到这个页面,并且你的gitlab-runner状态显示为绿色,那恭喜你!
你的gitlab-runner可以正常使用了。
现在正式进入gitlab-runner的ci部分
首先把你的业务代码clone下来
git clone http://192.168.150.11/ops/ruoyi-cloud.git
进入到你的业务代码里创建一个名为.gitlab-ci.yml的文件
这里简单介绍一下.gitlab-ci.yml这个文件:
.gitlab-ci.yml 是 GitLab 整合持续集成和持续交付能力的关键配置文件,它定义了你的代码如何自动化构建、测试、打包及部署,从而加速软件开发和发布流程,提高稳定性和效率。
ok,现在让我们在这个文件中创建一些基础的环境变量和ci运行时的步骤:
1. 第一步:构建前端项目(build-ui)
任务说明:
使用 Node.js 镜像(node:16)
仅对 master 分支执行
进入 ruoyi-ui 目录
安装依赖(npm install,使用镜像加速地址)
生产环境打包(npm run build:prod)
生成产物 ruoyi-ui/dist/,作为 artifact 保留一个小时
[root@k8s-master ruoyi-cloud]# cat .gitlab-ci.yml
# .gitlab-ci.yml (兼容 GitLab 11.1.4)
stages:
- build
- package
- update-cd
variables:
HARBOR_URL: "填写你的harbor地址"
HARBOR_PROJECT: "ruoyi-cloud"
RUDYI_UI_IMAGE_NAME: "ruoyi-ui"
GIT_CONFIG_REPO_URL: "http://192.168.150.11/ops/ruoyi-cloud-cd.git"
GIT_CONFIG_FILE_PATH: "ruoyi-ui/ruoyi-ui.yml"
build-ui:
stage: build
image: node:16 # 使用 Node.js 16.x 版本
only:
- master
cache:
key: "$CI_COMMIT_REF_SLUG-node-modules"
paths:
- ruoyi-ui/node_modules/
script:
- echo "======== 开始构建 ruoyi-ui 项目 ========"
- node -v || echo "❌ Node.js 未安装"
- npm -v || echo "❌ npm 未安装"
- cd ruoyi-ui || { echo "❌ ruoyi-ui 目录不存在"; exit 1; }
- echo "📦 安装依赖中..."
- npm install --registry=https://registry.npmmirror.com --loglevel info || { echo "❌ npm install 失败"; exit 1; }
- echo "🚀 开始打包..."
- npm run build:prod || { echo "❌ 构建失败"; exit 1; }
- echo "✅ ruoyi-ui 项目构建完成"
artifacts:
paths:
- ruoyi-ui/dist/
expire_in: 1 hour
完事以后,保存提交一下
git add .
git commit -m "提交说明"
git push -u origin master
如果提交正常,你可以在gitlab的cicd的工作流页面看到有任务在执行
点击具体的流水线编号进去,你可以看到你定义的作业名称
点进去具体看一下
这里如果你构建成功的话就会看到这样的提示,如果有报错的话请百度或者ai
如果你能正常进行到这一步并且成功的话,恭喜你,基本距离成功已经不远了,因为接下来的任务基本就是依样画葫芦了!!
2. 第二步:打包 Docker 镜像(package-ui)
任务说明:
使用 Docker 官方镜像(docker:20.10.16)
不使用 Docker TLS 功能,方便镜像推送
仅 master 分支执行,指定 runner 标签 ci220-0626
使用当前时间创建镜像 tag
登录 Harbor 镜像仓库(凭借 CI/CD 环境变量 HARBOR_USER, HARBOR_PASSWORD)
构建 Docker 镜像,基于 ruoyi-ui/Dockerfile 和前一步的产物
推送镜像至 Harbor
将镜像标记和完整路径写入文件供下一步使用
保存 image_tag.txt 和 image_full_name.txt 作为 artifact
package-ui:
stage: package
image: docker:20.10.16
variables:
DOCKER_TLS_CERTDIR: ""
only:
- master
tags:
- ci220-0626
script: |
echo "========= 开始打包 Docker 镜像推送到 Harbor ========="
export DATE_VERSION=$(date +"%Y%m%d%H%M")
export IMAGE_TAG="${DATE_VERSION}"
echo "📌 使用时间戳作为版本号: $IMAGE_TAG"
export IMAGE_REGISTRY="${HARBOR_URL}"
export IMAGE_NAME="${HARBOR_PROJECT}/${RUDYI_UI_IMAGE_NAME}"
export IMAGE_FULL_NAME="${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
echo "🔖 镜像 Tag:${IMAGE_TAG}"
echo "🧩 镜像名称:${IMAGE_NAME}"
echo "🌐 镜像地址:${IMAGE_FULL_NAME}"
echo "${HARBOR_PASSWORD}" | docker login ${IMAGE_REGISTRY} -u ${HARBOR_USER} --password-stdin || { echo "❌ Docker 登录失败"; exit 1; }
docker build -f ruoyi-ui/Dockerfile -t ${IMAGE_FULL_NAME} ./ruoyi-ui || { echo "❌ Docker 构建失败"; exit 1; }
docker push ${IMAGE_FULL_NAME} || { echo "❌ Docker 推送失败"; exit 1; }
echo "${IMAGE_TAG}" > image_tag.txt
echo "${IMAGE_FULL_NAME}" > image_full_name.txt
echo "📄 保存的文件内容:"
echo "image_tag.txt: $(cat image_tag.txt)"
echo "image_full_name.txt: $(cat image_full_name.txt)"
echo "当前目录: $(pwd)"
ls -la
echo "✅ 镜像构建并推送完成"
artifacts:
paths:
- image_tag.txt
- image_full_name.txt
expire_in: 1 hour
把这部分代码作为第二部分添加在刚才第一部分代码的下方,保存并提交
git add .
git commit -m "提交说明"
git push -u origin master
这样你就能在刚才那个gitlab 流水线页面看到你的第二步的作业了

3. 第三步:更新 ArgoCD 配置仓库(update-manifest-ui)
任务说明:
使用 alpine/k8s:1.26.11 镜像,内含常用 Kubernetes 及 Linux 工具
仅 master 分支执行
依赖 package-ui 阶段 artifacts
读取 image_tag.txt 和 image_full_name.txt 文件,获取最新镜像信息
安装 git、sed、grep 以便操作 Git 并编辑配置文件
设置 Git 用户名和邮箱,配置 Git HTTP 认证凭据(通过环境变量 CI_USERNAME、CI_PASSWORD)
克隆配置仓库 GIT_CONFIG_REPO_URL 到工作目录
校验配置文件是否存在 GIT_CONFIG_FILE_PATH
查找 yml 文件里镜像字段,智能替换镜像标签
若常规替换失败,使用 awk 做更强力替换
对比文件是否修改,没有修改提示失败,修改了则提交并推送
配置推送之后,ArgoCD 会自动检测并启动新镜像部署
update-manifest-ui:
stage: update-cd
image: alpine/k8s:1.26.11
only:
- master
dependencies:
- package-ui
script: |
echo "======== 开始更新 ArgoCD 配置仓库 ========"
if [ -f "image_tag.txt" ]; then
export IMAGE_TAG=$(cat image_tag.txt)
else
echo "⚠️ 文件 image_tag.txt 不存在,使用当前时间作为版本号"
export IMAGE_TAG=$(date +"%Y%m%d%H%M")
fi
if [ -f "image_full_name.txt" ]; then
export IMAGE_FULL_NAME=$(cat image_full_name.txt)
else
echo "⚠️ 文件 image_full_name.txt 不存在,使用构建的镜像名"
export IMAGE_FULL_NAME="${HARBOR_URL}/${HARBOR_PROJECT}/${RUDYI_UI_IMAGE_NAME}:${IMAGE_TAG}"
fi
echo "使用镜像: ${IMAGE_FULL_NAME}"
apk add --no-cache git sed grep
git config --global user.name "填写你自己的git账号"
git config --global user.email "填写你自己git账号的邮箱"
echo "🔐 使用 HTTP 认证"
git config --global credential.helper store
echo "http://${CI_USERNAME}:${CI_PASSWORD}@192.168.150.11" > ~/.git-credentials
echo "🔄 正在克隆配置仓库..."
git clone "${GIT_CONFIG_REPO_URL}" /tmp/k8s-manifests || { echo "❌ Git 克隆失败"; exit 1; }
cd /tmp/k8s-manifests
if [ ! -f "${GIT_CONFIG_FILE_PATH}" ]; then
echo "❌ 配置文件 ${GIT_CONFIG_FILE_PATH} 不存在"
exit 1
fi
echo "🔎 检查配置文件内容"
echo "-----------------------------------"
cat "${GIT_CONFIG_FILE_PATH}"
echo "-----------------------------------"
if grep -q "image: {image}" "${GIT_CONFIG_FILE_PATH}"; then
echo "🔍 找到占位符格式: 'image: {image}'"
sed -i "s|image: {image}|image: ${IMAGE_FULL_NAME}|g" "${GIT_CONFIG_FILE_PATH}"
elif grep -q "image: ${HARBOR_URL}/${HARBOR_PROJECT}/${RUDYI_UI_IMAGE_NAME}:" "${GIT_CONFIG_FILE_PATH}"; then
echo "🔍 找到具体镜像格式,尝试替换版本"
sed -i "s|image: ${HARBOR_URL}/${HARBOR_PROJECT}/${RUDYI_UI_IMAGE_NAME}:[^ ]*|image: ${IMAGE_FULL_NAME}|g" "${GIT_CONFIG_FILE_PATH}"
else
echo "⚠️ 未找到匹配的镜像格式,尝试正则表达式匹配镜像标签"
sed -i "s|image: ${HARBOR_URL}/${HARBOR_PROJECT}/${RUDYI_UI_IMAGE_NAME}:[^ #]*|image: ${IMAGE_FULL_NAME}|g" "${GIT_CONFIG_FILE_PATH}"
fi
echo "🔎 替换后的文件内容"
echo "-----------------------------------"
cat "${GIT_CONFIG_FILE_PATH}"
echo "-----------------------------------"
if git diff --quiet; then
echo "⚠️ 没有检测到文件更改,尝试更强力的替换"
awk -v new_image="${IMAGE_FULL_NAME}" '
{
if ($0 ~ /image:/) {
if ($0 ~ /ruoyi-ui/) {
comment = ""
if ($0 ~ /#/) {
split($0, parts, "#")
comment = "#" parts[2]
}
print " image: " new_image " " comment
} else {
print $0
}
} else {
print $0
}
}' ${GIT_CONFIG_FILE_PATH} > ${GIT_CONFIG_FILE_PATH}.tmp
mv ${GIT_CONFIG_FILE_PATH}.tmp ${GIT_CONFIG_FILE_PATH}
echo "🔎 强力替换后的文件内容"
echo "-----------------------------------"
cat "${GIT_CONFIG_FILE_PATH}"
echo "-----------------------------------"
fi
if git diff --quiet; then
echo "❌ 所有替换方法都失败,无法更新文件"
exit 1
else
echo "✅ 成功更新镜像标签"
fi
echo "🔄 提交并推送更新..."
git add "${GIT_CONFIG_FILE_PATH}"
git commit -m "[CI] Update ruoyi-ui image to ${IMAGE_TAG}"
git push || { echo "❌ Git 提交推送失败"; exit 1; }
echo "✅ 配置仓库更新完成!ArgoCD 将会自动部署。"
保存退出后再次提交git
git add .
git commit -m "提交说明"
git push -u origin master
到gitlab的流水线上你能看到完整的ci部分流水线了
到此为止,恭喜你,利用gitlab-runner完成了ci部分的内容
CD:argocd cd部分
ArgoCD 部署
ArgoCD 是 Kubernetes 原生的持续交付工具,通过声明式 GitOps 模式实现应用自动同步和版本回滚。下面介绍如何在 Kubernetes 集群中部署 ArgoCD,并进行基础配置。
1. ArgoCD 安装
目前最简便的安装方式是通过官方提供的 YAML 清单文件一键部署:
# 没有kubectl的先安装kubectl
kubectl create namespace argocd
kubectl apply -n argocd -f https://github.com/argoproj/argo-cd/tree/release-2.8/manifests/install.yaml
# 或者
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.8/manifests/install.yaml
发布 Argo CD 服务
默认情况下, Argo CD 服务不对外暴露服务,可以通过 LoadBalancer 或者 NodePort 类型的 Service、Ingress、Kubectl 端口转发等方式将 Argo CD 服务发布到 Kubernetes 集群外部。
这里使用以下命令通过 NodePort 服务的方式暴露 Argo CD 到集群外部:
# 修改 Service 类型
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
# 获取随机生成的 NodePort 端口
kubectl get svc -n argocd

访问Web UI
kubectl get secret argocd-initial-admin-secret -o jsonpath=“{.data.password}” -n argocd | base64 -d
到这里为止,恭喜你,成功部署了argocd
argocd发版
让我们来到argocd的页面,创建一个新的发版任务


填写一下需要的参数
保存即可
argocd的部分就这些
我这边为了方便测试,我的cd部分就只有k8s deploy的一份文件

最后测试一下
随便修改一个页面上的内容并提交到git
这里千万注意,是提交到业务代码,也就是ci部分,因为cd部分的代码变更是由ci来自动更新的
进去随便改点内容然后提交git
git add .
git commit -m "提交说明"
git push -u origin master
如果顺利,你将看到完整走完的ci流水线任务
等待ci部分完成以后,再回到argocd页面,看你刚才创建的任务,就会发现任务被自动触发运行了
最后,查看一下你的前端页面,如果正常更新,说明这个流程走下来是没问题的
更多推荐
所有评论(0)