Argo CD 实践 GitOps

介绍

书接上文 OneDev 自建 Git 服务和 CI/CD,这次通过 ArgoCD 实现项目部署,项目编译、镜像构建依然通过 OneDev 流水线实现。当然用别的 Git 服务也是可以的。

Argo CD 被实现为一个 kubernetes 控制器,它持续监控正在运行的应用程序并将当前的活动状态与所需的目标状态(如 Git repo 中指定的)进行比较。Argo CD 报告和可视化差异,同时提供自动或手动将实时状态同步回所需目标状态的工具。

上次 git 仓库只有一个,这次 git 仓库分为两个

wx-msg-push 为项目代码
gitops 应用部署定义

整体流程为:

  • wx-msg-push 正常开发提交
  • 当创建 tag 推送时,触发 OneDev 流水线构建
  • 检出 wx-msg-push 代码,在容器中编译可执行文件,生成多平台可执行文件压缩包制品
  • 通过 kaniko 构建 wx-msg-push 项目镜像,推送至镜像仓库
  • 检出 gitops 代码,修改 wx-msg-push 项目 yaml 文件的镜像版本后 push
  • 在 argocd 中发现 gitops 配置变更
  • 同步应用最新状态

安装部署

高可用配置请参考 High Availability

1
2
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

安装之后默认会启用 TLS 验证和 http 强制跳转至 https
我这里不需要,直接修改 argocd-server 配置 kubectl -n argocd edit deployments.apps argocd-server,增加运行 insecure 运行参数,取消该限制。

1
2
3
4
containers:
- command:
- argocd-server
- --insecure

然后来查看服务地址

1
2
3
4
5
6
7
8
9
10
$ kubectl -n argocd get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-applicationset-controller ClusterIP 10.98.109.34 <none> 7000/TCP,8080/TCP 18m
argocd-dex-server ClusterIP 10.108.192.57 <none> 5556/TCP,5557/TCP,5558/TCP 18m
argocd-metrics ClusterIP 10.103.219.23 <none> 8082/TCP 18m
argocd-notifications-controller-metrics ClusterIP 10.105.150.33 <none> 9001/TCP 18m
argocd-redis ClusterIP 10.96.158.98 <none> 6379/TCP 18m
argocd-repo-server ClusterIP 10.111.153.43 <none> 8081/TCP,8084/TCP 18m
argocd-server ClusterIP 10.98.129.33 <none> 80/TCP,443/TCP 18m
argocd-server-metrics ClusterIP 10.110.107.116 <none> 8083/TCP 18m

获取密码 kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

下载 argocd cli 可以通过命令行直接控制

cli 登录

1
2
3
4
$ argocd login 10.98.129.33 --username admin
Password:
'admin:login' logged in successfully
Context '10.98.129.33' updated

cli 修改密码

1
2
3
4
5
6
$ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context '10.98.129.33' updated

argocd-server Service 加个 Ingress 再配个负载均衡加个二级域名解析,就直接略过了,可以参考之前的文章。也可以通过暴露 Node port 方式访问。

dashboard

登录之后 Applications 还是空的,目前也没有中文界面。

创建 Projects

先创建一个 Projects,SOURCE REPOSITORIES 可以限制仓库来源,DESTINATIONS 部署到的目标集群限制,CLUSTER RESOURCENAMESPACE RESOURCE 资源权限限制,先都直接给 * 想细分可以直接细化。
NEW PROJECT
NEW PROJECT

创建 repo

可以选择 ssh, https 方式,在配置中加上 gitops 仓库地址,Project 选择刚才添加的 nico。
Connect Repo using HTTPS

创建 App

在 Applications 中新增 App,可以通过 EDIT AS YAML 直接编辑。
NEW APP
SYNC POLICY 同步策略,可以选择自动或手动

  • PRUNE RESOURCES 是否清理未定义资源,参考 No Prune Resources
  • SELF HEAL 自动修复,当集群中应用与定义不符时自动修复

SYNC OPTIONS

  • SKIP SCHEMA VALIDATION 跳过验证也就是 kubectl apply --validate=false
  • AUTO-CREATE NAMESPACE 没啥可说的
  • PRUNE LAST 对资源进行修剪时建议勾选,参考 Allow resource pruning to be an implicit final wave of a sync operation
  • APPLY OUT OF SYNC ONLY 只同步不同步的资源。目前,当使用自动同步 ArgoCD 进行同步时,会应用应用程序中的每个对象。 对于包含数千个对象的应用程序,这需要相当长的时间,并对 api 服务器施加过大的压力。
  • RESPECT IGNORE DIFFERENCES 是否在同步的时候也忽略 spec.ignoreDifferences 差异配置。默认情况下 spec.ignoreDifferences 配置仅用于计算实时状态和期望状态之间的差异。

PRUNE PROPAGATION POLICY 集联删除策略,分为三种。文档上看默认是 background 详情参考 cascading-deletion

  • foreground 前台,先标记删除资源本身,然后删除所有关联子资源,再删除资源本身。
  • background 后台,直接删除资源本身,再处理关联子资源。
  • orphan 孤儿模式,直接删除资源本身,子资源垃圾回收器处理。

REPLACE 使用 kubectl replace/create 代替 kubectl apply
RETRY 重试配置

NEW APP
Path 可指定要配置文件目录
最下面为部署时的工具配置,可以选择 DirectoryHelmKustomizePlugin

创建完成

同步时机

argocd 默认每三分钟会检查一次仓库是否有新的修改,如果想要实时更新可以通过 webhook 通知 argocd。但是目前 argocd webhook 仅支持 GitHub, Bitbucket, GitLab, Gogs。对于未支持的 git 服务配置 webhook 会返回 Unknown webhook event 见此,clone 下来可以自己适配下 onedev webhook 也不算太麻烦。当然也可以在页面手动更新。
默认轮询间隔配置可以通过 argocd-cm Configmaptimeout.reconciliation 修改,如果想禁用设成 0s 即可,这里我改成 30s 看下效果。yaml 参考 argocd-cm.yaml

1
$ kubectl edit configmap argocd-cm -n argocd

现在我修改下 wx-msg-push 代码,push 一个新 tag,就会触发整个流程。最终通过 argocd 部署新版本应用,在 k8s 中对该应用进行修改导致与配置定义不一致的行为都会自动修复。
APP

可以看到部署的历史详情,还可以进行回滚,回滚会禁用自动同步,可以再手动开启。
History and rollback

总结

本文实践了 Argo CD 全程基本通过 web ui 操作,也可以通过 cli 操作。其中 webhook 只支持几个大牌 git,如果使用未支持的 git 服务,建议自行适配,如果不想侵入修改也可以编写远程脚本执行 argocd cli 来触发,达到同样的效果。timeout.reconciliation 建议直接禁用就好了。
Argo CD 不止于此,还有更多使用姿势及配置请通过官方文档了解。