背景
Kubesphere 3.3.0
集成了 ArgoCD
,但与笔者目前使用的 K8S 版本不兼容。再者,目前 Kubesphere
中持续集成和流水线打通还是不太友好,也缺少文档说明(可能是笔者没有找到)。
目前遇到最主要的问题就是流水线制作完成的镜像如何更新到 Git 仓库,然后触发 Application 的同步。
基于上述问题,目前有两种方法:
为此笔者基于 Kubesphere v3.1.1 的流水线,根据笔者的场景,实现了 GitOps 的服务发布流程,作此记录,暂且称之为最佳实践。
基于 Kubesphere 的流水线:
argocd-gitops-{devops 项目名}
);argocd-gitops-templates
项目存储了生成服务流水线和部署清单、argocd Application 的模板。
.
|-- app-manifests-templates
| |-- go
| | |-- base
| | | |-- deployment.yaml
| | | |-- kustomization.yaml
| | | `-- service.yaml
| | |-- canary
| | | |-- deployment_overlay.yaml
| | | |-- kustomization.yaml
| | | `-- service_overlay.yaml
| | |-- ga
| | | `-- kustomization.yaml
| | |-- kustomization.yaml
| |
|-- application-templates
| |-- README.md
| |-- application-pipeline.yaml
| `-- application.yaml
|-- pipeline-templates
| `-- pipeline
| `-- ks-pipeline-jenkinsfile.yaml
|-- top-pipeline
| |-- README.md
| |-- dev
| | |-- application.yaml
| | |-- only-test-deploy-by-argo-top-pipeline.jenkinsfile
| | `-- pipeline
| | `-- deploy-by-argo-top-pipeline.yaml
| |-- prod
| | |-- application.yaml
| | |-- only-test-deploy-by-argo-top-pipeline.jenkinsfile
| | `-- pipeline
| | `-- deploy-by-argo-top-pipeline.yaml
Groovy
语法实现注意:app-manifests-templates、pipeline-templates、application-templates,在发布 GitOps 服务时,执行 Top pipeline 生成服务 pipeline,会自动拷贝,并根据运行 Top pipeline 时输入的参数生成清单,到服务对应的 GitLab 仓库中。
例如:devops1 项目的 GitLab 部署清单仓库目录结构如下:
.
|-- README.md
`-- appsmanifests
|-- kubeinfo-svc1
| |-- prod
| | |-- application-pipeline.yaml
| | |-- application.yaml
| | `-- manifests
| | |-- base
| | | |-- deployment.yaml
| | | |-- kustomization.yaml
| | | `-- service.yaml
| | |-- canary
| | | |-- deployment_overlay.yaml
| | | |-- kustomization.yaml
| | | `-- service_overlay.yaml
| | |-- ga
| | | |-- deployment_overlay.yaml
| | | `-- kustomization.yaml
| | |-- kustomization.yaml
| | |-- pipeline
| | | `-- ks-pipeline-jenkinsfile.yaml
| `-- uat
| |-- application-pipeline.yaml
| |-- application.yaml
| `-- manifests
| |-- base
| | |-- deployment.yaml
| | |-- kustomization.yaml
| | `-- service.yaml
| |-- canary
| | |-- deployment_overlay.yaml
| | |-- kustomization.yaml
| | `-- service_overlay.yaml
| |-- ga
| | |-- deployment_overlay.yaml
| | `-- kustomization.yaml
| |-- kustomization.yaml
| |-- pipeline
| | `-- ks-pipeline-jenkinsfile.yaml
appsmanifests/{服务名}
文件夹下。Top Pipeline 用来自动化创建 GitOps 仓库,生成服务部署清单、pipeline CR 清单、Application CR 清单,将清单提交到 GitLab 仓库,并将 Application 创建到 K8S 集群中。整体用 Groovy
语法实现。
流程
黄色部分为需要人为干预的,绿色为自动执行的。
每个服务的发布,流水线都隶属于一个 DevOps 项目下,如果这个 DevOps 项目不存在,则需要手动新建。
如果存在,则需要手动点击运行 top pipeline。
kubectl apply -f {两个 application yaml}
创建 argocd Application CR;通过 kubectl 命令行直接创建到 ArgoCD 所在 K8S 集群。
一个服务对应 2 个 Application,一个管理 pipeline CR,另一个管理 deployment 等部署清单。
用 Git 命令行实现。
一个 DevOps 项目下的多个 Pipeline 同时运行,一定程度可能会提交失败。比如:B 克隆代码到本地,此时 A 提交一次,B 提交时就失败,需要重新 pull 后再提交。所以需要加重试机制,失败重新 pull。
容易提交冲突,所以需要先 pull 再 push,并增加失败之后重试
开启自动同步后,默认是 3~4 分钟 sync,时间较长。如何及时触发 CD 同步?
集成 argocd 命令行工具到 Agent 镜像中,新建一个 gitops 账号,并通过 RBAC 控制该账号的权限。
执行 argocd sync 命令也可能失败,需要加失败之后重试
具体请参看:ArgoCD 用户管理、RBAC 控制、命令行登录、App 同步[3]
kubesphere/builder-base:v3.2.2 镜像中包含了 kustomize 和 Git,更新镜像 Tag 时,用 base-3.2.2 作为 Pipeline Agent。
并将 argocd 命令行集成到上面镜像中,生成新的镜像:harbor.kubeinfo.cn/library/kubesphere/builder-base:v3.2.2-argocd
审核阶段,如果点击“终止”,将回滚上一个阶段的镜像版本。
正式环境发布之后(即流水线最后一步),可以点击“终止”回滚到上一个镜像版本(一般在新版本测试不通过的情况下点击“终止”),如果 30 分钟内没有点击,或者点了继续,本次发布流程将结束。
回滚的时候,通过 git revert 命令回退某一次提交。
没有启用 DevOps 系统的 K8S 集群中,不存在 pipeline CRD。
所以 pipeline 用单独的 Application 管理,其中的 destination cluster 只能为 ArgoCD 所在的集群。
只要加入到了 argocd 中的 k8s 集群(即使没有被 Kubesphere 纳管),都可以走这一套 GitOps 流程,将服务部署到这个 k8s 集群中。
目前采用 Kustomize,kustomize 利用 overlay 机制覆盖某些配置,虽然在可定制化方面不如 helm,如:不支持模板语法和变量,但 helm 对于笔者来说太重。目前的场景采用 Kustomize,基本可以满足需求。
kustomize 命令行用于更新 kustomization.yaml 中镜像 Tag,以及校验语法是否正确,避免语法不正确提交。
kustomize edit set image kubeinfo-svc=harbor-kubeinfo.cn/argocd/kubeinfo-svc:${DOCKER_TAG}
kustomize 已经在上面的 Agent 镜像中包含。
注释掉 deployment 中的spec.replicas
,argocd 将不管理 deployment 的实例数。
argocd Application 中有个 selfHeal
配置,表示:指定当仅在目标 Kubernetes 集群中更改资源且未检测到 git 更改时(默认为 false) ,是否应执行部分应用程序同步。
所以当 K8S 资源对象被修改时,Git 中清单没变化的情况下,不需要自愈修复,argocd 不会做还原;
但下一次流水线发布版本时,Git 上的清单会发生变化,此时 K8S 资源会被还原。
用 top pipeline 生成的流水线,有统一的格式,所以凭证必须统一。
DevOps 项目有很多,维护凭证成本很高。如何统一、自动化创建管理?如:harbor、argocd 的 gitops 账户、GitLab 的账号凭证。
通过 kubed + kyverno 实现:在 kubesphere-devops-system 下创建的源 secret,将会自动同步到所有 devops project 下。
参考:如何跨命名空间共享 Secret 和 ConfigMap?Kubesphere 凭证如何同步?[4]
引入了 GitOps,发现要做的东西更多了,但也确实带来很多好处。本文旨在记录分享笔者的 GitOps 落地经验,有些方案细节可能只适用于笔者当前的场景,笔者也处于摸索阶段。欢迎大佬们拍砖。
同时也期待 Kubesphere
服务的发布可以和流水线一条龙创建,将 GitOps
做的更易用,而不用在项目
和DevOps项目
之间切换;同时将灰度发布集成到流水线、可以回滚。
[1]
argocd-image-updater: https://argocd-image-updater.readthedocs.io/en/stable/
[2]
ks app update 工具: https://github.com/kubesphere-sigs/ks/blob/master/docs/app.md
[3]
ArgoCD 用户管理、RBAC 控制、命令行登录、App 同步: https://blog.csdn.net/ll837448792/article/details/125899955
[4]
如何跨命名空间共享 Secret 和 ConfigMap?Kubesphere 凭证如何同步?: https://liabio.blog.csdn.net/article/details/124973387
- END -