GitLabJenkinsArgoCDHarbor 完整GitOps发布流程详解这份文档是生产级K8s GitOps流水线的完整落地手册核心逻辑是Git作为唯一可信源Jenkins负责CI构建ArgoCD负责CD同步彻底实现代码提交即自动上线。下面我会从架构原理→组件部署→CI配置→CD配置→完整发布闭环一步步拆解结合文档里的每一条命令和配置讲清楚做什么、为什么这么做。一、先搞懂整体架构与核心分工1. 架构图对应文档环境开发者提交代码 → GitLab(代码仓库配置仓库) → Jenkins自动触发CI → 编译打包 → 推镜像到Harbor → Jenkins更新GitLab配置仓库的镜像标签 → ArgoCD检测到Git变化 → 自动同步配置到K8s集群 → 服务上线2. 各组件明确分工文档严格遵循组件负责工作核心作用GitLab存储业务代码仓库和K8s配置仓库唯一可信源所有变更都记录在GitJenkins拉代码→编译→测试→构建镜像→推Harbor→更新配置仓库纯CI持续集成只做构建不做部署ArgoCD监控Git配置仓库→自动同步到K8s集群→保证集群状态与Git一致纯CD持续部署只做部署不做构建Harbor存储Docker镜像私有镜像仓库统一管理所有服务镜像3. 文档环境说明K8s集群1个Master节点2个Worker节点node01/node02所有组件都部署在K8s的gitops命名空间下ArgoCD单独在argocd命名空间集群内部域名*.svc.cluster.local外部访问用Ingress域名gitlab.zls.com/jenkins.zls.com/argocd.zls.com二、第一步部署三大核心组件GitLab/Jenkins/ArgoCD所有组件都通过K8s YAML资源清单部署统一管理、持久化存储避免物理机部署的混乱。1. 部署GitLab代码/配置仓库文档提供了两种部署方式Docker命令和K8s YAML生产环境用K8s YAML。关键配置解释# 1. 持久化存储把GitLab的配置、日志、数据挂载到宿主机目录避免Pod重启丢失数据volumes:-name:gitlab-confighostPath:path:/data/gitlab/config# 宿主机目录提前创建-name:gitlab-loghostPath:path:/data/gitlab/log-name:gitlab-datahostPath:path:/data/gitlab/data# 2. 环境变量关闭不需要的Prometheus监控减少资源占用配置GitLab访问地址env:-name:GITLAB_OMNIBUS_CONFIGvalue:|external_url http://gitlab-svc.gitops.svc.cluster.local # 集群内部访问地址 gitlab_rails[gitlab_shell_ssh_port] 22 prometheus[enable] false # 关闭监控节省资源部署后验证# 查看Pod状态kubectl get pod-ngitops# 获取初始root密码kubectlexec-it-ngitops gitlab-xxx --grepPassword/etc/gitlab/initial_root_password# 测试访问配置本地hosts解析10.0.0.102 gitlab.zls.comcurlhttp://gitlab.zls.com2. 部署JenkinsCI构建工具这是最关键的一步Jenkins需要能运行Docker命令和能访问GitLab文档里的配置解决了这两个核心问题。核心配置详解# 1. 特权模式挂载Docker套接字让Jenkins容器能直接调用宿主机的Docker引擎securityContext:privileged:true# 开启特权模式capabilities:add:[ALL]volumes:-name:docker-commandhostPath:path:/usr/bin/docker# 挂载宿主机docker命令-name:docker-sockethostPath:path:/var/run/docker.sock# 挂载宿主机Docker套接字核心# 2. InitContainer初始化SSH密钥让Jenkins能通过SSH拉取GitLab代码initContainers:-name:setup-sshimage:busybox:latestcommand:[/bin/sh,-c]args:-mkdir-p /root/.sshcp /tmp/ssh-key/id_rsa /root/.ssh/id_rsachmod 700 /root/.sshchmod 600 /root/.ssh/id_rsavolumeMounts:-name:ssh-key-volume# 从Secret中读取提前生成的SSH私钥mountPath:/tmp/ssh-keyreadOnly:true-name:ssh-dirmountPath:/root/.ssh# 3. Secret存储SSH私钥把提前生成的SSH私钥base64编码后存入K8s SecretapiVersion:v1kind:Secretmetadata:name:gitlab-ssh-keynamespace:gitopstype:kubernetes.io/ssh-authdata:ssh-privatekey:LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQo# 你的私钥base64编码为什么这么做挂载docker.sockJenkins本身运行在容器里无法直接运行Docker命令通过挂载宿主机的Docker套接字就能调用宿主机的Docker引擎构建镜像InitContainer初始化SSH避免把私钥直接写在YAML里通过Secret管理更安全同时自动设置正确的权限SSH私钥必须是600权限否则无法使用部署后验证# 获取Jenkins初始密码kubectlexec-it-ngitops jenkins-xxx --cat/var/jenkins_home/secrets/initialAdminPassword# 测试Jenkins能否拉取GitLab代码kubectlexec-it-ngitops jenkins-xxx --gitclone gitgitlab-svc.gitops.svc.cluster.local:root/test.git3. 部署ArgoCDCD同步工具ArgoCD官方提供了一键部署的YAML文档里做了两个关键优化关闭HTTPS和配置Ingress。关键配置# 1. 关闭ArgoCD的HTTPS方便通过Ingress HTTP访问args:-/usr/local/bin/argocd-server---insecure# 关闭HTTPS# 2. Ingress配置外部访问ArgoCDapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:argocd-server-ingressnamespace:argocdannotations:nginx.ingress.kubernetes.io/backend-protocol:HTTPnginx.ingress.kubernetes.io/ssl-redirect:false# 关闭HTTPS重定向spec:rules:-host:argocd.zls.comhttp:paths:-path:/pathType:Prefixbackend:service:name:argocd-serverport:number:80部署后验证# 获取ArgoCD初始admin密码kubectl-nargocd get secret argocd-initial-admin-secret-ojsonpath{.data.password}|base64-d# 登录ArgoCD CLIargocd login10.1.6.33--usernameadmin--insecure--grpc-web# 查看集群状态argocd cluster list三、第二步配置CI流水线Jenkins端Jenkins的核心工作是代码提交后自动触发完成构建→推镜像→更新配置仓库。1. 前置准备在GitLab创建两个仓库业务代码仓库devops-demo存放Spring Boot/前端代码配置仓库devops-demo-k8s存放K8s的Deployment/Service/Ingress YAML把Jenkins的公钥~/.ssh/id_rsa.pub添加到GitLab的SSH密钥中让Jenkins能读写这两个仓库在Harbor创建项目devops用于存储镜像配置Jenkins的Harbor凭证用户名密码用于推送镜像2. 完整Jenkins Pipeline脚本对应文档作业pipeline{agent any environment{// 全局变量参数化构建时可修改IMAGE_NAME10.0.0.107/devops/hello-world// Harbor地址项目名镜像名IMAGE_TAG${BUILD_NUMBER}// 用Jenkins构建号作为镜像标签唯一且可追溯CONFIG_REPOgitgitlab-svc.gitops.svc.cluster.local:root/devops-demo-k8s.git// 配置仓库地址}stages{stage(拉取业务代码){steps{git url:gitgitlab-svc.gitops.svc.cluster.local:root/devops-demo.git,branch:main,credentialsId:gitlab-ssh// Jenkins中配置的GitLab SSH凭证}}stage(编译打包){steps{// Java项目示例shmvn clean package -DskipTests// 前端项目示例sh npm install npm run build}}stage(构建Docker镜像){steps{// 用项目根目录的Dockerfile构建镜像shdocker build -t${IMAGE_NAME}:${IMAGE_TAG}.}}stage(推送镜像到Harbor){steps{withCredentials([usernamePassword(credentialsId:harbor-cred,usernameVariable:HARBOR_USER,passwordVariable:HARBOR_PASS)]){// 登录Harborshdocker login 10.0.0.107 -u${HARBOR_USER}-p${HARBOR_PASS}// 推送镜像shdocker push${IMAGE_NAME}:${IMAGE_TAG}// 清理本地镜像节省空间shdocker rmi${IMAGE_NAME}:${IMAGE_TAG}}}}stage(更新Git配置仓库){steps{// 克隆配置仓库shgit clone${CONFIG_REPO}config-repodir(config-repo){// 替换Deployment中的镜像标签sh sed -i s|image: 10.0.0.107/devops/hello-world:.*|image:${IMAGE_NAME}:${IMAGE_TAG}|g deployment.yaml // 提交并推送修改sh git config user.name jenkins git config user.email jenkinsexample.com git add deployment.yaml git commit -m Update image to${IMAGE_TAG} git push origin main }}}}post{success{echo构建成功ArgoCD将自动同步部署}failure{echo构建失败请查看日志排查问题}}}3. 配置自动触发在GitLab的业务代码仓库中配置Webhook地址为http://jenkins.zls.com/project/devops-demo触发事件选择Push events这样开发者提交代码到main分支就会自动触发Jenkins构建。四、第三步配置CD同步ArgoCD端ArgoCD的核心工作是持续监控Git配置仓库一旦发现配置变化自动同步到K8s集群。1. 两种创建ArgoCD应用的方式文档提供了UI创建和YAML创建两种方式生产环境推荐用YAML创建可版本化管理。方式1YAML创建推荐apiVersion:argoproj.io/v1alpha1kind:Applicationmetadata:name:hello-worldnamespace:argocdspec:project:default# 所属项目默认default# Git配置仓库信息source:repoURL:gitgitlab-svc.gitops.svc.cluster.local:root/devops-demo-k8s.gittargetRevision:main# 监控的分支path:.# 配置文件所在目录# 部署目标集群和命名空间destination:server:https://kubernetes.default.svc# 部署到当前K8s集群namespace:hello-world# 目标命名空间# 自动同步策略核心syncPolicy:automated:prune:true# 自动删除Git中不存在的资源比如旧的PodselfHeal:true# 自动修复手动修改的集群资源保证Git是唯一可信源syncOptions:-CreateNamespacetrue# 如果目标命名空间不存在自动创建部署命令kubectl apply -f hello-world-argo.yaml方式2UI创建登录ArgoCD UIhttp://argocd.zls.com点击New App填写应用名称、项目、同步策略填写Git仓库地址、分支、路径填写目标集群和命名空间点击Create完成创建2. 关键参数解释prune: true如果Git中删除了某个资源的YAMLArgoCD会自动在集群中删除该资源避免残留selfHeal: true如果有人手动修改了集群中的资源比如kubectl edit deploymentArgoCD会自动将其恢复为Git中的状态保证Git是唯一可信源CreateNamespacetrue自动创建目标命名空间不需要提前手动创建五、完整发布闭环演示对应文档lol-web例子现在我们模拟一次完整的代码提交到上线的过程你就能彻底理解整个流程了开发者提交代码修改devops-demo仓库的代码提交到main分支GitLab触发Webhook自动通知Jenkins开始构建Jenkins执行CI流程拉取最新代码编译打包生成jar包构建Docker镜像标签为10.0.0.107/devops/hello-world:123123是Jenkins构建号推送镜像到Harbor克隆配置仓库devops-demo-k8s修改deployment.yaml中的镜像标签为123提交并推送修改到GitLabArgoCD检测到变化每隔3分钟轮询Git配置仓库发现deployment.yaml有更新ArgoCD自动同步执行kubectl apply -f deployment.yaml更新K8s集群中的DeploymentK8s执行滚动更新逐步替换旧的Pod为新的Pod服务无中断上线验证结果访问http://hello.zls.com看到最新的代码效果六、文档中的坑与生产优化建议1. 文档中的坑YAML缩进错误文档中部分YAML的缩进不正确比如Jenkins Service的namespace位置复制时需要修正HostPath存储生产环境不要用HostPath应该用PV/PVC或云存储避免节点故障导致数据丢失没有配置资源限制所有组件都没有配置CPU/内存限制可能导致资源抢占生产环境必须添加HTTP访问生产环境应该配置HTTPS证书不要用明文HTTP2. 生产优化建议多环境管理配置仓库用不同分支对应不同环境dev/test/prodArgoCD分别同步权限分离开发人员只有代码仓库的读写权限没有配置仓库的写入权限只有运维人员能修改生产环境配置镜像版本管理除了构建号还可以加上Git提交哈希方便追溯监控告警监控Jenkins构建状态、ArgoCD同步状态、服务运行状态回滚机制出问题时直接回滚Git配置仓库的提交ArgoCD会自动同步回滚完整触发链你关心的你或 Jenkins改 GitLab 配置仓库里的 web.yamlgit add → commit → push 推到 GitLabArgoCD 定时拉取 Git默认 3 分钟发现 YAML 变了ArgoCD 自动 apply 到 K8sDeployment 更新、Pod 滚动替换集群状态和 Git 保持一致一句话总结GitLab 是唯一真实状态YAML 一更新ArgoCD 自动同步到 K8s全程不用 kubectl。七、文档作业完成指南作业要求gitlab jenkins argoCD 发布 hello-world harbor 参数化构建在GitLab创建hello-world代码仓库和hello-world-k8s配置仓库编写hello-world的Dockerfile和K8s配置文件deployment.yaml/service.yaml/ingress.yaml在Jenkins创建参数化构建项目添加IMAGE_TAG参数默认值为${BUILD_NUMBER}把上面的Pipeline脚本复制到Jenkins项目中修改对应的仓库地址和Harbor地址在ArgoCD创建应用关联hello-world-k8s配置仓库提交代码到hello-world仓库验证自动构建和部署是否成功测试参数化构建手动触发构建指定不同的镜像标签验证是否能正常发布GitLab 相关密钥SSH 私钥用途Jenkins 免密读写 GitLab代码仓、配置仓1. 生成位置在master01 或 Jenkins 宿主机生成 SSH 密钥对ssh-keygen私钥~/.ssh/id_rsa公钥~/.ssh/id_rsa.pub2. 配置位置三处1GitLab 网页把公钥加到 GitLab 用户 SSH Keys → Jenkins 能拉/推代码2K8s Secret私钥 base64 后创建 Secret名字gitlab-ssh-keyapiVersion:v1kind:Secretmetadata:name:gitlab-ssh-keynamespace:gitopstype:kubernetes.io/ssh-authdata:ssh-privatekey:私钥base643Jenkins YAML挂载这个 Secret 到 Jenkins 容器volumes:-name:ssh-key-volumesecret:secretName:gitlab-ssh-keyitems:-key:ssh-privatekeypath:id_rsa→ 容器里/tmp/ssh-key/id_rsa→ 复制到/root/.ssh/id_rsa→ 免密访问 GitLab二、Harbor 镜像仓库密钥账号密码用途Jenkins 登录 Harbor 推镜像K8s 拉镜像1. 配置位置两处1Jenkins 凭证Jenkins 里添加usernamePassword凭证 → Pipeline 里登录 Harbor 推镜像withCredentials([usernamePassword(credentialsId:harbor-cred,...)]){shdocker login harbor地址 -u \$USER -p \$PASS}2K8s SecretimagePullSecret集群拉 Harbor 私有镜像用kubectl create secret docker-registry harbor-secret\--docker-serverharbor地址\--docker-usernameadmin\--docker-passwordxxxDeployment 里引用spec:imagePullSecrets:-name:harbor-secret三、Jenkins 自身密码用途登录 Jenkins 网页初始密码容器内/var/jenkins_home/secrets/initialAdminPassword可改密码Jenkins 网页里修改四、ArgoCD 密码用途登录 ArgoCD UI / CLI初始密码K8s Secretargocd-initial-admin-secretkubectl-nargocd get secret argocd-initial-admin-secret-ojsonpath{.data.password}|base64-d可改kubectl edit secret或 UI 改五、整体密钥流向一句话串SSH 私钥宿主机 → K8s Secret → Jenkins 容器 → 免密读写 GitLabHarbor 账号密码Jenkins 凭证推镜像 K8s Secret拉镜像Jenkins/ArgoCD 密码各自容器/Secret用于网页登录面试极简总结直接背GitLab SSH 密钥宿主机生成 → GitLab 加公钥 → K8s Secret 存私钥 → Jenkins 挂载使用Harbor 密钥Jenkins 凭证推镜像、K8s imagePullSecret拉镜像Jenkins/ArgoCD 密码各自初始密码/Secret用于登录