来自社区用户 willqy 的分享
argo cd 是用于 kubernetes 的声明性 gitops 持续交付工具,应用程序定义,配置和环境应为声明性的,并应受版本控制,应用程序部署和生命周期管理应该是自动化、可审核且易于理解。
argo cd 遵循 gitops 模式,该模式使用 git 仓库作为定义所需应用程序状态的真实来源。
argo cd 可在指定的目标环境中自动部署所需的应用程序状态,应用程序部署可以在 git 提交时跟踪对分支,标签的更新,或固定到清单的特定版本。
官网:https://argoproj.github.io/
argo cd 架构图:
argo cd 被实现为 kubernetes 控制器,该控制器持续监视正在运行的应用程序,并将当前的活动状态与所需的目标状态(在 git 存储库中指定)进行比较。当已部署应用程序的运行状态偏离目标状态时将被 argo cd 视为 outofsync。
argo cd 报告并可视化差异,同时提供了自动或手动将实时状态同步回所需目标状态的功能。在 git 存储库中对所需目标状态所做的任何修改都可以自动应用并同步到指定的目标环境中。
argo cd 支持的 kubernetes 配置清单包括 helm charts、kustomize 或纯 yaml/json 文件等。
本篇文章涉及内容:
使用 kubesphere devops 实现 ci 部分, cd 部分由 argo cd 完成;
argo cd 持续监测 git 仓库某个目录下 yaml 文件变动,自动将 yaml 文件部署到 k8s 集群;
argo cd 持续监测 harbor 镜像仓库某个镜像 tag 变动,自动将最新镜像部署到 k8s 集群。
基本原理图:
准备 2 个 git 仓库,一个源码仓库,一个 yaml 文件仓库,源码和 yaml 文件分离。
源码仓库可参考以下链接,离线环境原因,这里选择第二个示例 spring-demo:
https://github.com/kubesphere/devops-java-sample
https://github.com/willzhang/spring-demo
yaml 文件仓库可参考以下链接,这里命名为 argocd-gitops:
https://github.com/argoproj/argocd-example-apps
yaml 仓库下创建 javademo 目录,并创建 2 个简单的 yaml 文件:
javademo-deployment.yaml 示例,当前镜像 tag 可随意指定,执行 ci 时会实时替换该参数:
javademo-svc.yaml
argo cd 有多种部署方式,可以直接部署 yaml 文件.
这里使用 helm 方式部署,可直接指定 argo cd server service 类型 nodeport:
查看运行的 pod:
如果使用 kubesphere 部署 argo cd,首先需要配置 argo cd helm 仓库,进入企业空间,选择应用模板上传离线 helm chart 包,或在应用仓库配置公网 helm repo 地址。
完成后进入项目,点击部署新应用,选择 argo cd helm chart 进行部署即可:
要与 argo cd api server 进行交互,我们需要安装 cli 命令:
如果上面 argo cd 使用 yaml 方式部署,修改 serivce 类型为 nodeport,以便访问 argo cd api server
查看 argo cd server service,记录 nodeport 信息:
argo cd 默认登录用户为 admin,初始密码为 argocd-server pod 名称,获取 pod 名称
使用 argo cd cli 登录,以 nodeip 和 nodeport 作为 argo cd server 登录地址:
修改默认密码:
浏览器登录 argo cd ui:
登陆 argo cd ui 后,选择 new app 创建 application,选择 edit as ayml:
粘贴以下内容,save 后点击左上 create,当然也可以直接使用 kubectl apply 命令执行以下内容,效果相同。
参数说明:
metadata 字段:指定了应用名称,命名空间必须指定 argo cd,添加 finalizers 字段可在删除应用时级联删除相关 k8s 资源;
source 字段:指定了 yaml 文件所在 git 仓库 url,及要监测的 yaml 文件存放目录,该目录下文件有任何变更 argo cd 都会自动将其更新部署到 k8s 集群;
destination 字段:指定监测的 yaml 文件要部署到哪个 k8s 集群及哪个命名空间下;
syncpolicy 字段:指定自动同步策略和频率,不配置时需要手动触发同步。
另外如果使用私有 git 仓库,需要创建凭证,这里的凭证是 argo cd 访问 yaml 文件 git 仓库的凭证:
等效的 argo cd cli 命令:
创建后 argo cd 会自动将 git 仓库 javademo 目录下的 yaml 文件部署到 k8s 集群,此时应用无法正常启动,因为 yaml 文件中的镜像 tag 还不存在,拉取镜像会失败:
也可以使用 argo cd cli 查看部署的应用:
在 kubesphere ui 查看 pod 状态,一直在重试拉取镜像:
使用 kubectl 命令查看,状态为 imagepullbackoff :
创建 ci 流水线,使用 kubesphere devops 完成源码编译、镜像构建并推送到 harbor 仓库,最后以 git commit 方式更新 yaml 仓库中 image 字段。
由于此时 argo cd 持续监测 yaml 仓库配置文件变动,当 ci 部分执行 git push 时便会触发 argo cd 更新 yaml 文件到 k8s 集群。
在 kubesphere devops 工程下创建一条空流水线,命名为 javademo,进入流水线,选择编辑 jenkinsfile,复制以下内容:
注意修改相关参数,流水线中引用了 2 个凭证:
git_credential_id 为内网 gogs git 仓库账号密码
registry_credential_id 为 harbor 仓库账号密码
运行流水线前需要在 devops 工程下提前创建好相关凭证,后续需要在 jenkinsfile 中引用。
最终流水线如下,点击运行,等待流水线执行完成,查看状态为成功:
查看流水线构建日志,可以看到执行了以下过程,其中最后 update docker tag 步骤,执行了 2 个关键操作,sed 命令替换镜像 tag,然后执行 git push 更新 yaml 仓库。
查看推送到 harbor 仓库的镜像:
argo cd 监测到 yaml 文件变更后更新至 k8s 集群:
argo cd ui 查看使用的镜像:
登录 kubesphere ui 查看应用状态为运行中:
在 git 仓库直接修改 yaml 文件配置,同样能够触发 argo cd 同步,例如将 service 类型改为 nodeport:
等待 argo cd 自动同步配置更新到 k8s 集群,浏览器以 nodeport 方式访问 java web 应用:
上面演示了基于 git 仓库变更作为应用部署的事实来源,下面演示另一种方式,以镜像 tag 变更作为应用部署的事实来源。argo cd 提供了<code>argo cd image updater</code>小工具,用于实现该操作。
argo cd image updater 是一种自动更新由 argo cd 管理的 kubernetes 工作负载容器镜像的工具。
该工具目前还在开发中,并且有以下特性和局限性:
只能更新由 argo cd 管理并由helm或kustomize工具生成的应用程序的镜像;
对广泛使用的容器仓库的默认支持:dockerhub、harbor 私有镜像仓库等;
能够使用匹配器功能过滤镜像仓库返回的标签列表;
镜像拉取 secrets 必须存在于 argo cd image updater 在其中运行(或可以访问)的同一 kubernetes 群集中。当前不可能从其他集群中获取这些 secrets。
在当前版本中,argo cd image updater 不会将任何更改写回到 git 存储库。
官方文档:
https://argocd-image-updater.readthedocs.io/en/stable/
argo cd image updater 部署略显繁琐,部署操作如下:
1、在 argo cd 中创建本地用户
创建 argo cd 镜像更新程序需要访问 argo cd api server 的凭据,使用一个 image-updater 具有适当 api 权限的帐户,将以下用户定义添加到 argocd-cm:
为用户创建访问令牌,将令牌的值复制到某个地方,稍后将需要它。
2、在 argo cd 中授予 rbac 权限
为<code>image-updater</code>用户配置适当的 rbac 权限,argo cd image updater 需要应用程序的<code>update</code>和<code>get</code>权限。
3、 安装 argo cd image updater
yaml 文件下载:https://github.com/argoproj-labs/argocd-image-updater/tree/master/manifests
4、 配置镜像仓库
即使您不打算使用私有镜像仓库,您也需要至少配置一个 empty <code>registries.conf</code>:
没有此条目<code>argocd-image-updater</code> pod 将无法启动。
如果使用私有镜像仓库可参考以下配置,以 harbor 镜像仓库为例:
5、 配置 api 访问令牌密钥
当从清单安装到 kubernetes 集群时,argo cd image updater 将从名为<code>argo cd_token</code>的环境变量中读取访问 argo cd api 所需的令牌,该环境变量是从名为 <code>argo cd.token</code> 的 secret 字段中设置的<code>argocd-image-updater-secret</code>。
<code>argo cd.token</code> 的值应设置为您上面生成的访问令牌的 base64 编码值。作为一种捷径,您可以使用 <code>kubectl</code> 生成密钥,并将其应用于现有资源:
更改后,必须重新启动 <code>argocd-image-updater</code> pod,即运行
新建 yaml 仓库 kustomize 文件
由于 image updater 仅支持 helm 或 kustomize 类型 yaml,这里新建一个基于 kustomize 的 yaml 目录,修改 yaml 中的参数不要与之前的冲突即可:
javademo-deployment.yaml
kustomization.yaml
登录 argo cd ui 新建一个 argo cd 应用,和之前相比增加了 annotations 参数,指定要监测的镜像地址,更新策略为 latest,另外修改了 source path:
登录 kubesphere ui 重新创建一条 ci 流水线,删除 update docker tag 步骤即可,已经不需要基于 git push 来触发应用部署了:
查看流水线日志,镜像成功推送到 harbor 仓库:
harbor 仓库镜像 tag 更新,argo cd image updater 自动将最新 tag 更新到 k8s 集群。
查看镜像 tag:
以后每次 harbor 仓库生成最新镜像,argo cd 都会自动将其更新到 k8s 集群。