在OpenShift上使用Helm构建GitOps流水线:实战经验分享

本文分享了在OpenShift平台上使用Helm和ArgoCD构建GitOps流水线的实战经验,包括技术架构设计、部署流程优化、常见问题解决方案,以及如何实现从手动部署到自动化GitOps工作流的完整迁移过程。

在OpenShift上使用Helm构建GitOps流水线:实战经验分享

GitOps的实际意义(超越营销术语)

GitOps并不是火箭科学。它基本上是将Git视为集群中运行的所有内容的单一事实来源。当出现故障时(我们都经历过),你不再需要疯狂地运行kubectl命令,而是在Git中进行更改,让自动化处理其余工作。

核心思想很简单:

  • 将基础设施编写为代码(YAML、Helm图表等)
  • 将其存储在Git中,可以跟踪每个更改
  • 让ArgoCD等工具自动将集群同步到与Git中的内容匹配

美妙之处在于,回滚损坏的部署变得像恢复提交一样简单。不再需要"有人记得我们上周二更改了什么吗?"

为什么选择Helm + OpenShift + ArgoCD

老实说,我们并不是一开始就选择这个技术栈的。我们首先尝试了几种不同的方法:

  • Git - 显然需要这个来进行版本控制。这里没有争议
  • Helm - 在编写了数千行重复的YAML之后,Helm模板成为了救命稻草。模板语法可能有点奇怪,但比复制粘贴部署文件要好
  • OpenShift - 我们公司已经标准化使用Red Hat,OpenShift为我们提供了企业级功能,如适当的RBAC和安全扫描
  • ArgoCD - 我们最初尝试了Flux,但ArgoCD的UI赢得了我们运营团队的青睐。在部署过程中能够可视化正在发生的事情非常有价值

这个组合解决了我们最大的痛点:环境不一致、没有回滚策略,以及部署过程中过多的人工干预。

我们的组织结构

经过几次迭代后,我们的Git仓库结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
platform-gitops/
├── applications/
│   ├── user-service/
│   │   ├── Chart.yaml
│   │   ├── templates/
│   │   ├── values-development.yaml
│   │   ├── values-staging.yaml
│   │   └── values-production.yaml
│   ├── payment-service/
│   │   └── (相同结构)
├── infrastructure/
│   ├── monitoring/
│   ├── ingress-controllers/
│   └── cert-management/
└── argocd-apps/
    ├── dev-apps.yaml
    └── prod-apps.yaml

关于组织结构的经验:

  • 为每个环境保留单独的值文件。尝试使用带有覆盖的单个值文件会很快变得混乱
  • 将共享基础设施内容放在自己的目录中。你不希望监控配置与应用程序代码混合
  • 清晰命名事物。未来的你会感谢现在的你

在OpenShift上设置ArgoCD

让ArgoCD运行起来相当简单,但我们遇到了一些问题:

1
2
3
4
5
oc new-project argocd-system
kubectl apply -n argocd-system -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 创建路由以便访问UI
oc expose svc argocd-server --port=https -n argocd-system

专业提示:立即更改默认管理员密码。我们以尴尬的方式学到了这一点。

让ArgoCD与我们的私有Git仓库通信需要一些摸索。SSH密钥可以正常工作,但我们最终使用服务账户令牌以简化操作。

实际可用的应用程序定义

这是我们其中一个ArgoCD应用程序定义的样子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service-prod
  namespace: argocd-system
spec:
  project: production
  source:
    repoURL: https://github.com/ourcompany/platform-gitops
    path: applications/user-service
    targetRevision: release
    helm:
      valueFiles:
        - values-production.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: user-service-prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

值得注意的几点:

  • 我们对不同的环境使用不同的Git分支:开发用main,生产用release
  • prune: true 自动删除Git中不再存在的资源。当我们重命名一些服务时,这最初让我们措手不及
  • selfHeal: true 修复配置漂移,这发生的频率比你想象的要高

与CI流水线集成

GitOps不会取代CI/CD - 它改变了CD部分的工作方式。我们的Jenkins流水线现在看起来像这样:

  1. 开发人员推送代码
  2. Jenkins运行测试并构建Docker镜像
  3. Jenkins标记镜像并推送到我们的注册表
  4. Jenkins使用新的镜像标签更新Helm值文件
  5. ArgoCD注意到Git更改并自动部署

关键见解是意识到CI应该更新Git,而不是直接部署到Kubernetes。一开始感觉很奇怪,但现在很自然。

这是我们如何从Jenkins更新镜像标签的片段:

1
2
3
4
5
# 使用新镜像标签更新值文件
sed -i "s/tag: .*/tag: ${BUILD_NUMBER}/" applications/user-service/values-production.yaml
git add .
git commit -m "Deploy user-service build ${BUILD_NUMBER} to production"
git push origin release

遇到的问题(以及我们如何解决)

  • 密钥管理:不要将密钥放在Git中。我们现在使用Sealed Secrets,它加密只有集群可以解密的密钥。External Secrets Operator是另一个不错的选择
  • 资源限制:确保Helm图表包含适当的资源请求和限制。我们有一些服务会消耗整个节点,因为我们忘记在模板中设置限制
  • RBAC复杂性:OpenShift的RBAC与ArgoCD的项目系统结合可能会变得复杂。尽早记录权限模型并坚持使用
  • 同步波次:当服务之间存在依赖关系时,使用ArgoCD同步波次来控制部署顺序。我们遇到过数据库在其持久卷准备就绪之前尝试启动的情况
  • 图表依赖:Helm的依赖管理有效,但不太明显。定期使用Helm依赖更新,并正确版本化图表依赖

我们获得的收益

通过GitOps运行所有内容六个月后:

  • 部署时间从30多分钟的手动步骤减少到不到5分钟的完全自动化
  • 我们没有发生过一次"糟糕,环境错了"的事件
  • 回滚部署从令人恐慌变得无聊(以好的方式)
  • 我们的审计合规性变得更容易,因为所有内容都在Git中跟踪
  • 新开发人员可以通过阅读仓库了解我们的部署过程

最大的胜利不是技术上的 - 而是文化上的。我们的开发人员不再害怕部署。当部署只是一个Git提交时,人们更愿意发布小而频繁的更改。

来之不易的建议

  • 从小开始:不要试图一次性迁移所有内容。选择一个简单的服务,在扩展之前确保工作流程可靠
  • 投资Helm图表:花时间使它们可配置和良好文档化。你将与这些模板一起生活多年
  • 监控ArgoCD本身:ArgoCD宕机意味着部署停止。设置适当的监控和警报
  • 培训团队:工具只有在使用它的人手中才是好的。确保每个人都理解新的工作流程
  • 规划密钥:尽早制定密钥管理策略。稍后改造是痛苦的
  • 使用预览环境:一个意想不到的好处是能够为功能分支启动临时环境。非常适合在合并前进行测试

回顾

构建这个GitOps流水线不仅仅是采用新工具 - 它从根本上改变了我们对部署的思考方式。Git不再只是我们存储代码的地方;它是我们的部署控制平面。

学习曲线是真实的,我们在此过程中肯定犯了错误。但现在一切运行顺利,我无法想象回到旧的做事方式。当有人问"生产环境中运行的是什么版本?“时,答案总是"发布分支中的任何内容”。

如果你正在考虑进行这一跳跃,我的建议很简单:从一个应用程序开始,让它运行良好,然后从那里扩展。自动化投资每天都会带来回报。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计