1.简介
Argo 英 [ˈɑ:ɡəu] 美 [ˈɑrˌɡo]
Kubernetes 原生工具,用于运行工作流程、管理集群以及正确执行 GitOps。
Argo 于 2020 年 3 月 26 日被 CNCF 接受为孵化成熟度级别,然后于 2022 年 12 月 6 日转移到毕业成熟度级别。
manifest 清单
UK /ˈmæn.ɪ.fest/
US /ˈmæn.ə.fest/
2.什么是Argo CD
Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。
2.1.为什么选择 Argo CD?
- 应用程序定义、配置和环境应该是声明性的和版本控制的。
- 应用程序部署和生命周期管理应该是自动化、可审计且易于理解的。
2.2.演示示例
3.概要
3.1.快速开始
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
3.2.工作原理
Argo CD 遵循 GitOps 模式,使用 Git 存储库作为定义所需应用程序状态的真实来源。Kubernetes 清单(manifests)可以通过多种方式指定:
Argo CD 可自动在指定的目标环境中部署所需的应用程序状态。应用程序部署可以跟踪 Git 提交时对分支、标签或固定到特定版本清单的更新。有关可用的不同跟踪策略的更多详细信息,请参阅跟踪策略。
3.3.架构
Argo CD 被实现为 Kubernetes 控制器,它持续监控正在运行的应用程序并将当前实时状态与所需目标状态(如 Git 存储库中指定)进行比较。如果已部署应用程序的实时状态与目标状态有偏差,则视为 OutOfSync。Argo CD 报告并可视化差异,同时提供将实时状态自动或手动同步回所需目标状态的功能。对 Git 存储库中所需目标状态所做的任何修改都可以自动应用并反映在指定的目标环境中。
3.4.特征
- 自动将应用程序部署到指定的目标环境
- 支持多种配置管理/模板工具(Kustomize、Helm、Jsonnet、plain-YAML)
- 能够管理和部署到多个集群
- SSO 集成(OIDC、OAuth2、LDAP、SAML 2.0、GitHub、GitLab、Microsoft、LinkedIn)
- 多租户和 RBAC 授权策略
- 回滚/随处回滚至 Git 存储库中提交的任何应用程序配置
- 应用资源健康状态分析
- 自动配置漂移检测和可视化
- 自动或手动同步应用程序至所需状态
- Web UI 提供应用程序活动的实时视图
- 用于自动化和 CI 集成的 CLI
- Webhook 集成(GitHub、BitBucket、GitLab)
- 自动化访问令牌
- PreSync、Sync、PostSync 挂钩支持复杂的应用程序推出(例如蓝/绿和金丝雀升级)
- 应用程序事件和 API 调用的审计跟踪
- Prometheus 指标
- 用于覆盖 Git 中的 helm 参数的参数覆盖
3.5.发布版本
4.基本原理
在有效使用 Argo CD 之前,有必要了解该平台所基于的底层技术。还需要了解提供给您的功能及其使用方法。以下部分提供了一些有用的链接来帮助您加深这种理解。
5.核心概念
以下是一些特定于 Argo CD 的概念。
- 应用程序:清单(manifest)定义的一组 Kubernetes 资源。这是一个自定义资源定义 (CRD)。
- 应用程序源类型:用于构建应用程序的工具。
- 目标状态:应用程序的所需状态,以 Git 存储库中的文件表示。
- 实时状态:该应用程序的实时状态。部署了哪些 pod 等。
- 同步状态:实时状态是否与目标状态匹配。部署的应用程序是否与 Git 所说的一致?
- 同步:使应用程序移动到其目标状态的过程。例如,通过将更改应用于 Kubernetes 集群。
- 同步操作状态:同步是否成功。
- 刷新:将 Git 中的最新代码与实时状态进行比较。找出不同之处。
- 健康:应用程序的健康状况,是否正常运行? 是否可以处理请求?
- 工具:从文件目录创建清单(manifest)的工具。例如 Kustomize。请参阅应用程序源类型。
- 配置管理工具:请参阅工具。
- 配置管理插件:自定义工具。
6.入门
6.1.前提条件
- 已安装 kubectl 命令行工具
- 有一个 kubeconfig 文件(默认位置是
~/.kube/config
) - CoreDNS:通过
microk8s enable dns && microk8s stop && microk8s start
启用
1.安装 Argo CD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
这将创建一个新的命名空间 argocd,Argo CD 服务和应用程序资源将驻留在其中。
安装清单包括引用 argocd 命名空间的 ClusterRoleBinding 资源。如果您要将 Argo CD 安装到其他命名空间,请确保更新命名空间引用。
如果您对 UI、SSO 和多集群功能不感兴趣,那么您可以只安装核心 Argo CD 组件。
此默认安装将具有自签名证书,如果不进行额外工作则无法访问。请执行以下任一操作:
- 按照说明配置证书(并确保客户端操作系统信任它)。
- 配置客户端操作系统以信任自签名证书。
- 在本指南的所有 Argo CD CLI 操作中使用
--insecure
标志。
kubectl config
的默认命名空间必须设置为argocd
。这仅适用于以下命令,因为前面的命令已经有-n argocd
:kubectl config set-context --current --namespace=argocd
使用 argocd login --core
配置 CLI 访问并跳过步骤 3-5。
Redis 的默认安装使用密码验证。Redis 密码存储在安装 Argo CD 的命名空间中的 Kubernetes 机密 argocd-redis
中,密钥为 auth
。
2.下载 Argo CD CLI
下载 最新的 Argo CD 版本。可以通过 CLI 安装文档 找到更详细的安装说明。
也可在 Mac、Linux 和 WSL Homebrew 中使用:
brew install argocd
3.访问 Argo CD API 服务器
默认情况下,Argo CD API 服务器不会通过外部 IP 公开。要访问 API 服务器,请选择以下技术之一来公开 Argo CD API 服务器:
服务类型负载均衡器
将argocd-server
服务类型更改为LoadBalancer
:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Ingress 容器注册表
按照入口文档 了解如何使用入口配置 Argo CD。
转发端口
Kubectl 端口转发也可用于连接 API 服务器而无需公开服务。
kubectl port-forward svc/argocd-server -n argocd 8080:443
然后可以使用 https://localhost:8080 访问 API 服务器
4.使用 CLI 登录
admin
帐户的初始密码是自动生成的,并以明文形式存储在 Argo CD 安装命名空间中名为 argocd-initial-admin-secret
的机密中的password
字段中。您可以使用 argocd CLI 轻松检索此密码:
argocd admin initial-password -n argocd
更改密码后,您应该从 Argo CD 命名空间中删除
argocd-initial-admin-secret
。该密钥除了以明文形式存储最初生成的密码外,没有其他用途,并且可以随时安全地删除。如果必须重新生成新的管理员密码,Argo CD 将根据需要重新创建它。
使用上面的用户名admin
和密码登录 Argo CD 的 IP 或主机名:
argocd login <ARGOCD_SERVER>
CLI 环境必须能够与 Argo CD API 服务器通信。如果无法按照上述步骤 3 中的说明直接访问,您可以通过以下机制之一告诉 CLI 使用端口转发来访问它:
- 向每个 CLI 命令添加
--port-forward-namespace argocd
标志;
或 2) 设置 ARGOCD_OPTS 环境变量:export ARGOCD_OPTS='--port-forward-namespace argocd'
。
使用以下命令更改密码:
argocd account update-password
5.注册集群以部署应用程序(可选)
此步骤将集群的凭据注册到 Argo CD,并且仅在部署到外部集群时才需要。在内部部署时(部署到 Argo CD 正在运行的同一集群),应使用 https://kubernetes.default.svc
作为应用程序的 K8s API 服务器地址。
首先列出当前 kubeconfig 中的所有集群上下文:
kubectl config get-contexts -o name
从列表中选择一个上下文名称并将其提供给 argocd cluster add CONTEXTNAME
。例如,对于 docker-desktop 上下文,运行:
argocd cluster add docker-desktop
上述命令将 ServiceAccount (argocd-manager) 安装到该 kubectl 上下文的 kube-system 命名空间中,并将服务帐户绑定到管理员级别的 ClusterRole。Argo CD 使用此服务帐户令牌执行其管理任务(即部署/监控)。
argocd-manager-role
角色的规则可以修改,使其仅对有限的命名空间、组和种类具有create, update, patch, delete
权限。但是,在集群范围内,get, list, watch
权限是 Argo CD 正常运行所必需的。
6.从 Git 存储库创建应用程序
包含留言簿应用程序的示例存储库可在 https://github.com/argoproj/argocd-example-apps.git
上找到,以演示 Argo CD 的工作原理。
通过 CLI 创建应用程序
首先,我们需要运行以下命令将当前命名空间设置为 argocd:
kubectl config set-context --current --namespace=argocd
使用以下命令创建示例留言簿应用程序:
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
通过 UI 创建应用程序
打开浏览器进入 Argo CD 外部 UI,通过访问浏览器中的 IP/主机名并使用步骤 4 中设置的凭据登录。
登录后,点击+ New App按钮,如下图:
将您的应用命名为 guestbook,使用项目默认值,并将同步策略保留为手动:
通过将存储库 URL 设置为 github 存储库 URL,将 https://github.com/argoproj/argocd-example-apps.git
存储库连接到 Argo CD,将修订保留为 HEAD,并将路径设置为 guestbook
:
对于目标,将集群 URL 设置为 https://kubernetes.default.svc
(或集群名称为集群内)并将命名空间设置为默认值:
填写完以上信息后,点击UI顶部的Create,创建留言簿应用:
7.同步(部署)应用程序
通过 CLI 同步
一旦创建了留言簿应用程序,您现在可以查看其状态:
$ argocd app get guestbook
Name: guestbook
Server: https://kubernetes.default.svc
Namespace: default
URL: https://10.97.164.88/applications/guestbook
Repo: https://github.com/argoproj/argocd-example-apps.git
Target:
Path: guestbook
Sync Policy: <none>
Sync Status: OutOfSync from (1ff8a67)
Health Status: Missing
GROUP KIND NAMESPACE NAME STATUS HEALTH
apps Deployment default guestbook-ui OutOfSync Missing
Service default guestbook-ui OutOfSync Missing
应用程序状态最初处于 OutOfSync 状态,因为应用程序尚未部署,并且尚未创建任何 Kubernetes 资源。要同步(部署)应用程序,请运行:
argocd app sync guestbook
此命令从存储库检索清单并执行清单的 kubectl apply
。留言簿应用现已运行,您现在可以查看其资源组件、日志、事件和评估的健康状况。
通过 UI 同步
7.操作手册
本指南适用于想要为其他开发人员安装和配置 Argo CD 的管理员和操作员。
请确保您已完成入门指南。
7.1.架构概述
7.2.组件
API Server
API 服务器是一个 gRPC/REST
服务器,用于公开 Web UI
、CLI
和 CI/CD
系统使用的 API。它具有以下职责:
- 应用程序管理和状态报告
- 调用应用程序操作(例如同步、回滚、用户定义的操作)
- 存储库和集群凭证管理(存储为 K8s 密钥)
- 身份验证和授权委托给外部身份提供商
- RBAC 实施
- Git webhook 事件的监听器/转发器
Repository Server
存储库服务器是一项内部服务,它维护保存应用程序清单的 Git 存储库的本地缓存。它负责在提供以下输入时生成并返回 Kubernetes 清单:
- repository URL
- revision (commit, tag, branch)
- 应用程序路径
- 模板特定设置:参数、helm values.yaml
Application Controller
应用程序控制器是一个 Kubernetes 控制器,它持续监控正在运行的应用程序,并将当前实时状态与所需的目标状态(如存储库中指定)进行比较。它检测 OutOfSync 应用程序状态并选择性地采取纠正措施。它负责调用任何用户定义的生命周期事件钩子(PreSync、Sync、PostSync)
7.3.安装
Argo CD 有两种安装类型:多租户和核心。
多租户(Multi-Tenant)
多租户安装是安装 Argo CD 最常见的方式。这种安装类型通常用于为组织中的多个应用程序开发团队提供服务,并由平台团队维护。
最终用户可以使用 Web UI 或 argocd CLI 通过 API 服务器访问 Argo CD。必须使用 argocd login <server-host>
命令配置 argocd CLI(在此处了解更多信息)。
提供了两种类型的安装清单:
非高可用性
不建议用于生产用途。此类安装通常在评估期间用于演示和测试。
- install.yaml : 具有集群管理员访问权限的标准 Argo CD 安装。如果您计划使用 Argo CD 在 Argo CD 运行的同一集群中部署应用程序(即
kubernetes.svc.default
),请使用此清单集。它仍将能够使用输入的凭据部署到外部集群。 - namespace-install.yaml : 安装 Argo CD 仅需要命名空间级别权限(不需要集群角色)。如果您不需要 Argo CD 在 Argo CD 运行的同一集群中部署应用程序,请使用此清单集,并且将仅依赖于输入的集群凭据。使用此清单集的一个示例是,如果您为不同的团队运行多个 Argo CD 实例,其中每个实例都将将应用程序部署到外部集群。仍然可以使用输入的凭据(即
argocd cluster add <CONTEXT> --in-cluster --namespace <YOUR NAMESPACE>
)部署到同一集群(kubernetes.svc.default
)。
注意:Argo CD CRD 不包含在
namespace-install.yaml
中,必须单独安装。CRD 清单位于manifests/crds
目录中。使用以下命令安装它们:kubectl apply -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable
高可用性
建议在生产中使用高可用性安装。此软件包包含相同的组件,但针对高可用性和弹性进行了调整。
- ha/install.yaml : 与
install.yaml
相同,但支持多个组件的副本。 - ha/namespace-install.yaml : 与
namespace-install.yaml
相同,但具有支持组件的多个副本。
核心(Core)
Argo CD Core 安装主要用于以无头模式部署 Argo CD。这种安装类型最适合独立使用 Argo CD 且不需要多租户功能的集群管理员。此安装包含的组件较少,设置起来也更简单。该软件包不包含 API 服务器或 UI,并安装每个组件的轻量级(非 HA)版本。
安装清单可在 core-install.yaml 中找到。
有关 Argo CD Core 的更多详细信息,请参阅官方文档
Kustomize
UK /ˈkʌs.tə.maɪzd/
US /ˈkʌs.tə.maɪzd/
Argo CD 清单也可以使用 Kustomize 安装。建议将清单作为远程资源包含在内,并使用 Kustomize 补丁应用其他自定义功能。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd
resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/v2.7.2/manifests/install.yaml
有关示例,请参阅用于部署 Argoproj CI/CD 基础设施的 kustomization.yaml
。
Helm
UK US /helm/
可以使用 Helm 安装 Argo CD。Helm 图表目前由社区维护,可在 argo-helm/charts/argo-cd 上找到。
支持的版本
下表显示了使用每个版本的 Argo CD 测试的 Kubernetes 版本。
Argo CD version | Kubernetes versions |
---|---|
2.11 | v1.29, v1.28, v1.27, v1.26, v1.25 |
2.10 | v1.28, v1.27, v1.26, v1.25 |
2.9 | v1.28, v1.27, v1.26, v1.25 |
7.4.Argo CD 核心
介绍
Argo CD Core 是一个不同的安装,它以无头模式运行 Argo CD。通过此安装,您将拥有一个功能齐全的 GitOps 引擎,能够从 Git 存储库获取所需状态并将其应用于 Kubernetes。
以下功能组在此安装中不可用:
- Argo CD RBAC 模型
- Argo CD API
- OIDC 基于身份验证
以下功能将部分可用:
- Argo CD Web UI
- Argo CD CLI
- Multi-tenancy (严格基于 git push 权限的 GitOps)
运行 Argo CD Core 的一些用例包括:
- 作为集群管理员,我只想依赖 Kubernetes RBAC。
- 作为一名 DevOps 工程师,我不想学习新的 API 或依赖其他 CLI 来自动化部署。我只想依赖 Kubernetes API。
- 作为集群管理员,我不想向开发人员提供 Argo CD UI 或 Argo CD CLI。
架构
由于 Argo CD 在设计时就考虑到了基于组件的架构,因此可以实现更简约的安装。在这种情况下,安装的组件较少,但主要的 GitOps 功能仍可正常运行。
下图中的核心框显示了选择 Argo CD Core 时将安装的组件:
请注意,即使 Argo CD 控制器可以在没有 Redis 的情况下运行,也不建议这样做。Argo CD 控制器使用 Redis 作为重要的缓存机制,以减少 Kube API 和 Git 中的负载。因此,此安装方法中也包含 Redis。
安装
可以通过应用包含所有必需资源的单个清单文件来安装 Argo CD Core。
举例:
export ARGOCD_VERSION=<desired argo cd release version (e.g. v2.7.0)>
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/$ARGOCD_VERSION/manifests/core-install.yaml
使用
安装 Argo CD Core 后,用户将能够通过 GitOps 与其进行交互。可用的 Kubernetes 资源将是Application
和 ApplicationSet
CRD。通过使用这些资源,用户将能够在 Kubernetes 中部署和管理应用程序。
即使在运行 Argo CD Core 时,仍然可以使用 Argo CD CLI。在这种情况下,CLI 将生成一个本地 API 服务器进程,用于处理 CLI 命令。命令结束后,本地 API 服务器进程也将终止。这对于用户来说是透明的,无需其他命令。请注意,Argo CD Core 将仅依赖 Kubernetes RBAC,并且调用 CLI 的用户(或进程)需要具有在Application
和 ApplicationSet
资源中执行给定命令的适当权限才能访问 Argo CD 命名空间。
举例:
kubectl config set-context --current --namespace=argocd # change current kube context to argocd namespace
argocd login --core
同样,如果用户喜欢使用此方法与 Argo CD 交互,他们也可以在本地运行 Web UI。可以通过运行以下命令在本地启动 Web UI:
argocd admin dashboard -n argocd
Argo CD Web UI 将在 http://localhost:8080
上提供
7.5.声明式启动
可以使用 Kubernetes 清单(manifests)以声明方式定义 Argo CD 应用程序、项目和设置。可以使用 kubectl apply
更新这些内容,而无需接触 argocd
命令行工具。
快速参考
所有资源,包括Application
和 AppProject
规范,都必须安装在 Argo CD 命名空间中(默认为 argocd
)。
原子配置
示例文件 | 资源名称 | 种类(Kind) | 描述 |
---|---|---|---|
argocd-cm.yaml | argocd-cm | ConfigMap | 通用 Argo CD 配置 |
argocd-repositories.yaml | my-private-repo / istio-helm-repo / private-helm-repo / private-repo | Secrets | 示例存储库连接详细信息 |
argocd-repo-creds.yaml | argoproj-https-creds / argoproj-ssh-creds / github-creds / github-enterprise-creds | Secrets | 示例存储库凭证模板 |
argocd-cmd-params-cm.yaml | argocd-cmd-params-cm | ConfigMap | Argo CD 环境变量配置 |
argocd-secret.yaml | argocd-secret | Secret | 用户密码、证书(已弃用)、签名密钥、Dex 机密、Webhook 机密 |
argocd-rbac-cm.yaml | argocd-rbac-cm | ConfigMap | RBAC 配置 |
argocd-tls-certs-cm.yaml | argocd-tls-certs-cm | ConfigMap | 用于通过 HTTPS 连接 Git 存储库的自定义 TLS 证书(v1.2 及更高版本) |
argocd-ssh-known-hosts-cm.yaml | argocd-ssh-known-hosts-cm | ConfigMap | 通过 SSH 连接 Git 存储库的 SSH 已知主机数据(v1.2 及更高版本) |
对于每种特定类型的 ConfigMap 和 Secret 资源,只有一个受支持的资源名称(如上表所列)——如果您需要合并,则需要在创建它们之前进行合并。
请务必使用标签
app.kubernetes.io/part-of: argocd
注释您的 ConfigMap 资源,否则 Argo CD 将无法使用它们。
多个配置对象
示例文件 | 种类(Kind) | 描述 |
---|---|---|
application.yaml | Application | 应用程序规范示例 |
project.yaml | AppProject | 项目规格示例 |
- | Secret | 存储库凭据 |
对于Application
和 AppProject
资源,资源的名称等于 Argo CD 中应用程序或项目的名称。这也意味着应用程序和项目名称在给定的 Argo CD 安装中是唯一的 - 两个不同的应用程序不能使用相同的应用程序名称。
Applications
应用程序 CRD 是代表环境中已部署的应用程序实例的 Kubernetes 资源对象。它由两条关键信息定义:
source
引用 Git 中所需的状态(repository, revision, path, environment)destination
引用目标集群和命名空间。对于集群,可以使用服务器或名称之一,但不能同时使用(这将导致错误)。当服务器缺失时,它会根据名称进行计算并用于任何操作。
最小应用程序规范如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
请参阅 application.yaml 以了解其他字段。只要您已完成入门的第一步,就可以使用 kubectl apply -n argocd -f application.yaml
应用此文件,然后 Argo CD 将开始部署留言簿应用程序。
命名空间必须与您的 Argo CD 实例的命名空间相匹配 - 通常是
argocd
。
从 Helm 存储库创建应用程序时,必须指定
chart
属性,而不是spec.source
中的path
属性。
spec:
source:
repoURL: https://argoproj.github.io/argo-helm
chart: argo
如果没有
resources-finalizer.argocd.argoproj.io
终结器,删除应用程序不会删除其管理的资源。要执行级联删除,您必须添加终结器。请参阅应用程序删除。
metadata:
finalizers:
- resources-finalizer.argocd.argoproj.io
应用程序的应用程序
您可以创建一个应用来创建其他应用,而这些应用又可以创建其他应用。这样就可以声明性地管理一组可以同时部署和配置的应用。
参见集群引导。
Projects
AppProject CRD 是代表应用程序逻辑分组的 Kubernetes 资源对象。它由以下关键信息定义:
sourceRepos
项目内的应用程序可以从中提取清单的存储库。destinations
项目内的应用程序可以部署到的集群和命名空间。roles
角色列表,其中定义了它们对项目内资源的访问权限。
如果项目的目标配置允许部署到安装了 Argo CD 的命名空间,则该项目下的应用程序具有管理员级访问权限。应严格限制对管理员级项目的 RBAC access,并且对允许的
sourceRepos
的推送访问权限应仅限于管理员。
示例规范如下:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: my-project
namespace: argocd
# Finalizer that ensures that project is not deleted until it is not referenced by any application
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
description: Example Project
# Allow manifests to deploy from any Git repos
sourceRepos:
- '*'
# Only permit applications to deploy to the guestbook namespace in the same cluster
destinations:
- namespace: guestbook
server: https://kubernetes.default.svc
# Deny all cluster-scoped resources from being created, except for Namespace
clusterResourceWhitelist:
- group: ''
kind: Namespace
# Allow all namespaced-scoped resources to be created, except for ResourceQuota, LimitRange, NetworkPolicy
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota
- group: ''
kind: LimitRange
- group: ''
kind: NetworkPolicy
# Deny all namespaced-scoped resources from being created, except for Deployment and StatefulSet
namespaceResourceWhitelist:
- group: 'apps'
kind: Deployment
- group: 'apps'
kind: StatefulSet
roles:
# A role which provides read-only access to all applications in the project
- name: read-only
description: Read-only privileges to my-project
policies:
- p, proj:my-project:read-only, applications, get, my-project/*, allow
groups:
- my-oidc-group
# A role which provides sync privileges to only the guestbook-dev application, e.g. to provide
# sync privileges to a CI system
- name: ci-role
description: Sync privileges for guestbook-dev
policies:
- p, proj:my-project:ci-role, applications, sync, my-project/guestbook-dev, allow
# NOTE: JWT tokens can only be generated by the API server and the token is not persisted
# anywhere by Argo CD. It can be prematurely revoked by removing the entry from this list.
jwtTokens:
- iat: 1535390316
Repositories
一些 Git 托管商(尤其是 GitLab 以及可能还有本地 GitLab 实例)要求您在存储库 URL 中指定
.git
后缀,否则它们将向以.git
为后缀的存储库 URL 发送 HTTP 301 重定向。Argo CD 不会遵循这些重定向,因此您必须调整存储库 URL 以使其以.git
为后缀。
存储库详细信息存储在密钥中。要配置存储库,请创建包含存储库详细信息的密钥。考虑使用 bitnami-labs/sealed-secrets
将加密的密钥定义存储为 Kubernetes 清单。每个存储库都必须有一个 url 字段,并且根据使用 HTTPS、SSH 还是 GitHub App 进行连接,必须有username
和password
(对于 HTTPS)、sshPrivateKey
(对于 SSH)或 githubAppPrivateKey
(对于 GitHub App)。
使用
bitnami-labs/sealed-secrets
时,标签将被删除,并且必须按照此处所述重新添加:https://github.com/bitnami-labs/sealed-secrets#sealedsecrets-as-templates-for-secrets
HTTPS 示例:
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
password: my-password
username: my-username
SSH 示例:
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: git@github.com:argoproj/my-private-repository.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
GitHub 应用程序示例:
apiVersion: v1
kind: Secret
metadata:
name: github-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/my-private-repository
githubAppID: 1
githubAppInstallationID: 2
githubAppPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
---
apiVersion: v1
kind: Secret
metadata:
name: github-enterprise-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://ghe.example.com/argoproj/my-private-repository
githubAppID: 1
githubAppInstallationID: 2
githubAppEnterpriseBaseUrl: https://ghe.example.com/api/v3
githubAppPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Google Cloud Source 存储库示例:
kind: Secret
metadata:
name: github-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://source.developers.google.com/p/my-google-project/r/my-repo
gcpServiceAccountKey: |
{
"type": "service_account",
"project_id": "my-google-project",
"private_key_id": "REDACTED",
"private_key": "-----BEGIN PRIVATE KEY-----\nREDACTED\n-----END PRIVATE KEY-----\n",
"client_email": "argocd-service-account@my-google-project.iam.gserviceaccount.com",
"client_id": "REDACTED",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/argocd-service-account%40my-google-project.iam.gserviceaccount.com"
}
Kubernetes 文档中有关于创建包含私钥的密钥的说明。
存储库凭证
如果您想要对多个存储库使用相同的凭证,可以配置凭证模板。凭证模板可以携带与存储库相同的凭证信息。
apiVersion: v1
kind: Secret
metadata:
name: first-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
---
apiVersion: v1
kind: Secret
metadata:
name: second-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/other-private-repo
---
apiVersion: v1
kind: Secret
metadata:
name: private-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
type: git
url: https://github.com/argoproj
password: my-password
username: my-username
在上面的例子中,每个通过 HTTPS 访问的存储库(其 URL 以 https://github.com/argoproj
为前缀)都会使用存储在键 username
中的用户名和存储在密钥 private-repo-creds
的键 password
中的密码来连接到 Git。
为了让 Argo CD 使用任何给定存储库的凭证模板,必须满足以下条件:
- 存储库必须完全未配置,或者如果已配置,则不能包含任何凭证信息(即不包含
sshPrivateKey, username, password
) - 为凭证模板配置的 URL(例如
https://github.com/argoproj
)必须与存储库 URL 的前缀匹配(例如https://github.com/argoproj/argocd-example-apps
)。
匹配凭证模板 URL 前缀是根据最佳匹配结果进行的,因此最长(最佳)匹配将优先。与 v1.4 之前的配置不同,定义的顺序并不重要。
以下密钥可以有效引用凭证密钥:
- SSH repositories
sshPrivateKey
用于访问存储库的 SSH 私钥
- HTTPS repositories
username
和password
指的是访问存储库的用户名和密码tlsClientCertData
和tlsClientCertKey
指的是存储用于访问存储库的 TLS 客户端证书 (tlsClientCertData
) 和相应私钥tlsClientCertKey
- GitHub App repositories
githubAppPrivateKey
指的是用于访问存储库的 GitHub App 私钥githubAppID
指的是创建的应用程序的 GitHub 应用程序 ID。githubAppInstallationID
指的是创建并安装的 GitHub 应用程序的安装 ID。githubAppEnterpriseBaseUrl
指的是 GitHub Enterprise 的基本 api URL(例如https://ghe.example.com/api/v3
)tlsClientCertData
和tlsClientCertKey
指的是存储 TLS 客户端证书(tlsClientCertData
)和相应的私钥tlsClientCertKey
,用于在使用自定义证书的情况下访问 GitHub Enterprise。
使用自签名 TLS 证书的存储库(或由自定义 CA 签名)
在名为 argocd-tls-certs-cm
的 ConfigMap 对象中管理用于验证存储库服务器真实性的 TLS 证书。数据部分应包含一个映射,其中存储库服务器的主机名部分(不是完整的 URL)作为密钥,PEM 格式的证书作为数据。因此,如果您连接到 URL 为 https://server.example.com/repos/my-repo
的存储库,则应使用 server.example.com
作为密钥。证书数据应该是服务器的证书(如果是自签名证书)或用于签署服务器证书的 CA 的证书。可以为每个服务器配置多个证书,例如,如果计划进行证书轮换。
如果没有为存储库服务器配置专用证书,则系统默认的信任存储将用于验证服务器的存储库。对于大多数(如果不是全部)公共 Git 存储库服务(例如 GitLab、GitHub 和 Bitbucket)以及大多数使用知名 CA 颁发的证书(包括 Let’s Encrypt 证书)的私人托管站点来说,这应该足够了。
ConfigMap 对象示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-tls-certs-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
server.example.com: |
-----BEGIN CERTIFICATE-----
MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL
BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE
BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0
c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda
Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT
YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES
MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5
NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc
CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u
P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G
ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+
YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E
Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko
Ml1L4zCU+xEsMcvb1iQ2n7PZdacqhkFRUVVVmJ56th8aYyX7KNX6M9CD+kMpNm6J
kKC1li/Iy+RI138bAvaFplajMF551kt44dSvIoJIbTr1LigudzWPqk31QaZXV/4u
kD1n4p/XMc9HYU/was/CmQBFqmIZedTLTtK7clkuFN6wbwzdo1wmUNgnySQuMacO
gxhHxxzRWxd24uLyk9Px+9U3BfVPaRLiOPaPoC58lyVOykjSgfpgbus7JS69fCq7
bEH4Jatp/10zkco+UQIDAQABo1MwUTAdBgNVHQ4EFgQUjXH6PHi92y4C4hQpey86
r6+x1ewwHwYDVR0jBBgwFoAUjXH6PHi92y4C4hQpey86r6+x1ewwDwYDVR0TAQH/
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFE4SdKsX9UsLy+Z0xuHSxhTd0jfn
Iih5mtzb8CDNO5oTw4z0aMeAvpsUvjJ/XjgxnkiRACXh7K9hsG2r+ageRWGevyvx
CaRXFbherV1kTnZw4Y9/pgZTYVWs9jlqFOppz5sStkfjsDQ5lmPJGDii/StENAz2
XmtiPOgfG9Upb0GAJBCuKnrU9bIcT4L20gd2F4Y14ccyjlf8UiUi192IX6yM9OjT
+TuXwZgqnTOq6piVgr+FTSa24qSvaXb5z/mJDLlk23npecTouLg83TNSn3R6fYQr
d/Y9eXuUJ8U7/qTh2Ulz071AO9KzPOmleYPTx4Xty4xAtWi1QE5NHW9/Ajlv5OtO
OnMNWIs7ssDJBsB7VFC8hcwf79jz7kC0xmQqDfw51Xhhk04kla+v+HZcFW2AO9so
6ZdVHHQnIbJa7yQJKZ+hK49IOoBR6JgdB5kymoplLLiuqZSYTcwSBZ72FYTm3iAr
jzvt1hxpxVDmXvRnkhRrIRhK4QgJL0jRmirBjDY+PYYd7bdRIjN7WNZLFsgplnS8
9w6CwG32pRlm0c8kkiQ7FXA6BYCqOsDI8f1VGQv331OpR2Ck+FTv+L7DAmg6l37W
+LB9LGh4OAp68ImTjqf6ioGKG0RBSznwME+r4nXtT1S/qLR6ASWUS4ViWRhbRlNK
XWyb96wrUlv+E8I=
-----END CERTIFICATE-----
argocd-tls-certs-cm
ConfigMap 将作为卷(volume)挂载在argocd-server
和argocd-repo-server
的 pod 中的挂载路径/app/config/tls
上。它将在挂载路径目录中为每个数据密钥创建文件,因此上述示例将保留文件/app/config/tls/server.example.com
,其中包含证书数据。ConfigMap 中的更改可能需要一段时间才能反映在 pod 中,具体取决于 Kubernetes 配置。
SSH 已知主机公钥
如果您正在配置存储库以使用 SSH,Argo CD 将需要知道它们的 SSH 公钥。为了让 Argo CD 通过 SSH 连接,必须在 Argo CD 中预先配置每个存储库服务器的公钥(与 TLS 配置不同),否则与存储库的连接将失败。
可以在 argocd-ssh-known-hosts-cm
ConfigMap 中管理 SSH 已知主机数据。此 ConfigMap 包含单个条目 ssh_known_hosts
,其值为 SSH 服务器的公钥。该值可以从任何现有的 ssh_known_hosts
文件中填写,也可以从 ssh-keyscan
实用程序(它是 OpenSSH 客户端包的一部分)的输出中填写。基本格式为 <server_name> <keytype> <base64-encoded_key>
,每行一个条目。
以下是运行 ssh-keyscan 的示例:
$ for host in bitbucket.org github.com gitlab.com ssh.dev.azure.com vs-ssh.visualstudio.com ; do ssh-keyscan $host 2> /dev/null ; done
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
下面是使用上面的 ssh-keyscan 输出的示例 ConfigMap 对象:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: argocd-ssh-known-hosts-cm
app.kubernetes.io/part-of: argocd
name: argocd-ssh-known-hosts-cm
data:
ssh_known_hosts: |
# This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT
[ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
[ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
[ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
argocd-ssh-known-hosts-cm
ConfigMap 将作为卷(volume)安装在argocd-server
和argocd-repo-server
的 pod 中的安装路径 /app/config/ssh 上。它将在该目录中创建一个文件 ssh_known_hosts,其中包含 Argo CD 用于通过 SSH 连接到 Git 存储库的 SSH 已知主机数据。ConfigMap 中的更改可能需要一段时间才能反映在您的 pod 中,具体取决于您的 Kubernetes 配置。
使用代理配置存储库
可以在存储库密钥的代理字段中指定存储库的代理以及其他存储库配置。Argo CD 使用此代理访问存储库。如果自定义代理不存在,Argo CD 会在存储库服务器中查找标准代理环境变量。
带有代理的示例存储库:
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
proxy: https://proxy-server-url:8888
password: my-password
username: my-username
遗留行为
在 Argo CD 2.0 及更早版本中,存储库作为 argocd-cm 配置图的一部分进行存储。为了向后兼容,Argo CD 仍将遵循配置图中的存储库,但这种存储库配置样式已被弃用,并且将在未来版本中移除对它的支持。
apiVersion: v1
kind: ConfigMap
data:
repositories: |
- url: https://github.com/argoproj/my-private-repository
passwordSecret:
name: my-secret
key: password
usernameSecret:
name: my-secret
key: username
repository.credentials: |
- url: https://github.com/argoproj
passwordSecret:
name: my-secret
key: password
usernameSecret:
name: my-secret
key: username
---
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: argocd
stringData:
password: my-password
username: my-username
集群(Clusters)
集群凭证存储在与存储库或存储库凭证相同的机密中。每个机密都必须具有标签 argocd.argoproj.io/secret-type: cluster
。
密钥数据必须包含以下字段:
name
群集名称server
集群 API 服务器 URLnamespaces
可选的以逗号分隔的命名空间列表,这些命名空间在该集群中可访问。如果命名空间列表不为空,则集群级别资源将被忽略。clusterResources
可选布尔字符串(“true”或“false”)确定 Argo CD 是否可以管理此集群上的集群级资源。仅当管理命名空间列表不为空时才使用此设置。project
可选字符串,用于将其指定为项目范围的集群。config
以下数据结构的 JSON 表示:
# Basic authentication settings
username: string
password: string
# Bearer authentication settings
bearerToken: string
# IAM authentication configuration
awsAuthConfig:
clusterName: string
roleARN: string
profile: string
# Configure external command to supply client credentials
# See https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig
execProviderConfig:
command: string
args: [
string
]
env: {
key: value
}
apiVersion: string
installHint: string
# Transport layer security configuration settings
tlsClientConfig:
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
caData: string
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
certData: string
# Server should be accessed without verifying the TLS certificate
insecure: boolean
# Base64 encoded PEM-encoded bytes (typically read from a client certificate key file).
keyData: string
# ServerName is passed to the server for SNI and is used in the client to check server
# certificates against. If ServerName is empty, the hostname used to contact the
# server is used.
serverName: string
集群凭证存储在与存储库或存储库凭证相同的密钥中。每个机密都必须具有标签 argocd.argoproj.io/secret-type: cluster
。
密钥数据必须包含以下字段:
name
集群 API 服务器 URLserver
集群 API 服务器 URLnamespaces
可选的以逗号分隔的命名空间列表,这些命名空间在该集群中可访问。如果命名空间列表不为空,则集群级别资源将被忽略。clusterResources
可选布尔字符串(true
或false
)确定 Argo CD 是否可以管理此集群上的集群级资源。仅当管理命名空间列表不为空时才使用此设置。- project 可选字符串,用于将其指定为项目范围的集群。
config
以下数据结构的 JSON 表示:
# Basic authentication settings
username: string
password: string
# Bearer authentication settings
bearerToken: string
# IAM authentication configuration
awsAuthConfig:
clusterName: string
roleARN: string
profile: string
# Configure external command to supply client credentials
# See https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig
execProviderConfig:
command: string
args: [
string
]
env: {
key: value
}
apiVersion: string
installHint: string
# Transport layer security configuration settings
tlsClientConfig:
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
caData: string
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
certData: string
# Server should be accessed without verifying the TLS certificate
insecure: boolean
# Base64 encoded PEM-encoded bytes (typically read from a client certificate key file).
keyData: string
# ServerName is passed to the server for SNI and is used in the client to check server
# certificates against. If ServerName is empty, the hostname used to contact the
# server is used.
serverName: string
请注意,如果指定在 execProviderConfig 下运行的命令,则该命令必须在 Argo CD 映像中可用。请参阅 BYOI(构建您自己的映像)。
集群密钥示例:
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: mycluster.example.com
server: https://mycluster.example.com
config: |
{
"bearerToken": "<authentication token>",
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
EKS
使用 argocd-k8s-auth 和 IRSA 的 EKS 集群密钥示例:
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: "mycluster.example.com"
server: "https://mycluster.example.com"
config: |
{
"awsAuthConfig": {
"clusterName": "my-eks-cluster-name",
"roleARN": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>"
},
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
请注意,应该在 EKS 集群上启用 IRSA,创建一个适当的 IAM 角色,允许它承担其他 IAM 角色(Argo CD 需要承担的任何角色 ARN),并有一个承担角色策略,允许 argocd-application-controller 和 argocd-server pod 通过 OIDC 承担上述角色。
<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ARGO_CD_MANAGEMENT_IAM_ROLE_NAME>
的信任关系配置示例,这是 Argo CD 通过 IAM 执行操作所必需的。确保集群已为其配置 IAM OIDC 提供程序。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.eks.<AWS_REGION>.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<AWS_REGION>.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": ["system:serviceaccount:argocd:argocd-application-controller", "system:serviceaccount:argocd:argocd-server"],
"oidc.eks.<AWS_REGION>.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
}
}
}
]
}
Argo CD 管理角色还需要被允许承担其他角色,在本例中,我们希望它承担 arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>
,以便它可以管理映射到该角色的集群。这可以扩展为允许承担多个角色,可以作为角色 ARN 的显式数组,也可以在适当的情况下使用 *
。
{
"Version" : "2012-10-17",
"Statement" : {
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Resource" : [
"<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>"
]
}
}
argocd-application-controller 和 argocd-server 的示例服务帐户配置。
一旦在服务账户上设置了注释,就需要重新启动应用程序控制器和服务器容器。
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ARGO_CD_MANAGEMENT_IAM_ROLE_NAME>"
name: argocd-application-controller
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ARGO_CD_MANAGEMENT_IAM_ROLE_NAME>"
name: argocd-server
反过来,每个托管集群的 roleARN 都需要添加到每个相应集群的 aws-auth 配置映射中(请参阅启用对集群的 IAM 主体访问),并且具有允许它由 Argo CD pod 角色承担的承担角色策略。
假设由 Argo CD 管理的集群的角色策略示例:
{
"Version" : "2012-10-17",
"Statement" : {
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Principal" : {
"AWS" : "<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ARGO_CD_MANAGEMENT_IAM_ROLE_NAME>"
}
}
}
由 Argo CD 管理的集群的示例 kube-system/aws-auth 配置映射:
apiVersion: v1
data:
# Other groups and accounts omitted for brevity. Ensure that no other rolearns and/or groups are inadvertently removed,
# or you risk borking access to your cluster.
#
# The group name is a RoleBinding which you use to map to a [Cluster]Role. See https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-binding-examples
mapRoles: |
- "groups":
- "<GROUP-NAME-IN-K8S-RBAC>"
"rolearn": "<arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>"
"username": "<some-username>"
替代的 EKS 身份验证方法
在某些情况下,可能无法使用 IRSA,例如当 Argo CD 集群在不同云提供商的平台上运行时。在这种情况下,有两个选项:
- 使用 execProviderConfig 调用 AWS 身份验证机制,该机制允许注入环境变量以提供凭据
- 利用 Argo CD 版本 2.10 中提供的新 AWS 配置文件选项
这两个选项都需要涉及 IAM 和 aws-auth 配置映射(如上所述)的步骤,以便为主体提供对集群的访问权限。
- 使用 EXECPROVIDERCONFIG 与环境变量
---
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: mycluster
server: https://mycluster.example.com
namespaces: "my,managed,namespaces"
clusterResources: "true"
config: |
{
"execProviderConfig": {
"command": "argocd-k8s-auth",
"args": ["aws", "--cluster-name", "my-eks-cluster"],
"apiVersion": "client.authentication.k8s.io/v1beta1",
"env": {
"AWS_REGION": "xx-east-1",
"AWS_ACCESS_KEY_ID": "{{ .aws_key_id }}",
"AWS_SECRET_ACCESS_KEY": "{{ .aws_key_secret }}",
"AWS_SESSION_TOKEN": "{{ .aws_token }}"
}
},
"tlsClientConfig": {
"insecure": false,
"caData": "{{ .cluster_cert }}"
}
}
此示例假定角色附加到已提供的凭证,如果不是这种情况,则可以将角色附加到 args 部分,如下所示:
...
"args": ["aws", "--cluster-name", "my-eks-cluster", "--roleARN", "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>"],
...
该构造可与外部密钥操作员之类的东西结合使用,以避免以纯文本形式存储密钥,并且有助于为密钥轮换提供基础。
- 使用 AWS 配置文件进行身份验证
在版本 2.10 中添加的使用配置文件的选项提供了一种提供凭证的方法,同时仍然使用标准 Argo CD EKS 集群声明以及指向 AWS 凭证文件的附加命令标志:
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: "mycluster.com"
server: "https://mycluster.com"
config: |
{
"awsAuthConfig": {
"clusterName": "my-eks-cluster-name",
"roleARN": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>",
"profile": "/mount/path/to/my-profile-file"
},
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
这将指示 ArgoCD 读取所提供路径的文件并使用其中定义的凭据向 AWS 进行身份验证。必须安装配置文件才能使其正常工作。例如,可以在基于 Helm 的 ArgoCD 部署中定义以下值:
controller:
extraVolumes:
- name: my-profile-volume
secret:
secretName: my-aws-profile
items:
- key: my-profile-file
path: my-profile-file
extraVolumeMounts:
- name: my-profile-mount
mountPath: /mount/path/to
readOnly: true
server:
extraVolumes:
- name: my-profile-volume
secret:
secretName: my-aws-profile
items:
- key: my-profile-file
path: my-profile-file
extraVolumeMounts:
- name: my-profile-mount
mountPath: /mount/path/to
readOnly: true
其中 secret 定义如下:
apiVersion: v1
kind: Secret
metadata:
name: my-aws-profile
type: Opaque
stringData:
my-profile-file: |
[default]
region = <aws_region>
aws_access_key_id = <aws_access_key_id>
aws_secret_access_key = <aws_secret_access_key>
aws_session_token = <aws_session_token>
密钥挂载会按间隔更新,而不是实时更新。如果需要轮换,请确保令牌的生命周期超过挂载更新间隔,并且轮换过程不会立即使现有令牌失效
GKE
使用 argocd-k8s-auth 和 Workload Identity 的 GKE 集群密钥示例:
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: mycluster.example.com
server: https://mycluster.example.com
config: |
{
"execProviderConfig": {
"command": "argocd-k8s-auth",
"args": ["gcp"],
"apiVersion": "client.authentication.k8s.io/v1beta1"
},
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
请注意,必须在 GKE 集群上启用 Workload Identity,创建具有适当 IAM 角色的 GCP 服务帐户,并将其绑定到 argocd-application-controller 和 argocd-server 的 Kubernetes 服务帐户(在 UI 上显示 Pod 日志)。请参阅使用 Workload Identity 和向 Kubernetes API 服务器进行身份验证。
AKS
使用 argocd-k8s-auth 和 kubelogin 的 Azure 群集密钥示例。argocd-k8s-auth execProviderConfig 的选项 azure 封装了 kubelogin 的 get-token 命令。根据所需的身份验证流程(devicecode、spn、ropc、msi、azurecli、workloadidentity),使用此值设置环境变量 AAD_LOGIN_METHOD。根据所需的身份验证流程设置其他适当的环境变量。
Variable Name | Description |
---|---|
AAD_LOGIN_METHOD | One of devicecode, spn, ropc, msi, azurecli, or workloadidentity |
AAD_SERVICE_PRINCIPAL_CLIENT_CERTIFICATE | AAD client cert in pfx. Used in spn login |
AAD_SERVICE_PRINCIPAL_CLIENT_ID | AAD client application ID |
AAD_SERVICE_PRINCIPAL_CLIENT_SECRET | AAD client application secret |
AAD_USER_PRINCIPAL_NAME | Used in the ropc flow |
AAD_USER_PRINCIPAL_PASSWORD | Used in the ropc flow |
AZURE_TENANT_ID | The AAD tenant ID. |
AZURE_AUTHORITY_HOST | Used in the WorkloadIdentityLogin flow |
AZURE_FEDERATED_TOKEN_FILE | Used in the WorkloadIdentityLogin flow |
AZURE_CLIENT_ID | Used in the WorkloadIdentityLogin flow |
除了上述环境变量外,argocd-k8s-auth 还接受两个额外的环境变量来设置 AAD 环境,以及设置 AAD 服务器应用程序 ID。如果未指定,AAD 服务器应用程序 ID 将默认为 6dae42f8-4368-4678-94ff-3960e28e3630。详情请参阅此处。
Variable Name | Description |
---|---|
AAD_ENVIRONMENT_NAME | The azure environment to use, default of AzurePublicCloud |
AAD_SERVER_APPLICATION_ID | The optional AAD server application ID, defaults to 6dae42f8-4368-4678-94ff-3960e28e3630 |
这是使用联合工作负载登录流程的示例。联合令牌文件需要作为密钥挂载到 argoCD 中,以便可以在流程中使用。令牌文件的位置需要在环境变量 AZURE_FEDERATED_TOKEN_FILE 中设置。
如果你的 AKS 集群使用 Azure Workload Identity 项目中的 Mutating Admission Webhook,请按照以下步骤启用 argocd-application-controller
和 argocd-server
pods 以使用联合标识:
- 给 Pod 贴上标签:将
azure.workload.identity/use: "true"
标签添加到argocd-application-controller
和argocd-server
Pods。 - 创建联合身份凭证:为
argocd-application-controller
和argocd-server
服务帐户生成 Azure 联合身份凭据。有关详细说明,请参阅联合身份凭据文档。 - 设置 AZURE_CLIENT_ID:更新集群密钥中的
AZURE_CLIENT_ID
以匹配新创建的联合身份凭证的客户端 ID。
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: mycluster.example.com
server: https://mycluster.example.com
config: |
{
"execProviderConfig": {
"command": "argocd-k8s-auth",
"env": {
"AAD_ENVIRONMENT_NAME": "AzurePublicCloud",
"AZURE_CLIENT_ID": "fill in client id",
"AZURE_TENANT_ID": "fill in tenant id", # optional, injected by workload identity mutating admission webhook if enabled
"AZURE_FEDERATED_TOKEN_FILE": "/opt/path/to/federated_file.json", # optional, injected by workload identity mutating admission webhook if enabled
"AZURE_AUTHORITY_HOST": "https://login.microsoftonline.com/", # optional, injected by workload identity mutating admission webhook if enabled
"AAD_LOGIN_METHOD": "workloadidentity"
},
"args": ["azure"],
"apiVersion": "client.authentication.k8s.io/v1beta1"
},
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
这是使用 spn(服务主体名称)流的示例。
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: mycluster.example.com
server: https://mycluster.example.com
config: |
{
"execProviderConfig": {
"command": "argocd-k8s-auth",
"env": {
"AAD_ENVIRONMENT_NAME": "AzurePublicCloud",
"AAD_SERVICE_PRINCIPAL_CLIENT_SECRET": "fill in your service principal client secret",
"AZURE_TENANT_ID": "fill in tenant id",
"AAD_SERVICE_PRINCIPAL_CLIENT_ID": "fill in your service principal client id",
"AAD_LOGIN_METHOD": "spn"
},
"args": ["azure"],
"apiVersion": "client.authentication.k8s.io/v1beta1"
},
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
Helm Chart 存储库
非标准 Helm Chart 存储库必须明确注册。每个存储库必须具有 url、type
和 name
字段。对于私有 Helm 存储库,可能需要使用 username
、password
、tlsClientCertData
和 tlsClientCertKey
字段配置访问凭据和 HTTPS 设置。
例子:
apiVersion: v1
kind: Secret
metadata:
name: istio
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
name: istio.io
url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts
type: helm
---
apiVersion: v1
kind: Secret
metadata:
name: argo-helm
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
name: argo
url: https://argoproj.github.io/argo-helm
type: helm
username: my-username
password: my-password
tlsClientCertData: ...
tlsClientCertKey: ...
资源排除/包含
可以将资源排除在发现和同步之外,这样 Argo CD 就无法识别它们。例如,apiGroup/kind events.k8s.io/*
、metrics.k8s.io/*
、coordination.k8s.io/Lease
和 ""/Endpoints
始终被排除在外。用例:
- 遇到临时问题,并且希望排除有问题的资源。
- 有很多种资源会影响 Argo CD 的性能。
- 限制 Argo CD 对某些资源(例如密钥)的访问。请参阅 security.md#cluster-rbac。
要配置此功能,请编辑 argocd-cm
配置图:
kubectl edit configmap argocd-cm -n argocd
添加 resource.exclusions
,例如:
apiVersion: v1
data:
resource.exclusions: |
- apiGroups:
- "*"
kinds:
- "*"
clusters:
- https://192.168.0.20
kind: ConfigMap
resource.exclusions
节点是对象列表。每个对象可以具有:
apiGroups
与 API 组匹配的全局列表kinds
要匹配的种类列表。可以使用*
来匹配所有clusters
与集群匹配的全局列表
如果三者全部匹配,则忽略该资源。
除了排除之外,您还可以使用 resource.inclusions
设置配置包含的资源列表。默认情况下,包含所有资源group/kinds
。resource.inclusions
设置允许自定义包含的group/kinds
列表:
apiVersion: v1
data:
resource.inclusions: |
- apiGroups:
- "*"
kinds:
- Deployment
clusters:
- https://192.168.0.20
kind: ConfigMap
resource.inclusions
和 resource.exclusions
可以一起使用。最终的资源列表包括 resource.inclusions
中指定的group/kinds
减去 resource.exclusions
设置中指定的group/kinds
。
笔记:
- 在 YAML 中引用全局变量以避免解析错误。
- 无效的全局变量会导致整个规则被忽略。
- 如果添加与现有资源匹配的规则,这些资源将在界面中显示为
OutOfSync
。
控制器自动限制RBAC
可以仅使用控制器 RBAC 来限制 Argocd 控制器发现/同步特定资源,而无需手动配置资源排除。可以通过在 argocd cm 中设置 resource.respectRBAC
键来启用此功能,设置后,控制器将自动停止监视它无权列出/访问的资源。
resource.respectRBAC
的可能值包括:
strict
:此设置检查控制器发出的列表调用是否被禁止/未经授权,如果是,它将通过对资源进行 SelfSubjectAccessReview 调用来交叉检查权限。normal
:这将仅检查列表调用响应是否被禁止/未经授权,并跳过 SelfSubjectAccessReview 调用,以尽量减少任何额外的 api 服务器调用。unset/empty
(默认):这将禁用该功能,控制器将继续监视所有资源。
可以接受增加 kube api-server
调用次数的用户可以选择strict
选项,而担心更高 api 调用次数并愿意在准确性上做出妥协的用户可以选择normal
选项。
笔记:
- 当设置为使用
strict
模式时,控制器必须具有 RBAC 权限才能创建SelfSubjectAccessReview
资源 elfSubjectAccessReview
请求仅针对list
动词进行,假定如果允许列出资源,则控制器也可以使用所有其他权限。
将 resource.respectRBAC
设置为 strict
的示例 argocd cm
:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
resource.respectRBAC: "strict"
资源自定义标签
使用 resource.customLabels
(逗号分隔的字符串)配置的自定义标签将显示在 UI 中(对于定义它们的任何资源)。
SSO & RBAC
使用 Argo CD 管理 Argo CD
Argo CD 能够自我管理,因为所有设置都由 Kubernetes 清单表示。建议的方法是创建基于 Kustomize 的应用程序,该应用程序使用来自 https://github.com/argoproj/argo-cd
的基本 Argo CD 清单(manifests),并在其上应用所需的更改。
kustomization.yaml
示例:
# additional resources like ingress rules, cluster and repository secrets.
resources:
- github.com/argoproj/argo-cd//manifests/cluster-install?ref=stable
- clusters-secrets.yaml
- repos-secrets.yaml
# changes to config maps
patches:
- path: overlays/argo-cd-cm.yaml
自我管理的 Argo CD 配置的实时示例可在 https://cd.apps.argoproj.io
上找到,配置存储在 argoproj/argoproj-deployments
中。
需要使用 GitHub 帐户登录才能访问
https://cd.apps.argoproj.io
7.6.任意名称空间中的应用程序
启用此功能前请仔细阅读本文档。配置错误可能会导致潜在的安全问题。
介绍
从 2.5 版开始,Argo CD 支持在控制平面命名空间(通常是 argocd)以外的命名空间中管理Application
资源,但必须明确启用并适当配置此功能。
Argo CD 管理员可以定义一组特定的命名空间,可以在其中创建、更新和协调Application
资源。但是,这些附加命名空间中的应用程序将只被允许使用 Argo CD 管理员配置的某些 AppProject
。这允许普通 Argo CD 用户(例如应用程序团队)使用诸如声明式管理应用程序资源、实现 app-of-apps 等模式,而不会因使用超出授予应用程序团队的权限的其他 AppProjects
而面临特权升级的风险。
为了启用此功能,Argo CD 管理员需要执行一些手动步骤。
在任何命名空间中采用应用程序的另一个优点是允许最终用户在 Argo CD 应用程序正在运行的命名空间中为其 Argo CD 应用程序配置通知。有关更多信息,请参阅基于通知命名空间的配置页面。
先决条件
群集范围内的 Argo CD 安装
仅当 Argo CD 作为集群范围实例安装时,才能启用和使用此功能,因此它有权列出和操作集群范围内的资源。它不适用于以命名空间范围模式安装的 Argo CD。
选择机资源跟踪方法
此外,虽然从技术上来说没有必要,但强烈建议您将应用程序跟踪方法从默认label
设置切换为annotation
或annotation+label
。这样做的原因是,应用程序名称将是命名空间名称和Application
名称的组合,这很容易超过对标签值施加的 63 个字符的长度限制。注释的长度限制明显更大。
要启用基于注释的资源跟踪,请参阅有关资源跟踪方法的文档
实现细节
概述
为了在 Argo CD 的控制平面命名空间之外管理和协调应用程序,必须满足两个先决条件:
-
必须使用
--application-namespaces
参数为argocd-application-controller
和argocd-server
工作负载明确启用应用程序的命名空间。此参数控制 Argo CD 被允许从全局获取应用程序资源的命名空间列表。任何未在此处配置的命名空间都不能从任何 AppProject 使用。 -
Application
的.spec.project
字段引用的AppProject
必须在其.spec.sourceNamespaces
字段中列出命名空间。此设置将决定应用程序是否可以使用某个AppProject
。如果应用程序指定了不允许的AppProject
,Argo CD 将拒绝处理此应用程序。如上所述,在.spec.sourceNamespaces
字段中配置的任何命名空间也必须全局启用。
可以像以前 argocd 命名空间中的任何其他Application
一样创建和管理不同命名空间中的Applications
,可以通过声明方式或通过 Argo CD API(例如使用 CLI、Web UI、REST API 等)进行创建和管理。
重新配置 Argo CD 以允许某些命名空间
1) 更改工作负载启动参数
为了启用此功能,Argo CD 管理员必须重新配置 argocd-server
和 argocd-application-controller
工作负载,以将 --application-namespaces
参数添加到容器的启动命令中。
--application-namespaces
参数采用逗号分隔的命名空间列表,允许应用程序进入这些命名空间。列表中的每个条目都支持 shell 样式的通配符,例如 *
,因此例如条目 app-team-*
将匹配 app-team-one
和 app-team-two
。要启用运行 Argo CD 的集群上的所有命名空间,只需指定 *
,即 --application-namespaces=*
。
还可以通过指定 argocd-cmd-params-cm
ConfigMap 中的 application.namespaces
设置来方便地设置 argocd-server
和 argocd-application-controller
的启动参数并保持同步,而无需更改相应工作负载的清单。例如:
data:
application.namespaces: app-team-one, app-team-two
将允许 app-team-one
和 app-team-two
命名空间管理应用程序资源。更改 argocd-cmd-params-cm
命名空间后,需要重新启动相应的工作负载:
kubectl rollout restart -n argocd deployment argocd-server
kubectl rollout restart -n argocd statefulset argocd-application-controller
2) 调整 Kubernetes RBAC
我们决定暂时不默认扩展 argocd-server
工作负载的 Kubernetes RBAC。如果希望其他命名空间中的应用程序由 Argo CD API(即 CLI 和 UI)管理,则需要扩展 argocd-server
ServiceAccount 的 Kubernetes 权限。
我们在 examples/k8s-rbac/argocd-server-applications
目录中提供了适合此目的的 ClusterRole 和 ClusterRoleBinding。对于默认的 Argo CD 安装(即安装到 argocd 命名空间),可以按原样应用它们:
kubectl apply -k examples/k8s-rbac/argocd-server-applications/
argocd-notifications-controller-rbac-clusterrole.yaml
和 argocd-notifications-controller-rbac-clusterrolebinding.yaml
用于支持通知控制器通知所有命名空间中的应用程序。
在稍后的某个时间点,我们可能会将此集群角色作为默认安装清单的一部分。
允许 AppProject 中的其他命名空间
任何具有 Kubernetes 访问 Argo CD 控制平面命名空间(argocd)的用户,尤其是那些有权以声明方式创建或更新应用程序的用户,都被视为 Argo CD 管理员。
这可以防止非特权 Argo CD 用户在过去以声明方式创建或管理应用程序。 这些用户被限制使用 API,但要遵守 Argo CD RBAC,确保只创建允许的 AppProject 中的应用程序。
对于在 argocd 命名空间之外创建的应用程序,应用程序的 .spec.project
字段中引用的 AppProject
必须在其 .spec.sourceNamespaces
字段中包含应用程序的命名空间。
例如,考虑以下两个(不完整的)AppProject
规范:
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: project-one
namespace: argocd
spec:
sourceNamespaces:
- namespace-one
和
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: project-two
namespace: argocd
spec:
sourceNamespaces:
- namespace-two
为了让应用程序将 .spec.project
设置为 project-one
,必须在命名空间 namespace-one
或 argocd
中创建它。同样,为了让应用程序将 .spec.project
设置为 project-two``,必须在命名空间
namespace-two或
argocd` 中创建它。
如果namespace-two
中的应用程序将其 .spec.project
设置为 project-one
,或者namespace-one
中的应用程序将其 .spec.project
设置为 project-two
,则 Argo CD 会将此视为权限违规并拒绝协调该应用程序。
此外,无论 Argo CD RBAC 权限如何,Argo CD API 都会强制执行这些约束。
AppProject
的 .spec.sourceNamespaces
字段是一个可以包含任意数量的命名空间的列表,每个条目都支持 shell 样式的通配符,以便您可以允许具有 team-one-*
等模式的命名空间。
不要在任何特权
AppProject
(如默认项目)的.spec.sourceNamespaces
字段中添加用户控制的命名空间。始终确保AppProject
遵循授予最少所需权限的原则。切勿授予对AppProject
中argocd
命名空间的访问权限。
为了向后兼容,
Argo CD
控制平面的命名空间(argocd)中的应用程序可以设置其.spec.project
字段以引用任何AppProject
,而不管AppProject
的.spec.sourceNamespaces
字段所施加的限制。
应用程序名称
对于 CLI 和 UI,应用程序现在以 <namespace>/<name>
格式引用和显示。
为了向后兼容,如果应用程序的命名空间是控制平面的命名空间(即 argocd),则在引用应用程序名称时可以省略 <namespace>
。例如,应用程序名称 argocd/someapp
和 someapp
在语义上相同,并且在 CLI 和 UI 中引用的是同一个应用程序。
应用程序 RBAC
应用程序对象的 RBAC 语法已从 <project>/<application>
更改为 <project>/<namespace>/<application>
,以适应根据要管理的应用程序的源命名空间限制访问的需要。
为了向后兼容,argocd
命名空间中的应用程序在 RBAC 策略规则中仍然可以被称为 <project>/<application>
。
通配符目前还不区分项目和应用程序命名空间。例如,以下 RBAC 规则将匹配属于项目 foo
的任何应用程序,无论它是在哪个命名空间中创建的:
p, somerole, applications, get, foo/*, allow
如果想要限制仅向命名空间 bar
内的项目 foo
中的应用程序授予访问权限,则需要对规则进行如下调整:
p, somerole, applications, get, foo/bar/*, allow
管理其他命名空间中的应用程序
声明式
对于应用程序的声明式管理,只需在所需的命名空间中从 YAML
或 JSON
清单创建应用程序即可。确保 .spec.project 字段引用允许此命名空间的 AppProject
。例如,以下(不完整的)应用程序清单在命名空间 some-namespace
中创建一个应用程序:
kind: Application
apiVersion: argoproj.io/v1alpha1
metadata:
name: some-app
namespace: some-namespace
spec:
project: some-project
# ...
然后,项目 some-project
将需要在允许的源命名空间列表中指定 some-namespace
,例如
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: some-project
namespace: argocd
spec:
sourceNamespaces:
- some-namespace
使用 CLI
可以使用所有现有的 Argo CD CLI 命令来管理其他命名空间中的应用程序,就像使用 CLI 管理控制平面命名空间中的应用程序一样。
例如,要检索命名空间 bar 中名为 foo
的Application
,您可以使用以下 CLI 命令:
argocd app get foo/bar
同样,要管理此Application
,请继续将其称为 foo/bar
:
# Create an application
argocd app create foo/bar ...
# Sync the application
argocd app sync foo/bar
# Delete the application
argocd app delete foo/bar
# Retrieve application's manifest
argocd app manifests foo/bar
如前所述,对于 Argo CD 的控制平面命名空间中的应用程序,可以从应用程序名称中省略命名空间。
使用 UI
与 CLI 类似,您可以在 UI 中将应用程序引用为 foo/bar
。
例如,要在 Web UI 中的命名空间 foo
中创建名为 bar
的应用程序,请在创建对话框的应用程序名称字段中将应用程序名称设置为 foo/bar
。如果省略命名空间,则将使用控制平面的命名空间。
使用 REST API
如果使用的是 REST API,则无法将 Application
的命名空间指定为应用程序名称,而需要使用可选的 appNamespace
查询参数指定资源。例如,要使用命名空间 bar
中名为 foo
的 Application
资源,请求应如下所示:
GET /api/v1/applications/foo?appNamespace=bar
对于 POST
和 PUT
等其他操作,appNamespace
参数必须是请求的一部分。
对于控制平面命名空间中的应用程序资源,可以省略此参数。
7.7.Ingress配置
Argo CD API 服务器同时运行 gRPC 服务器(由 CLI 使用)和 HTTP/HTTPS 服务器(由 UI 使用)。这两种协议均由 argocd-server 服务对象在以下端口上公开:
- 443 - gRPC/HTTPS
- 80 - HTTP (redirects to HTTPS)
有多种方式可以配置 Ingress。
Ambassador
UK /æmˈbæs.ə.dər/
US /æmˈbæs.ə.dɚ/
Ambassador Edge Stack 可用作 Kubernetes 入口控制器,具有适用于 CLI 和 UI 的自动 TLS 终止和路由功能。
API 服务器应在禁用 TLS 的情况下运行。编辑 argocd-server
部署以将 --insecure
标志添加到 argocd-server
命令,或者只需在 argocd-cmd-params-cm
ConfigMap 中设置 server.insecure: "true"
,如此处所述。鉴于 argocd
CLI 在请求host
标头中包含端口号,因此需要 2 个映射。
选项 1:映射 CRD 以进行基于Host的路由
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: argocd-server-ui
namespace: argocd
spec:
host: argocd.example.com
prefix: /
service: argocd-server:443
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: argocd-server-cli
namespace: argocd
spec:
# NOTE: the port must be ignored if you have strip_matching_host_port enabled on envoy
host: argocd.example.com:443
prefix: /
service: argocd-server:80
regex_headers:
Content-Type: "^application/grpc.*$"
grpc: true
使用 argocd CLI 登录:
argocd login <host>
选项 2:映射 CRD 以进行基于Path的路由
API 服务器必须配置为在非根路径下可用(例如 /argo-cd
)。编辑 argocd-server
部署以将 --rootpath=/argo-cd
标志添加到 argocd-server
命令。
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: argocd-server
namespace: argocd
spec:
prefix: /argo-cd
rewrite: /argo-cd
service: argocd-server:443
对于非根路径,使用额外的 --grpc-web-root-path
标志通过 argocd CLI 登录。
argocd login <host>:<port> --grpc-web-root-path /argo-cd
Contour
UK /ˈkɒn.tɔːr/
US /ˈkɑːn.tʊr/
Contour 入口控制器可以在边缘终止 TLS 入口流量。
Argo CD API 服务器应在禁用 TLS 的情况下运行。编辑 argocd-server
部署以将 --insecure
标志添加到 argocd-server
容器命令,或者只需在 argocd-cmd-params-cm
ConfigMap 中设置 server.insecure: "true"
,如此处所述。
还可以通过部署两个 Contour 实例来提供仅限内部的入口路径和仅限外部的入口路径:一个位于私有子网 LoadBalancer 服务后面,另一个位于公共子网 LoadBalancer 服务后面。私有 Contour 部署将拾取带有 kubernetes.io/ingress.class: contour-internal
注释的入口,而公共 Contour 部署将拾取带有 kubernetes.io/ingress.class: contour-external
注释的入口。
这提供了私下部署 Argo CD UI 的机会,但仍允许 SSO 回调成功。
具有多个Ingress对象和 BYO 证书的个人 Argo CD UI
由于 Contour Ingress 每个 Ingress 对象仅支持一种协议,因此请定义三个 Ingress 对象。一个用于私有 HTTP/HTTPS,一个用于私有 gRPC,一个用于公共 HTTPS SSO 回调。
内部 HTTP/HTTPS Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-http
annotations:
kubernetes.io/ingress.class: contour-internal
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
rules:
- host: internal.path.to.argocd.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: http
tls:
- hosts:
- internal.path.to.argocd.io
secretName: your-certificate-name
内部 gRPC Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-grpc
annotations:
kubernetes.io/ingress.class: contour-internal
spec:
rules:
- host: grpc-internal.path.to.argocd.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
tls:
- hosts:
- grpc-internal.path.to.argocd.io
secretName: your-certificate-name
外部 HTTPS SSO 回调Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-external-callback-http
annotations:
kubernetes.io/ingress.class: contour-external
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
rules:
- host: external.path.to.argocd.io
http:
paths:
- path: /api/dex/callback
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: http
tls:
- hosts:
- external.path.to.argocd.io
secretName: your-certificate-name
argocd-server
服务需要标注 projectcontour.io/upstream-protocol.h2c: "https,443"
来连接 gRPC 协议代理。
然后应在禁用 TLS 的情况下运行 API 服务器。编辑 argocd-server
部署以将 --insecure
标志添加到 argocd-server
命令,或者只需在 argocd-cmd-params-cm
ConfigMap 中设置 server.insecure: "true"
,如此处所述。
Contour httpproxy CRD:
使用Contour httpproxy CRD 允许您对 GRPC 和 REST api 使用相同的主机名。
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: argocd-server
namespace: argocd
spec:
ingressClassName: contour
virtualhost:
fqdn: path.to.argocd.io
tls:
secretName: wildcard-tls
routes:
- conditions:
- prefix: /
- header:
name: Content-Type
contains: application/grpc
services:
- name: argocd-server
port: 80
protocol: h2c # allows for unencrypted http2 connections
timeoutPolicy:
response: 1h
idle: 600s
idleConnection: 600s
- conditions:
- prefix: /
services:
- name: argocd-server
port: 80
kubernetes/ingress-nginx
选项 1:SSL 直通
Argo CD 在同一端口(443)上提供多种协议(gRPC/HTTPS),这在尝试为 argocd-service 定义单个 nginx ingress
对象和规则时带来了挑战,因为 nginx.ingress.kubernetes.io/backend-protocol
标注仅接受后端协议的单个值(例如 HTTP、HTTPS、GRPC、GRPCS
)。
为了使用单个入口规则和主机名公开 Argo CD API 服务器,必须使用 nginx.ingress.kubernetes.io/ssl-passthrough
标注来传递 TLS 连接并在 Argo CD API 服务器上终止 TLS。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
上述规则在 Argo CD API 服务器上终止 TLS,该服务器检测正在使用的协议并做出适当的响应。请注意,nginx.ingress.kubernetes.io/ssl-passthrough
注释要求将 --enable-ssl-passthrough
标志添加到 nginx-ingress-controller
的命令行参数中。
SSL-Passthrough with cert-manager and Let’s Encrypt
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
# If you encounter a redirect loop or are getting a 307 response code
# then you need to force the nginx ingress to connect to the backend using HTTPS.
#
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
tls:
- hosts:
- argocd.example.com
secretName: argocd-server-tls # as expected by argocd-server
选项 2:Ingress控制器上的 SSL 终止
另一种方法是在 Ingress 处执行 SSL 终止。由于 ingress-nginx Ingress
每个 Ingress
对象仅支持一种协议,因此需要使用 nginx.ingress.kubernetes.io/backend-protocol
标注定义两个 Ingress 对象,一个用于 HTTP/HTTPS
,另一个用于 gRPC
。
每个Ingress将用于不同的域(argocd.example.com
和 grpc.argocd.example.com
)。这要求Ingress资源使用不同的 TLS secretName
以避免意外行为。
HTTP/HTTPS Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-http-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: http
host: argocd.example.com
tls:
- hosts:
- argocd.example.com
secretName: argocd-ingress-http
gRPC Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-grpc-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
host: grpc.argocd.example.com
tls:
- hosts:
- grpc.argocd.example.com
secretName: argocd-ingress-grpc
然后应在禁用 TLS 的情况下运行 API 服务器。编辑 argocd-server
部署以将 --insecure
标志添加到 argocd-server
命令,或者只需在 argocd-cmd-params-cm
ConfigMap 中设置 server.insecure: "true"
,如此处所述。
这种方法的明显缺点是,该技术需要为 API 服务器提供两个单独的主机名 - 一个用于 gRPC
,另一个用于 HTTP/HTTPS
。但是,它允许在入口控制器处进行 TLS 终止。
Traefik (v2.2)
UK /ˈtræf.ɪk/
US /ˈtræf.ɪk/
Traefik 可用作边缘路由器并在同一部署中提供 TLS 终止。
目前,它比 NGINX 具有优势,因为它可以终止同一端口上的 TCP 和 HTTP 连接,这意味着您不需要多个主机或路径。
API 服务器应在禁用 TLS 的情况下运行。编辑 argocd-server
部署以将 --insecure
标志添加到 argocd-server
命令或按照此处所述在 argocd-cmd-params-cm
ConfigMap 中设置 server.insecure: "true"
。
IngressRoute CRD
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: argocd-server
namespace: argocd
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`argocd.example.com`)
priority: 10
services:
- name: argocd-server
port: 80
- kind: Rule
match: Host(`argocd.example.com`) && Headers(`Content-Type`, `application/grpc`)
priority: 11
services:
- name: argocd-server
port: 80
scheme: h2c
tls:
certResolver: default
AWS 应用程序负载均衡器 (ALB) 和经典 ELB (HTTP 模式)
AWS ALB 可用作 UI 和 gRPC 流量的 L7 负载均衡器,而 Classic ELB 和 NLB 可用作两者的 L4 负载均衡器。
使用 ALB 时,需要为 argocd-server
创建第二个服务。这是必要的,因为我们需要告诉 ALB 将 GRPC 流量发送到与 UI 流量不同的目标组,因为后端协议是 HTTP2
而不是 HTTP1
。
apiVersion: v1
kind: Service
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol-version: HTTP2 #This tells AWS to send traffic from the ALB using HTTP2. Can use GRPC as well if you want to leverage GRPC specific features
labels:
app: argogrpc
name: argogrpc
namespace: argocd
spec:
ports:
- name: "443"
port: 443
protocol: TCP
targetPort: 8080
selector:
app.kubernetes.io/name: argocd-server
sessionAffinity: None
type: NodePort
创建此服务后,可以使用 alb.ingress.kubernetes.io/conditions
标注配置 Ingress
,以有条件地将所有 application/grpc
流量路由到新的 HTTP2
后端,如下所示。注意:条件标注中 .
后面的值必须与希望的流量路由到的服务名称相同 - 并且将应用于具有匹配 serviceName
的任何路径。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTPS
# Use this annotation (which must match a service name) to route traffic to HTTP2 backends.
alb.ingress.kubernetes.io/conditions.argogrpc: |
[{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}]
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
name: argocd
namespace: argocd
spec:
rules:
- host: argocd.argoproj.io
http:
paths:
- path: /
backend:
service:
name: argogrpc
port:
number: 443
pathType: Prefix
- path: /
backend:
service:
name: argocd-server
port:
number: 443
pathType: Prefix
tls:
- hosts:
- argocd.argoproj.io
Istio
UK US /iːst’iəʊ/
可以使用以下配置将 Argo CD 置于 Istio 后面。在这里,我们将实现在 istio 后面提供 Argo CD 并在 Istio 上使用子路径
首先,我们需要确保可以使用子路径(即 /argocd
)运行 Argo CD。为此,我们按原样使用了 argocd
项目中的 install.yaml
curl -kLs -o install.yaml https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
将以下文件保存为 kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./install.yaml
patches:
- path: ./patch.yml
并将以下行作为 patch.yml
# Use --insecure so Ingress can send traffic with HTTP
# --bashref /argocd is the subpath like https://IP/argocd
# env was added because of https://github.com/argoproj/argo-cd/issues/3572 error
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
spec:
template:
spec:
containers:
- args:
- /usr/local/bin/argocd-server
- --staticassets
- /shared/app
- --redis
- argocd-redis-ha-haproxy:6379
- --insecure
- --basehref
- /argocd
- --rootpath
- /argocd
name: argocd-server
env:
- name: ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT
value: "0"
之后安装 Argo CD(当前目录中应该只有上面定义的 3 个 yml 文件)
kubectl apply -k ./ -n argocd --wait=true
确保为 Isito 创建 secret(在我们的例子中 secretname 是 argocd 命名空间上的 argocd-server-tls)。之后我们创建 Istio 资源
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: argocd-gateway
namespace: argocd
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: argocd-server-tls
maxProtocolVersion: TLSV1_3
minProtocolVersion: TLSV1_2
mode: SIMPLE
cipherSuites:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES128-SHA
- AES128-GCM-SHA256
- AES128-SHA
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
- ECDHE-ECDSA-AES256-SHA
- AES256-GCM-SHA384
- AES256-SHA
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: argocd-virtualservice
namespace: argocd
spec:
hosts:
- "*"
gateways:
- argocd-gateway
http:
- match:
- uri:
prefix: /argocd
route:
- destination:
host: argocd-server
port:
number: 80
现在我们可以浏览 http://{{ IP }}/argocd
(它将被重写为 https://{{ IP }}/argocd
带有 Kubernetes Ingress 的 Google Cloud 负载均衡器
可以利用 GKE 与 Google Cloud 的集成来仅使用 Kubernetes 对象部署负载均衡器。
为此,我们需要以下五个对象:
- Service
- BackendConfig
- FrontendConfig
- 带有 SSL 证书的密钥
- GKE 的 Ingress
如果你需要了解这些 Google 集成的所有可用选项的详细信息,你可以查看有关配置 Ingress 功能的 Google 文档
此处忽略…
通过多层身份验证反向代理进行身份验证
Argo CD 端点可能受到一个或多个反向代理层的保护,在这种情况下,您可以通过 argocd CLI --header
参数提供额外的标头来通过这些层进行身份验证。
$ argocd login <host>:<port> --header 'x-token1:foo' --header 'x-token2:bar' # can be repeated multiple times
$ argocd login <host>:<port> --header 'x-token1:foo,x-token2:bar' # headers can also be comma separated
ArgoCD 服务器和 UI 根路径 (v1.5.3)
Argo CD 服务器和 UI 可以配置为在非根路径下可用(例如 /argo-cd
)。为此,请在 argocd-server
部署命令中添加 --rootpath
标志:
spec:
template:
spec:
name: argocd-server
containers:
- command:
- /argocd-server
- --repo-server
- argocd-repo-server:8081
- --rootpath
- /argo-cd
注意:标志 --rootpath
会更改 API 服务器和 UI 基本 URL。示例 nginx.conf
:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
server {
listen 443;
location /argo-cd/ {
proxy_pass https://localhost:8080/argo-cd/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
# buffering should be disabled for api/v1/stream/applications to support chunked response
proxy_buffering off;
}
}
}
标志 --grpc-web-root-path
用于提供非根路径(例如 /argo-cd
)
$ argocd login <host>:<port> --grpc-web-root-path /argo-cd
UI 基本路径
如果 Argo CD UI 在非根路径下可用(例如 /argo-cd
而不是 /
),则应在 API 服务器中配置 UI 路径。要配置 UI 路径,请将 --basehref
标志添加到 argocd-server
部署命令中:
spec:
template:
spec:
name: argocd-server
containers:
- command:
- /argocd-server
- --repo-server
- argocd-repo-server:8081
- --basehref
- /argo-cd
注意:标志 --basehref
仅更改 UI 基本 URL。API 服务器将继续使用 /
路径,因此您需要向代理配置添加 URL 重写规则。带有 URL 重写的 nginx.conf
示例:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
server {
listen 443;
location /argo-cd {
rewrite /argo-cd/(.*) /$1 break;
proxy_pass https://localhost:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
# buffering should be disabled for api/v1/stream/applications to support chunked response
proxy_buffering off;
}
}
}
7.8.高可用性
Argo CD 基本上是无状态的。所有数据都以 Kubernetes 对象的形式保存,而这些对象又存储在 Kubernetes 的 etcd 中。Redis 仅用作一次性缓存,可能会丢失。丢失后,它将重建而不会造成服务损失。
对于希望以高可用性方式运行 Argo CD 的用户,我们提供了一组 HA 清单。这将运行更多容器,并以 HA 模式运行 Redis。
注意:由于规范中的 pod 反亲和性角色,HA 安装将需要至少三个不同的节点。此外,不支持仅 IPv6 集群。
扩展
argocd-repo-server
设置:
argocd-repo-server
负责克隆 Git 存储库、保持其更新并使用适当的工具生成清单。
argocd-repo-server
fork/exec 配置管理工具用于生成清单。由于内存不足或操作系统线程数受限,fork 可能会失败。--parallelismlimit
标志控制同时运行的清单生成数量,并有助于避免 OOM 终止。argocd-repo-server
确保在清单生成期间使用配置管理工具(例如Kustomize
、Helm
或自定义插件)时存储库处于干净状态。因此,具有多个应用程序的 Git 存储库可能会影响存储库服务器性能。有关更多信息,请阅读 Monorepo 扩展注意事项。argocd-repo-server
将存储库克隆到/tmp
(或 TMPDIR 环境变量中指定的路径)。如果 Pod 中的存储库过多或存储库中包含大量文件,则 Pod 可能会耗尽磁盘空间。为避免此问题,请挂载持久卷。argocd-repo-server
使用git ls-remote
来解析不明确的修订版本,例如 HEAD、分支或标签名称。此操作经常发生,并且可能会失败。为避免同步失败,请使用ARGOCD_GIT_ATTEMPTS_COUNT
环境变量重试失败的请求。argocd-repo-server
每 3 分钟(默认情况下)Argo CD 检查一次应用清单的更改。Argo CD 默认假定清单仅在存储库更改时更改,因此它会缓存生成的清单(默认情况下为 24 小时)。使用 Kustomize 远程基础,或者如果 Helm 图表发生更改而未改变其版本号,则即使存储库未更改,预期的清单也可能会更改。通过减少缓存时间,您无需等待 24 小时即可获得更改。使用--repo-cache-expiration
持续时间,我们建议在低容量环境中尝试“1h”。请记住,如果设置得太低,这将抵消缓存的好处。argocd-repo-server
执行配置管理工具(例如helm
或kustomize
)并强制执行 90 秒超时。可以使用ARGOCD_EXEC_TIMEOUT
环境变量更改此超时。该值应采用 Go 时间持续时间字符串格式,例如 2m30s。
指标:
argocd_git_request_total
git 请求数。此指标提供两个标签:repo
:Git repo URLrequest_type
:ls-remote
或fetch
argocd-application-controller
设置:
argocd-application-controller
使用 argocd-repo-server
来获取生成的清单,并使用 Kubernetes API
服务器来获取实际的集群状态。
- 每个控制器副本使用两个单独的队列来处理应用程序协调(毫秒)和应用程序同步(秒)。每个队列的队列处理器数量由
--status-processors
(默认为 20)和--operation-processors
(默认为 10)标志控制。如果 Argo CD 实例管理的应用程序太多,请增加处理器数量。对于 1000 个应用程序,对--status-processors
使用 50 个,对--operation-processors
使用 25 个 - 清单生成通常在协调期间花费最多时间。清单生成的持续时间受到限制,以确保控制器刷新队列不会溢出。如果清单生成花费的时间过长,则应用程序协调会失败,并出现上下文截止时间超出错误。作为解决方法,请增加
--repo-server-timeout-seconds
的值并考虑扩大argocd-repo-server
部署。 - 控制器使用 Kubernetes watch API 来维护轻量级 Kubernetes 集群缓存。这样可以避免在应用程序协调期间查询 Kubernetes,并显著提高性能。出于性能原因,控制器仅监视和缓存资源的首选版本。在协调期间,控制器可能必须将缓存的资源从首选版本转换为存储在 Git 中的资源版本。如果
kubectl convert
由于不支持转换而失败,则控制器将回退到 Kubernetes API 查询,这会减慢协调速度。在这种情况下,我们建议在 Git 中使用首选资源版本。 - 控制器默认每
3 分钟
轮询一次 Git。您可以使用argocd-cm
ConfigMap 中的timeout.reconciliation
和timeout.reconciliation.jitter
设置更改此持续时间。字段的值是持续时间字符串,例如60 秒、1 分钟、1 小时或 1 天
。 - 如果控制器管理的集群过多且占用过多内存,则可以跨多个控制器副本对集群进行分片。要启用分片,请增加
argocd-application-controller
StatefulSet 中的副本数量,并在ARGOCD_CONTROLLER_REPLICAS
环境变量中重复副本数量。下面的战略合并补丁演示了配置两个控制器副本所需的更改。 - 默认情况下,控制器会每
10 秒
更新一次集群信息,如果你的集群网络环境有问题导致更新时间过长,可以尝试修改环境变量ARGO_CD_UPDATE_CLUSTER_INFO_TIMEOUT
增加超时时间(单位为秒)。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: argocd-application-controller
spec:
replicas: 2
template:
spec:
containers:
- name: argocd-application-controller
env:
- name: ARGOCD_CONTROLLER_REPLICAS
value: "2"
- 为了手动设置集群的分片数,请在创建集群时指定可选的分片属性。如果未指定,它将由应用程序控制器动态计算。
argocd-application-controller
的分片分布算法可以通过--sharding-method
参数设置。支持的分片方法有:[legacy
(默认)、round-robin
]legacy
模式使用基于 uid 的分布(非均匀)。round-robin
在所有分片中使用均等分布。- 还可以通过在
argocd-cmd-params-cm
configMap 中设置键controller.sharding.algorithm
(最好)或通过设置ARGOCD_CONTROLLER_SHARDING_ALGORITHM
环境变量并指定相同的可能值来覆盖--sharding-method
参数。
循环分片分布算法是一项实验性功能。已知在删除集群的某些情况下会发生重新洗牌。如果删除等级为 0 的集群,则会跨分片重新洗牌所有集群,并且可能会暂时对性能产生负面影响。
- 可以通过修补集群密钥中的分片字段以包含分片编号来手动分配集群并强制分片,例如
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
shard: 1
name: mycluster.example.com
server: https://mycluster.example.com
config: |
{
"bearerToken": "<authentication token>",
"tlsClientConfig": {
"insecure": false,
"caData": "<base64 encoded certificate>"
}
}
ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM
- 启用收集 RPC 性能指标的环境变量。如果需要解决性能问题,请启用它。注意:此指标的查询和存储成本都很昂贵!ARGOCD_CLUSTER_CACHE_LIST_PAGE_BUFFER_SIZE
- 环境变量,用于控制在同步集群缓存时针对K8s api
服务器执行列表操作时控制器在内存中缓冲的页面数量。当集群包含大量资源且集群同步时间超过默认etcd
压缩间隔超时时,此功能非常有用。在这种情况下,当尝试同步集群缓存时,应用程序控制器可能会抛出错误,即continue
参数太旧而无法显示一致的列表结果。为此环境变量设置更高的值会为控制器配置更大的缓冲区,以存储异步处理的预取页面,从而增加在etcd
压缩间隔超时到期之前提取所有页面的可能性。在最极端的情况下,操作员可以设置此值,使得ARGOCD_CLUSTER_CACHE_LIST_PAGE_SIZE * ARGOCD_CLUSTER_CACHE_LIST_PAGE_BUFFER_SIZE
超过最大资源数量(按k8s api
版本分组,列表操作的并行度粒度)。在这种情况下,所有资源都将缓冲在内存中 - 不会有任何api
服务器请求被处理阻止。
指标
argocd_app_reconcile
- 报告应用程序协调持续时间。可用于构建协调持续时间热图,以获取高级协调性能图。argocd_app_k8s_request_total
- 每个应用程序的 k8s 请求数。回退Kubernetes API
查询的数量 - 有助于识别哪个应用程序具有非首选版本的资源并导致性能问题。
argocd-server
argocd-server
是无状态的,可能是最不可能引起问题的。为确保升级期间不会停机,请考虑将副本数增加到 3 个或更多,并在 ARGOCD_API_SERVER_REPLICAS
环境变量中重复该数字。下面的战略合并补丁演示了这一点。
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
spec:
replicas: 3
template:
spec:
containers:
- name: argocd-server
env:
- name: ARGOCD_API_SERVER_REPLICAS
value: "3"
设置:
ARGOCD_API_SERVER_REPLICAS
环境变量用于在每个副本之间划分并发登录请求的限制(ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT
)。ARGOCD_GRPC_MAX_SIZE_MB
环境变量允许指定服务器响应消息的最大大小(以兆字节为单位)。默认值为 200。对于管理 3000 多个应用程序的 Argo CD 实例,您可能需要增加此值。
argocd-dex-server, argocd-redis
argocd-dex-server
使用内存数据库,两个或多个实例可能会出现数据不一致的情况。argocd-redis
预先配置了仅理解总共三个 redis servers/sentinels。
Monorepo 扩展注意事项
Argo CD 存储库服务器在本地维护一个存储库克隆并将其用于应用程序清单生成。如果清单生成需要更改本地存储库克隆中的文件,则每个服务器实例只允许生成一个并发清单。如果 mono 存储库包含多个应用程序(50 个以上
),此限制可能会显著降低 Argo CD 的速度。
启用并发处理
Argo CD 根据配置管理工具和应用程序设置确定清单生成是否会更改本地存储库克隆中的本地文件。如果清单生成没有副作用,则请求将并行处理而不会影响性能。以下是可能导致速度缓慢的已知情况及其解决方法:
- 多个基于
Helm
的应用程序指向一个Git 存储库
中的同一目录:由于历史原因,Argo CD
按顺序生成Helm
清单。要启用并行生成,请将ARGOCD_HELM_ALLOW_CONCURRENCY=true
设置为argocd-repo-server
部署或创建.argocd-allow-concurrency
文件。Argo CD 的未来版本将默认启用此功能。 - 多个基于自定义插件的应用程序:避免在清单生成期间创建临时文件,并在应用程序目录中创建
.argocd-allow-concurrency
文件,或者使用sidecar
插件选项,该选项使用存储库的临时副本处理每个应用程序。 - 同一存储库中的多个 Kustomize 应用程序具有参数覆盖:抱歉,目前没有解决方法。
清单路径标注
Argo CD 积极缓存生成的清单并使用存储库提交 SHA 作为缓存键。对 Git 存储库的新提交会使存储库中配置的所有应用程序的缓存失效。这可能会对具有多个应用程序的存储库产生负面影响。可以使用 webhook
和 argocd.argoproj.io/manifest-generate-paths
应用程序 CRD 标注来解决此问题并提高性能。
argocd.argoproj.io/manifest-generate-paths
标注包含 Git 存储库中以分号分隔的路径列表,这些路径在清单生成期间使用。它将使用标注中指定的路径将上次缓存的修订与最新提交进行比较。如果没有修改的文件与 argocd.argoproj.io/manifest-generate-paths
中指定的路径匹配,则不会触发应用程序协调,现有缓存将被视为对新提交有效。
对每个应用程序使用不同存储库的安装不受此行为的影响,并且可能不会从使用这些标注中受益。
对于 webhook,比较是使用 webhook 事件负载中指定的文件进行的。
应用程序清单路径标注对 webhook 的支持取决于应用程序使用的 git 提供程序。目前仅支持基于 GitHub、GitLab 和 Gogs 的存储库。
- 相对路径标注可能包含相对路径。在这种情况下,路径被视为相对于应用程序源中指定的路径:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
annotations:
# resolves to the 'guestbook' directory
argocd.argoproj.io/manifest-generate-paths: .
spec:
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
# ...
- 绝对路径注释值可能是以
/
开头的绝对路径。在这种情况下,路径被视为 Git 存储库内的绝对路径:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
annotations:
argocd.argoproj.io/manifest-generate-paths: /guestbook
spec:
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
# ...
- 多条路径 可以将多条路径放入注释中。路径之间必须用分号 (
;
) 分隔:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
annotations:
# resolves to 'my-application' and 'shared'
argocd.argoproj.io/manifest-generate-paths: .;../shared
spec:
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: my-application
# ...
应用程序同步超时和抖动(Jitter)
Jitter 抖动
UK /ˈdʒɪt.ər/
US /ˈdʒɪt̬.ɚ/
Argo CD 对应用程序同步设置了超时时间。超时到期后,它会定期触发每个应用程序的刷新。如果应用程序数量很多,这会导致刷新队列出现峰值,并可能导致 repo-server
组件出现峰值。为了避免这种情况,您可以为同步超时设置抖动,这将分散刷新时间,并让 repo-server
有时间跟上。
抖动是可以添加到同步超时的最大持续时间,因此如果同步超时为 5 分钟而抖动为 1 分钟,则实际超时将在 5 到 6 分钟之间。
要配置抖动,可以设置以下环境变量:
ARGOCD_RECONCILIATION_JITTER
- 应用于同步超时的抖动。当值为 0 时禁用。默认为 0。
速率限制应用程序协调
为了防止由于应用程序行为不当或其他环境特定因素导致控制器资源使用率过高或同步循环,我们可以在应用程序控制器使用的工作队列上配置速率限制。可以配置两种类型的速率限制:
- 全局速率限制
- 每项费率限制
最终的速率限制器使用两者的组合,并将最终的退避计算为max(globalBackoff, perItemBackoff)
。
全局速率限制
默认情况下,此功能处于禁用状态,它是一个简单的基于存储桶的速率限制器,用于限制每秒可以排队的项目数量。这对于防止大量应用程序同时排队很有用。
要配置存储桶限制器,可以设置以下环境变量:
WORKQUEUE_BUCKET_SIZE
- 一次突发中可以排队的项目数。默认为500
。WORKQUEUE_BUCKET_QPS
- 每秒可排队的项目数。默认为MaxFloat64
,禁用限制器。
每项费率限制
默认情况下,这将返回固定的基本延迟/退避值(delay/backoff),但可以配置为返回指数值。每个项目速率限制器限制特定项目可以排队的次数。这是基于指数退避的,如果项目在短时间内多次排队,则项目的退避时间会不断呈指数增加,但如果自上次将项目排队以来已过了配置的冷却期,则退避会自动重置。
要配置每个项目限制器,可以设置以下环境变量:
WORKQUEUE_FAILURE_COOLDOWN_NS
:冷却时间(以纳秒为单位),一旦某个项目的冷却时间过去,退避就会重置。如果设置为 0(默认值),则禁用指数退避,例如值:10 * 10^9 (=10s)
WORKQUEUE_BASE_DELAY_NS
:基本延迟(以纳秒为单位),这是指数退避公式中使用的初始退避。默认为1000(=1μs)
WORKQUEUE_MAX_DELAY_NS
:最大延迟(以纳秒为单位),这是最大退避限制。默认为3 * 10^9(=3 秒)
WORKQUEUE_BACKOFF_FACTOR
:退避因子,这是每次重试增加退避的因子。默认为1.5
用于计算项目退避时间的公式,其中 numRequeue
是该项目已排队的次数,lastRequeueTime
是该项目上次排队的时间:
- 当
WORKQUEUE_FAILURE_COOLDOWN_NS != 0
时:
backoff = time.Since(lastRequeueTime) >= WORKQUEUE_FAILURE_COOLDOWN_NS ?
WORKQUEUE_BASE_DELAY_NS :
min(
WORKQUEUE_MAX_DELAY_NS,
WORKQUEUE_BASE_DELAY_NS * WORKQUEUE_BACKOFF_FACTOR ^ (numRequeue)
)
- 当
WORKQUEUE_FAILURE_COOLDOWN_NS == 0
时:
backoff = WORKQUEUE_BASE_DELAY_NS
HTTP 请求重试策略
在网络不稳定或服务器出现瞬时错误的情况下,重试策略通过自动重新发送失败的请求来确保 HTTP 通信的稳健性。它结合使用最大重试次数和退避间隔来防止服务器过载或网络崩溃。
配置重试
可以使用以下环境变量来微调重试逻辑:
ARGOCD_K8SCLIENT_RETRY_MAX
- 每个请求的最大重试次数。达到此次数后,请求将被丢弃。默认为0
(不重试)。ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF
- 第一次重试的初始退避延迟(以毫秒为单位)。后续重试将使此退避时间加倍,直至达到最大阈值。默认为100 毫秒
。
退避策略
所采用的退避策略是简单的无抖动指数退避。退避时间随着每次重试而呈指数增加,直到达到最大退避持续时间。
退避时间的计算公式为:
backoff = min(retryWaitMax, baseRetryBackoff * (2 ^ retryAttempt))
其中 retryAttempt 从 0 开始,每次后续重试增加 1。
最长等待时间
退避时间存在上限,以防止重试之间等待时间过长。此上限定义为:
retryWaitMax
- 重试前等待的最大时长。这可确保重试在合理的时间范围内进行。默认为10 秒
。
不可重审的条件
并非所有 HTTP 响应都符合重试条件。以下情况不会触发重试:
- 响应状态代码表示客户端错误(4xx),但 429 请求过多除外。
- 状态代码为 501 未实施的响应。
动态集群分布
目前状态:Alpha(自 v2.9.0 起)
默认情况下,集群会无限期地分配给分片。对于使用默认的基于哈希的分片算法的用户来说,这种静态分配是可以的:分片将始终通过基于哈希的算法大致平衡。但对于使用循环或其他自定义分片分配算法的用户来说,这种静态分配可能会导致在添加或删除副本时分片不平衡。
从 v2.9 开始,Argo CD 支持动态集群分布功能。添加或删除副本时,将重新运行分片算法,以确保集群按照算法进行分布。如果算法均衡,如循环,则分片也将均衡。
以前,分片数量是通过 ARGOCD_CONTROLLER_REPLICAS
环境变量设置的。更改环境变量会强制重新启动所有应用程序控制器 pod
。现在,分片数量是通过部署的replicas
字段设置的,不需要重新启动应用程序控制器 pod
。
实现集群的动态分布
此功能处于 alpha
阶段时默认处于禁用状态。为了利用此功能,清单 manifests/ha/base/controller-deployment/
可以作为 Kustomize 覆盖应用。此覆盖将 StatefulSet 副本设置为 0,并将应用程序控制器部署为 Deployment。此外,在将应用程序控制器作为部署运行时,必须将环境 ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION
设置为 true
。
使用 Deployment 而不是 StatefulSet 是一个实现细节,此功能的未来版本可能会发生变化。因此,Kustomize 覆盖的目录名称也可能会发生变化。请关注发行说明以避免出现问题。
注意引入了新的环境变量 ARGOCD_CONTROLLER_HEARTBEAT_TIME
。环境变量在动态分布心跳过程的工作原理中进行了说明
动态分布的工作原理
为了完成集群的运行时分布,应用程序控制器使用 ConfigMap 将控制器 pod 与分片号和心跳关联起来,以确保控制器 pod 仍然活跃并且处理它们的分片,实际上是它们的工作份额。
应用程序控制器将创建一个名为 argocd-app-controller-shard-cm
的新 ConfigMap 来存储Controller <-> Shard
映射。每个分片的映射如下所示:
ShardNumber : 0
ControllerName : "argocd-application-controller-hydrxyt"
HeartbeatTime : "2009-11-17 20:34:58.651387237 +0000 UTC"
ControllerName
:存储应用程序控制器 pod 的主机名ShardNumber
:存储控制器 pod 管理的分片编号HeartbeatTime
:存储上次更新此心跳的时间
控制器分片映射在 ConfigMap 中更新,每次检查 pod
的就绪探测时更新一次,即每 10 秒
更新一次(否则按配置)。控制器将在每次迭代就绪探测检查期间获取分片,并尝试使用 HeartbeatTime
更新 ConfigMap。默认 HeartbeatDuration
为 10 秒,在此之后应更新心跳。如果任何控制器 pod
的 ConfigMap 未更新超过 3 * HeartbeatDuration
,则应用程序 pod
的就绪探测将被标记为不健康。要增加默认 HeartbeatDuration
,可以将环境变量 ARGOCD_CONTROLLER_HEARTBEAT_TIME
设置为所需值。
新的分片机制不再监控环境变量ARGOCD_CONTROLLER_REPLICAS
,而是直接从Application Controller Deployment
中读取副本数,Controller通过对比Application Controller Deployment
中的副本数和argocd-app-controller-shard-cm
ConfigMap中的映射数来判断副本数的变化。
在应用程序控制器副本数量增加的情况下,会在 argocd-app-controller-shard-cm
ConfigMap 中的映射列表中添加新条目,并触发集群分发以重新分配集群。
在应用程序控制器副本数量减少的情况下,argocd-app-controller-shard-cm
ConfigMap 中的映射将被重置,并且每个控制器都会再次获取分片,从而触发集群的重新分配。
7.9.用户管理
安装后,Argo CD 会有一个内置管理员用户,该用户对系统具有完全访问权限。建议仅在初始配置时使用管理员用户,然后切换到本地用户或配置 SSO 集成。
概述
本地用户/帐户
本地用户/帐户功能主要有两个用途:
- 用于 Argo CD 管理自动化的身份验证令牌。可以配置具有有限权限的 API 帐户并生成身份验证令牌。此类令牌可用于自动创建应用程序、项目等。
- 对于非常小的团队来说,使用 SSO 集成可能被认为是过度的。本地用户不提供群组、登录历史记录等高级功能。因此,如果需要此类功能,强烈建议使用 SSO。
当创建本地用户时,每个用户都需要设置额外的 RBAC 规则,否则将恢复到
argocd-rbac-cm
ConfigMap 的policy.default
字段指定的默认策略。
本地帐户的用户名最大长度为 32。
创建新用户
新用户应该在 argocd-cm
ConfigMap 中定义:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
# add an additional local user with apiKey and login capabilities
# apiKey - allows generating API keys
# login - allows to login using UI
accounts.alice: apiKey, login
# disables user. User is enabled by default
accounts.alice.enabled: "false"
每个用户可能有两种能力:
apiKey
- 允许生成用于 API 访问的身份验证令牌login
- 允许使用 UI 登录
删除用户
为了删除用户,必须删除 argocd-cm
ConfigMap 中定义的相应条目:
例子:
kubectl patch -n argocd cm argocd-cm --type='json' -p='[{"op": "remove", "path": "/data/accounts.alice"}]'
建议还删除 argocd-secret
Secret 中的密码条目:
例子:
kubectl patch -n argocd secrets argocd-secret --type='json' -p='[{"op": "remove", "path": "/data/accounts.alice.password"}]'
禁用管理员用户
一旦创建了其他用户,建议禁用管理员用户:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
admin.enabled: "false"
管理用户
Argo CD CLI 提供了一组命令来设置用户密码和生成令牌。
- 获取完整用户列表
argocd account list
- 获取特定用户的详细信息
argocd account get --account <username>
- 设置用户密码
# if you are managing users as the admin user, <current-user-password> should be the current admin password.
argocd account update-password \
--account <name> \
--current-password <current-user-password> \
--new-password <new-user-password>
- 生成身份验证令牌
# if flag --account is omitted then Argo CD generates token for current user
argocd account generate-token --account <username>
限制登录失败率
为了防止密码暴力破解,Argo CD 会在登录尝试失败次数过多后拒绝登录尝试。以下环境变量可用于控制限制设置:
ARGOCD_SESSION_FAILURE_MAX_FAIL_COUNT
:Argo CD 开始拒绝登录尝试之前的最大登录失败次数。默认值:5
。ARGOCD_SESSION_FAILURE_WINDOW_SECONDS
:失败窗口的秒数。默认值:300(5 分钟)
。如果设置为0
,则禁用失败窗口,并且连续10
次登录失败后,登录尝试将被拒绝,无论发生的时间范围如何。ARGOCD_SESSION_MAX_CACHE_SIZE
:缓存中允许的最大条目数。默认值:1000
ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT
:限制最大并发登录请求数。如果设置为0
,则限制被禁用。默认值:50
。
SSO
有两种方法可以配置 SSO:
- 捆绑 Dex OIDC 提供商 - 如果当前的提供商不支持 OIDC(例如 SAML、LDAP)或者希望利用 Dex 的任何连接器功能(例如将 GitHub 组织和团队映射到 OIDC 组声明的能力),请使用此选项。Dex 还直接支持 OIDC,并且可以在组无法包含在 IDToken 中时从身份提供商处获取用户信息。
- 现有的 OIDC 提供商 - 如果已经有正在使用的 OIDC 提供商(例如 Okta、OneLogin、Auth0、Microsoft、Keycloak、Google(G Suite)),可以使用此选项来管理您的用户、群组和会员资格。
Dex
Argo CD 将 Dex 嵌入并捆绑在其安装中,目的是将身份验证委托给外部身份提供者。支持多种类型的身份提供者(OIDC、SAML、LDAP、GitHub 等)。Argo CD 的 SSO 配置需要使用 Dex 连接器设置编辑 argocd-cm
ConfigMap。
本文档以 GitHub(OAuth2)为例介绍了如何配置 Argo CD SSO,但对于其他身份提供者,步骤应该类似。
1. 在身份提供者中注册应用程序
在 GitHub 中注册一个新应用程序。回调地址应该是 Argo CD URL 的 /api/dex/callback
端点(例如 https://argocd.example.com/api/dex/callback
)。
注册应用程序后,将收到一个 OAuth2 客户端 ID 和密钥。这些值将输入到 Argo CD 配置映射中。
2. 配置 Argo CD 进行 SSO
编辑 argocd-cm 配置映射:
kubectl edit configmap argocd-cm -n argocd
- 在
url
键中,输入 Argo CD 的基本 URL。在此示例中,它是https://argocd.example.com
- 在
dex.config
键中,将 GitHub 连接器添加到connectors
子字段。请参阅 Dex 的 GitHub 连接器文档以了解字段的说明。最小配置应填充步骤 1 中生成的 clientID、clientSecret。 - 很可能希望将登录限制到一个或多个 GitHub 组织。在
connectors.config.orgs
列表中,添加一个或多个 GitHub 组织。然后,该组织的任何成员都可以登录 Argo CD 执行管理任务。
data:
url: https://argocd.example.com
dex.config: |
connectors:
# GitHub example
- type: github
id: github
name: GitHub
config:
clientID: aabbccddeeff00112233
clientSecret: $dex.github.clientSecret # Alternatively $<some_K8S_secret>:dex.github.clientSecret
orgs:
- name: your-github-org
# GitHub enterprise example
- type: github
id: acme-github
name: Acme GitHub
config:
hostName: github.acme.example.com
clientID: abcdefghijklmnopqrst
clientSecret: $dex.acme.clientSecret # Alternatively $<some_K8S_secret>:dex.acme.clientSecret
orgs:
- name: your-github-org
保存后,更改将自动生效。
笔记:
- 无需在
connectors.config
中设置redirectURI
,如 dex 文档中所示。Argo CD 将自动为任何 OAuth2 连接器使用正确的 redirectURI,以匹配正确的外部回调 URL(例如https://argocd.example.com/api/dex/callback
)- 当使用自定义密钥(例如上面的
some_K8S_secret
)时,它必须具有标签app.kubernetes.io/part-of: argocd
。
使用 DEX 的 OIDC 配置
Dex 可直接用于 OIDC 身份验证,而不是 ArgoCD。这提供了一组单独的功能,例如从UserInfo
端点和联合令牌获取信息
配置:
在 argocd-cm
ConfigMap 中,将 OIDC 连接器添加到 dex.config
内的连接器子字段。请参阅 Dex 的 OIDC 连接文档,了解其他哪些配置选项可能有用。我们将在这里使用最小配置。
发行者 URL 应该是 Dex 与 OIDC 提供商对话的地方。此 URL 下通常会有一个 .well-known/openid-configuration
,其中包含有关提供商支持的内容的信息。例如 https://accounts.google.com/.well-known/openid-configuration
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: oidc
id: oidc
name: OIDC
config:
issuer: https://example-OIDC-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
请求其他 ID 令牌声明
默认情况下,Dex 仅检索个人资料和电子邮件范围。为了检索更多声明,可以在 Dex 配置中的范围条目下添加它们。要通过 Dex 启用组声明,还需要启用 insecureEnableGroups
。组信息目前仅在身份验证时刷新,可以在此处跟踪更动态地刷新组信息的支持:dexidp/dex#1065
。
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: OIDC
id: oidc
name: OIDC
config:
issuer: https://example-OIDC-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
由于组信息仅在身份验证时刷新,因此仅向组中添加或删除帐户不会改变用户的成员身份,直到用户重新进行身份验证为止。根据您组织的需求,这可能是一个安全风险,可以通过更改身份验证令牌的生命周期来缓解。
检索不在令牌中的声明
当 Idp 不支持或无法支持 IDToken 中的某些声明时,可以使用 UserInfo
端点单独检索这些声明。Dex 使用 getUserInfo
端点支持此功能。IDToken 中不支持的最常见声明之一是groups
声明,并且 getUserInfo
和 insecureEnableGroups
都必须设置为 true
。
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: OIDC
id: oidc
name: OIDC
config:
issuer: https://example-OIDC-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
getUserInfo: true
现有的 OIDC 提供商
要配置 Argo CD 以将身份验证委托给现有的 OIDC 提供商,请将 OAuth2 配置添加到 oidc.config
键下的 argocd-cm
ConfigMap 中:
data:
url: https://argocd.example.com
oidc.config: |
name: Okta
issuer: https://dev-123456.oktapreview.com
clientID: aaaabbbbccccddddeee
clientSecret: $oidc.okta.clientSecret
# Optional list of allowed aud claims. If omitted or empty, defaults to the clientID value above (and the
# cliClientID, if that is also specified). If you specify a list and want the clientID to be allowed, you must
# explicitly include it in the list.
# Token verification will pass if any of the token's audiences matches any of the audiences in this list.
allowedAudiences:
- aaaabbbbccccddddeee
- qqqqwwwweeeerrrrttt
# Optional. If false, tokens without an audience will always fail validation. If true, tokens without an audience
# will always pass validation.
# Defaults to true for Argo CD < 2.6.0. Defaults to false for Argo CD >= 2.6.0.
skipAudienceCheckWhenTokenHasNoAudience: true
# Optional set of OIDC scopes to request. If omitted, defaults to: ["openid", "profile", "email", "groups"]
requestedScopes: ["openid", "profile", "email", "groups"]
# Optional set of OIDC claims to request on the ID token.
requestedIDTokenClaims: {"groups": {"essential": true}}
# Some OIDC providers require a separate clientID for different callback URLs.
# For example, if configuring Argo CD with self-hosted Dex, you will need a separate client ID
# for the 'localhost' (CLI) client to Dex. This field is optional. If omitted, the CLI will
# use the same clientID as the Argo CD server
cliClientID: vvvvwwwwxxxxyyyyzzzz
# PKCE authentication flow processes authorization flow from browser only - default false
# uses the clientID
# make sure the Identity Provider (IdP) is public and doesn't need clientSecret
# make sure the Identity Provider (IdP) has this redirect URI registered: https://argocd.example.com/pkce/verify
enablePKCEAuthentication: true
回调地址应该是 Argo CD URL 的
/auth/callback
端点(例如https://argocd.example.com/auth/callback
)。
请求其他 ID 令牌声明
并非所有 OIDC 提供商都支持特殊组范围。例如,Okta、OneLogin 和 Microsoft 都支持特殊groups
范围,并将使用默认的 requestedScopes
返回groups
成员身份。
如果明确要求,其他 OIDC 提供商可能能够返回具有组成员身份的声明。可以使用 requestedIDTokenClaims
请求单个声明,有关详细信息,请参阅 OpenID Connect 声明参数。Argo CD 的声明配置如下:
oidc.config: |
requestedIDTokenClaims:
email:
essential: true
groups:
essential: true
value: org:myorg
acr:
essential: true
values:
- urn:mace:incommon:iap:silver
- urn:mace:incommon:iap:bronze
对于简单情况,这可以是:
oidc.config: |
requestedIDTokenClaims: {"groups": {"essential": true}}
检索不在令牌中的组声明
某些 OIDC 提供商不会在 ID 令牌中返回用户的组信息,即使使用 equestedIDTokenClaims
设置明确请求(例如 Okta
)。它们改为在用户信息端点上提供组。使用以下配置,Argo CD 在登录期间查询用户信息端点以获取用户的组信息:
oidc.config: |
enableUserInfoGroups: true
userInfoPath: /userinfo
userInfoCacheExpiration: "5m"
注意:如果省略
userInfoCacheExpiration
设置或者它大于 ID 令牌的有效期,则只要 ID 令牌有效,argocd-server
就会缓存组信息!
为 OIDC 提供商配置自定义注销 URL
如果 OIDC 提供商公开了注销 API,这样可以配置自定义注销 URL 以便在注销后使任何活动会话无效,按如下方式指定它:
oidc.config: |
name: example-OIDC-provider
issuer: https://example-OIDC-provider.example.com
clientID: xxxxxxxxx
clientSecret: xxxxxxxxx
requestedScopes: ["openid", "profile", "email", "groups"]
requestedIDTokenClaims: {"groups": {"essential": true}}
logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}}
默认情况下,这会在用户注销后将用户带到其 OIDC 提供商的登录页面。如果在用户注销后将用户重定向回 Argo CD,您可以按如下方式指定注销 URL:
...
logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}
不需要指定 logoutRedirectURL
,因为它是由 ArgoCD 自动生成的,作为基本 ArgoCD url + Rootpath
注销后重定向 URI 可能需要根据您的 OIDC 提供商的 ArgoCD 客户端设置列入白名单。
配置自定义根 CA 证书以便与 OIDC 提供商进行通信
如果 OIDC 提供商设置的证书不是由知名证书颁发机构签名的,可以提供一个自定义证书,该证书将在与 OIDC 提供商通信时用于验证其 TLS 证书。
将包含 PEM 编码根证书的 rootCA 添加到 oidc.config
中:
oidc.config: |
...
rootCA: |
-----BEGIN CERTIFICATE-----
... encoded certificate data here ...
-----END CERTIFICATE-----
SSO 延伸阅读
敏感数据和 SSO 客户端机密
argocd-secret
可用于存储可被 ArgoCD 引用的敏感数据。configmap
中以 $
开头的值解释如下:
- 如果值的形式为:
$<secret>:a.key.in.k8s.secret
,则查找名为<secret>
(减去$
)的 k8s secret,并读取其值。 - 否则,在名为
argocd-secret
的 k8s 密钥中查找密钥。
例子
因此,SSO clientSecret 可以作为 Kubernetes 密钥存储,具体清单如下
argocd-secret
:
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
labels:
app.kubernetes.io/name: argocd-secret
app.kubernetes.io/part-of: argocd
type: Opaque
data:
...
# The secret value must be base64 encoded **once**
# this value corresponds to: `printf "hello-world" | base64`
oidc.auth0.clientSecret: "aGVsbG8td29ybGQ="
...
argocd-cm
:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
...
oidc.config: |
name: Auth0
clientID: aabbccddeeff00112233
# Reference key in argocd-secret
clientSecret: $oidc.auth0.clientSecret
...
选择
如果你想将敏感数据存储在另一个 Kubernetes Secret 中,而不是 argocd-secret 中。每当 configmap 或 secret 中的值以 $
开头时,ArgoCD 就会检查 Kubernetes Secret 中数据下的键以查找相应的键,然后是 Kubernetes Secret
名称和 :
(冒号)。
语法:$<k8s_secret_name>:<a_key_in_that_k8s_secret>
注意:Secret 必须有标签
app.kubernetes.io/part-of: argocd
例子
another-secret
:
apiVersion: v1
kind: Secret
metadata:
name: another-secret
namespace: argocd
labels:
app.kubernetes.io/part-of: argocd
type: Opaque
data:
...
# Store client secret like below.
# Ensure the secret is base64 encoded
oidc.auth0.clientSecret: <client-secret-base64-encoded>
...
argocd-cm
:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
...
oidc.config: |
name: Auth0
clientID: aabbccddeeff00112233
# Reference key in another-secret (and not argocd-secret)
clientSecret: $another-secret:oidc.auth0.clientSecret # Mind the ':'
...
跳过 OIDC 提供商连接上的证书验证
默认情况下,API 服务器与 OIDC 提供商(外部提供商或捆绑的 Dex 实例)建立的所有连接都必须通过证书验证。这些连接在获取 OIDC 提供商的已知配置、获取 OIDC 提供商的密钥以及在 OIDC 登录流程中交换授权码或验证 ID 令牌时发生。
如果出现以下情况,禁用证书验证可能是有意义的:
*
你正在使用捆绑的 Dex 实例,并且您的 Argo CD 实例已使用自签名证书配置了 TLS,并且您了解并接受跳过 OIDC 提供商证书验证的风险。*
你正在使用外部 OIDC 提供商,并且该提供商使用无效证书,并且您无法通过设置oidcConfig.rootCA
来解决问题,并且了解并接受跳过 OIDC 提供商证书验证的风险。
如果上述两种情况之一适用,那么可以通过在 argocd-cm
ConfigMap 中将 oidc.tls.insecure.skip.verify
设置为“true”来禁用 OIDC 提供商证书验证。
Auth0
用户定义
Auth0 中的用户定义超出了本指南的范围。直接在 Auth0 数据库中添加它们,使用企业注册表或“social login”。注意:所有用户都可以访问所有 Auth0 定义的应用程序,除非通过配置限制访问 - 如果 argo 在互联网上公开,请记住这一点,否则任何人都可以登录。
使用 Auth0 注册应用程序
按照注册应用程序说明在 Auth0 中创建 argocd 应用程序。在应用程序定义中:
- 记下
clientId
和clientSecret
值。 - 注册登录网址为
https://your.argoingress.address/login
- 将允许的回调 URL 设置为
https://your.argoingress.address/auth/callback
- 在连接下,选择想要与 argo 一起使用的用户注册表。
任何其他设置对于身份验证工作来说都是不必要的。
向 Auth0 添加授权规则
按照 Auth0 授权指南设置授权。这里要注意的重要部分是,组成员身份是非标准声明,因此需要放在 FQDN 声明名称下,例如 http://your.domain/groups
。
配置 argo
为 ArgoCD 配置 OIDC
kubectl edit configmap argocd-cm
...
data:
application.instanceLabelKey: argocd.argoproj.io/instance
url: https://your.argoingress.address
oidc.config: |
name: Auth0
issuer: https://<yourtenant>.<eu|us>.auth0.com/
clientID: <theClientId>
clientSecret: <theClientSecret>
requestedScopes:
- openid
- profile
- email
# not strictly necessary - but good practice:
- 'http://your.domain/groups'
...
为 ArgoCD 配置 RBAC
kubectl edit configmap argocd-rbac-cm
(或者使用 helm 值)。
...
data:
policy.csv: |
# let members with group someProjectGroup handle apps in someProject
# this can also be defined in the UI in the group-definition to avoid doing it there in the configmap
p, someProjectGroup, applications, *, someProject/*, allow
# let the group membership argocd-admins from OIDC become role:admin - needs to go into the configmap
g, argocd-global-admins, role:admin
policy.default: role:readonly
# essential to get argo to use groups for RBAC:
scopes: '[http://your.domain/groups, email]'
...
有关安全正确地存储客户端机密的详细信息,请参阅用户管理概述页面。
microsoft
此处忽略…,具体参考
Okta
此处忽略…,具体参考
OneLogin
此处忽略…,具体参考
Keycloak
此处忽略…,具体参考
OpenUnison
此处忽略…,具体参考
此处忽略…,具体参考
Zitadel
此处忽略…,具体参考
AWS SSO
此处忽略…,具体参考
RBAC 配置
RBAC 功能可以限制对 Argo CD 资源的访问。Argo CD 没有自己的用户管理系统,只有一个内置用户管理员。管理员用户是超级用户,可以不受限制地访问系统。RBAC 需要 SSO 配置或设置一个或多个本地用户。配置 SSO 或本地用户后,可以定义其他 RBAC 角色,然后可以将 SSO 组或本地用户映射到角色。
基本内置角色
Argo CD 有两个预定义角色,但 RBAC 配置允许定义角色和组(见下文)。
role:readonly
- 对所有资源的只读访问role:admin
- 不受限制地访问所有资源
这些默认的内置角色定义可以在builtin-policy.csv
中看到
RBAC 权限结构
在 Argo CD 中,权限定义的细分在应用程序和其他每种资源类型之间略有不同。
- 除应用程序特定权限之外的所有资源(请参阅下一个项目符号):
p, <role/user/group>, <resource>, <action>, <object>
- 应用程序、应用程序集、日志和 exec(属于
AppProject
):p, <role/user/group>, <resource>, <action>, <appproject>/<object>
RBAC 资源和动作
- 资源:
clusters, projects, applications, applicationsets, repositories, certificates, accounts, gpgkeys, logs, exec, extensions
- 动作:
get, create, update, delete, sync, override,action/<group/kind/action-name>
请注意,sync、override 和 action/<group/kind/action-name>
仅对应用程序资源有意义。
应用资源
应用程序对象的资源路径的形式为<project-name>/<application-name>
。
无法精细地管理对项目子资源(例如 rollout
或 pod
)的删除访问权限。<project-name>/<application-name>
授予对应用程序所有子资源的访问权限。
action动作
操作 action 对应于 Argo CD 存储库中定义的内置资源自定义,或您定义的自定义资源操作。操作路径的格式为 action/<api-group>/<Kind>/<action-name>
。例如,资源自定义路径 resource_customizations/extensions/DaemonSet/actions/restart/action.lua
对应于操作路径 action/extensions/DaemonSet/restart
。还可以在操作路径中使用 glob
模式:action/*
(或正则表达式模式,如果已启用正则表达式匹配模式)。
如果资源不在组下(例如,Pod
或 ConfigMaps
),则从 RBAC
配置中省略组名:p, example-user, applications, action//Pod/maintenance-off, default/*, allow
exec资源
exec
是一种特殊资源。当通过 create
操作启用时,此权限允许用户通过 Argo CD UI
执行 Pod 操作。该功能类似于 kubectl exec
。
请参阅基于 Web 的终端以了解更多信息。
applicationsets资源
ApplicationSets 提供了一种声明性的方式来自动create/update/delete
应用程序。
授予 applicationsets, create
权限实际上授予了创建应用程序的能力。虽然它不允许用户直接创建应用程序,但他们可以通过 ApplicationSet
创建应用程序。
在 v2.5 中,无法通过 API(或 CLI)创建具有模板化 Project
字段的 ApplicationSet
(例如 project: {{path.basename}}
)。禁止模板化项目可确保通过 RBAC 进行项目限制的安全:p, dev-group, applicationsets, *, dev-project/*, allow
有了此规则,dev-group
用户将无法创建能够在 dev-project
项目之外创建应用程序的 ApplicationSet
。
extensions资源
使用扩展资源可以配置权限以调用代理扩展。扩展 RBAC 验证与应用程序资源协同工作。登录 Argo CD(UI 或 CLI)的用户需要至少对请求来源的项目、命名空间和应用程序具有读取权限。
请考虑以下示例:
g, ext, role:extension
p, role:extension, applications, get, default/httpbin-app, allow
p, role:extension, extensions, invoke, httpbin, allow
解释:
- line1: 定义与主题
ext
关联的组role:extension
。 - line2:定义一个策略,允许该角色读取(
get
)项目中的default/httpbin-app
应用程序。 - line3:定义另一个允许该角色
invoke
,httpbin
扩展的策略。
注1:为了允许扩展请求,还需要第2行中定义的策略。
注 2:invoke
是专门为与extensions
资源配合使用而引入的新操作。的当前操作extensions
为*
或invoke
。
把所有东西结合在一起
可以在 argocd-rbac-cm
ConfigMap 中配置其他角色和组。下面的示例配置了一个名为 org-admin
的自定义角色。该角色分配给属于 your-github-org:your-team
组的任何用户。所有其他用户都获得默认策略 role:readonly
,该策略无法修改 Argo CD
设置。
所有经过身份验证的用户至少会获得默认策略授予的权限。此访问无法通过拒绝规则阻止。相反,应限制默认策略,然后根据需要向各个角色授予权限。
ArgoCD ConfigMap argocd-rbac-cm
示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, get, *, allow
p, role:org-admin, repositories, create, *, allow
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
p, role:org-admin, projects, get, *, allow
p, role:org-admin, projects, create, *, allow
p, role:org-admin, projects, update, *, allow
p, role:org-admin, projects, delete, *, allow
p, role:org-admin, logs, get, *, allow
p, role:org-admin, exec, create, */*, allow
g, your-github-org:your-team, role:org-admin
另一个 ·policy.csv· 示例可能如下所示:
p, role:staging-db-admin, applications, create, staging-db-project/*, allow
p, role:staging-db-admin, applications, delete, staging-db-project/*, allow
p, role:staging-db-admin, applications, get, staging-db-project/*, allow
p, role:staging-db-admin, applications, override, staging-db-project/*, allow
p, role:staging-db-admin, applications, sync, staging-db-project/*, allow
p, role:staging-db-admin, applications, update, staging-db-project/*, allow
p, role:staging-db-admin, logs, get, staging-db-project/*, allow
p, role:staging-db-admin, exec, create, staging-db-project/*, allow
p, role:staging-db-admin, projects, get, staging-db-project, allow
g, db-admins, role:staging-db-admin
此示例定义了一个名为 staging-db-admin
的角色,该角色具有九个权限,允许具有该角色的用户执行以下操作:
- 为
staging-db-project
项目中的应用程序·create, delete, get, override, sync, update·, - 为
staging-db-project
项目中的对象get
日志, - 为
staging-db-project
项目中的对象create
exec, - 并为名为
staging-db-project
的项目get
。
scopes
字段控制在 rbac 执行期间检查哪些 OIDC 范围(除了sub
范围)。如果省略,则默认为: ‘[groups]’ 。范围值可以是字符串或字符串列表。
以下示例显示了来自 OIDC 提供商的定位email
以及groups
。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-rbac-cm
app.kubernetes.io/part-of: argocd
data:
policy.csv: |
p, my-org:team-alpha, applications, sync, my-project/*, allow
g, my-org:team-beta, role:admin
g, user@example.org, role:admin
policy.default: role:readonly
scopes: '[groups, email]'
有关范围的更多信息,请参阅用户管理文档。
政策 CSV 组成
可以在 argocd-rbac-cm
configmap 中提供其他条目来组成最终策略 csv。在这种情况下,密钥必须遵循模式 policy.<any string>.csv
。Argo CD 会将它找到的所有附加策略与此模式连接在主策略(policy.csv
)下。附加提供的策略的顺序由密钥字符串决定。例如:如果提供了两个附加策略,其密钥分别为 policy.A.csv
和 policy.B.csv
,它将首先连接 policy.A.csv
,然后连接 policy.B.csv
。
这对于允许在 Kustomize、Helm 等配置管理工具中编写策略很有用。
下面的示例展示了如何在覆盖中提供 Kustomize 补丁以向现有 RBAC 策略添加额外配置。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.tester-overlay.csv: |
p, role:tester, applications, *, */*, allow
p, role:tester, projects, *, *, allow
g, my-org:team-qa, role:tester
匿名访问
可以使用 argocd-cm
中的 users.anonymous.enabled
字段启用对 Argo CD 的匿名访问(参见 argocd-cm.yaml
)。匿名用户获得由 argocd-rbac-cm.yaml
中的 policy.default
指定的默认角色权限。对于只读访问,需要使用如上所述的 policy.default: role:readonly
验证和测试 RBAC 策略
如果想确保 RBAC 策略按预期工作,可以使用 argocd admin settings rbac
命令来验证它们。此工具允许测试某个角色或主体是否可以使用系统中尚未生效的策略(即来自本地文件或配置映射)执行请求的操作。此外,它还可以用于 Argo CD 正在运行的集群中的实时策略。
要检查新策略是否有效并被 Argo CD 的 RBAC 实现理解,您可以使用 argocd admin settings rbac verify
命令。
验证策略
要验证存储在本地文本文件中的策略:
argocd admin settings rbac validate --policy-file somepolicy.csv
要验证 YAML 文件中本地 K8s ConfigMap 定义中存储的策略:
argocd admin settings rbac validate --policy-file argocd-rbac-cm.yaml
要验证存储在 K8s 中的策略(由 Argo CD 在命名空间 argocd 中使用),请确保 ~/.kube/config
中的当前上下文指向 Argo CD 集群并提供适当的命名空间:
argocd admin settings rbac validate --namespace argocd
测试策略
要测试角色或主体(组或本地用户)是否具有足够的权限对某些资源执行某些操作,可以使用 argocd admin settings rbac can
命令。其一般语法为
argocd admin settings rbac can SOMEROLE ACTION RESOURCE SUBRESOURCE [flags]
鉴于上述 ConfigMap 中的示例,它定义角色 role:org-admin
,并以 argocd-rbac-cm-yaml
的形式存储在本地系统中,您可以测试该角色是否可以执行如下操作:
$ argocd admin settings rbac can role:org-admin get applications --policy-file argocd-rbac-cm.yaml
Yes
$ argocd admin settings rbac can role:org-admin get clusters --policy-file argocd-rbac-cm.yaml
Yes
$ argocd admin settings rbac can role:org-admin create clusters 'somecluster' --policy-file argocd-rbac-cm.yaml
No
$ argocd admin settings rbac can role:org-admin create applications 'someproj/someapp' --policy-file argocd-rbac-cm.yaml
Yes
另一个示例,给定来自 policy.csv 的上述策略,该策略定义角色 role:staging-db-admin
并将组 db-admins
与其关联。策略在本地存储为 policy.csv
:
可以针对该角色进行测试:
$ # Plain policy, without a default role defined
$ argocd admin settings rbac can role:staging-db-admin get applications --policy-file policy.csv
No
$ argocd admin settings rbac can role:staging-db-admin get applications 'staging-db-project/*' --policy-file policy.csv
Yes
$ # Argo CD augments a builtin policy with two roles defined, the default role
$ # being 'role:readonly' - You can include a named default role to use:
$ argocd admin settings rbac can role:staging-db-admin get applications --policy-file policy.csv --default-role role:readonly
Yes
或者针对定义的组:
$ argocd admin settings rbac can db-admins get applications 'staging-db-project/*' --policy-file policy.csv
Yes
7.10.安全
Argo CD 经过了严格的内部安全审查和渗透测试,以满足 PCI 合规性要求。以下是 Argo CD 的一些安全主题和实施细节。
概括
身份验证
Argo CD API 服务器的身份验证仅使用 JSON Web Tokens (JWT) 执行。用户名/密码承载令牌不用于身份验证。JWT 可通过以下方式之一获取/管理:
- 对于本地
admin
用户,使用/api/v1/session
端点将用户名/密码交换为 JWT。此令牌由 Argo CD API 服务器本身签名和颁发,并在 24 小时后过期(此令牌以前不会过期,请参阅 CVE-2021-26921)。更新管理员密码后,所有现有的管理员 JWT 令牌都会立即被撤销。密码以bcrypt
哈希的形式存储在argocd-secret
Secret 中。 - 对于单点登录用户,用户完成 OAuth2 登录流程,登录到已配置的 OIDC 身份提供商(通过捆绑的 Dex 提供商委托,或直接委托给自管理的 OIDC 提供商)。此 JWT 由 IDP 签名和颁发,到期和撤销由提供商处理。Dex 令牌将在 24 小时后过期。
- 使用
/api/v1/projects/{project}/roles/{role}/token
端点为项目生成自动化令牌,并由 Argo CD 签名和颁发。这些令牌的范围和权限有限,只能用于管理其所属项目中的应用程序资源。项目 JWT 具有可配置的有效期,可以通过从项目角色中删除 JWT 引用 ID 立即撤销。
授权
授权是通过迭代用户 JWT 组声明中的组成员列表,并将每个组与 RBAC 策略中的角色/规则进行比较来执行的。任何匹配的规则都允许访问 API 请求。
TLS
所有网络通信均通过 TLS 进行,包括三个组件(argocd-server、argocd-repo-server、argocd-application-controller
)之间的服务到服务通信。Argo CD API 服务器可以使用以下标志强制使用 TLS 1.2:--tlsminversion 1.2
。默认情况下,与 Redis 的通信通过纯 HTTP 进行。可以使用命令行参数设置 TLS。
Git 和 Helm 存储库
Git 和 helm 存储库由独立服务(称为 repo-server
)管理。repo-server
不具有任何 Kubernetes 权限,也不存储任何服务(包括 git
)的凭据。repo-server
负责克隆已获得 Argo CD 操作员允许和信任的存储库,并在存储库中的给定路径生成 Kubernetes 清单。为了提高性能和带宽效率,repo-server
维护这些存储库的本地克隆,以便高效下载对存储库的后续提交。
配置允许 Argo CD 部署的 git 存储库时需要考虑安全问题。简而言之,未经授权获取 Argo CD 信任的 git 存储库的写入权限将产生如下所述的严重安全隐患。
未经授权的部署
由于 Argo CD 部署了 git
中定义的 Kubernetes 资源,因此有权访问受信任 git
存储库的攻击者将能够影响已部署的 Kubernetes 资源。例如,攻击者可以更新部署清单,将恶意容器映像部署到环境中,或者删除 git
中的资源,导致它们在实时环境中被删除。
工具命令调用
除了原始 YAML,Argo CD 还原生支持两种流行的 Kubernetes 配置管理工具:helm
和 kustomize
。在呈现清单时,Argo CD 会执行这些配置管理工具(即 helm template、kustomize build
)来生成清单。具有受信任git
存储库写权限的攻击者可能会构建恶意的 helm chart
或 kustomizations
,试图读取树外的文件。这包括相邻的 git
存储库,以及存储库服务器本身上的文件。这是否对组织构成风险取决于 git
存储库中的内容是否本质上是敏感的。默认情况下,存储库服务器本身不包含敏感信息,但可能配置了包含敏感信息的配置管理插件(例如解密密钥)。如果使用此类插件,必须格外小心,以确保存储库内容始终值得信赖。
内置配置管理工具可以单独禁用。如果知道用户不需要某个配置管理工具,建议禁用该工具。有关更多信息,请参阅工具检测。
远程基地和舵图依赖关系
Argo CD 的存储库允许列表仅限制克隆的初始存储库。但是,kustomize
和 helm
都包含引用和跟踪其他存储库(例如 kustomize
远程基础、helm chart
依赖项)的功能,这些存储库可能不在存储库允许列表中。Argo CD 操作员必须了解,对受信任的 git 存储库具有写访问权限的用户可以引用其他远程 git 存储库,这些存储库包含 Kubernetes 资源,在配置的 git 存储库中不易搜索或审核。
敏感信息
密钥
Argo CD 从不从其 API 返回敏感数据,并会删除 API 有效负载和日志中的所有敏感数据。这包括:
- 集群凭据
- Git 凭据
- OAuth2 客户端密钥
- Kubernetes 密钥值
外部集群凭证
为了管理外部集群,Argo CD 将外部集群的凭据作为 Kubernetes Secret 存储在 argocd 命名空间中。此 secret 包含与在 argocd cluster add
期间创建的 argocd-manager
ServiceAccount 关联的 K8s API 承载令牌,以及与该 API 服务器的连接选项(TLS 配置/证书、AWS role-arn 等)。该信息用于为 Argo CD 服务使用的集群重建 REST 配置和 kubeconfig。
# run using a kubeconfig for the externally managed cluster
kubectl delete secret argocd-manager-token-XXXXXX -n kube-system
argocd cluster add CONTEXTNAME
Kubernetes 1.24 停止自动为服务帐户创建令牌。从 Argo CD 2.4 开始,
argocd cluster add
在添加 1.24 集群时会创建一个服务帐户和一个永不过期的服务帐户令牌密钥。将来,Argo CD 将添加对 Kubernetes TokenRequest API 的支持,以避免使用长期令牌。
要撤销 Argo CD 对托管集群的访问权限,请删除针对托管集群的 RBAC 工件,并从 Argo CD 中删除集群条目:
# run using a kubeconfig for the externally managed cluster
kubectl delete sa argocd-manager -n kube-system
kubectl delete clusterrole argocd-manager-role
kubectl delete clusterrolebinding argocd-manager-role-binding
argocd cluster rm https://your-kubernetes-cluster-addr
注意:对于 AWS EKS 集群,
get-token
命令用于对外部集群进行身份验证,它使用 IAM 角色代替本地存储的令牌,因此不需要令牌轮换,并且通过 IAM 处理撤销。
集群 RBAC
默认情况下,Argo CD 使用 clusteradmin 级别角色来:
- 监视和操作集群状态
- 将资源部署到集群
尽管 Argo CD 需要对托管集群中的资源具有集群范围的读取权限才能正常运行,但它不一定需要对集群具有完全的写入权限。 argocd-server
和 argocd-application-controller
使用的 ClusterRole 可以进行修改,以便写入权限仅限于希望 Argo CD 管理的命名空间和资源。
要微调外部管理集群的权限,请编辑 argocd-manager-role
的 ClusterRole
# run using a kubeconfig for the externally managed cluster
kubectl edit clusterrole argocd-manager-role
为了微调 Argo CD 对其自身集群(即 https://kubernetes.default.svc
)的权限,请编辑 Argo CD 正在运行的以下集群角色:
# run using a kubeconfig to the cluster Argo CD is running in
kubectl edit clusterrole argocd-server
kubectl edit clusterrole argocd-application-controller
如果拒绝 Argo CD 访问某种资源,那么请将其添加为排除的资源。
审计
作为 GitOps 部署工具,Git 提交历史记录提供了自然的审计日志,记录了对应用程序配置进行了哪些更改、更改时间以及更改者。但是,此审计日志仅适用于 Git 中发生的事情,并不一定与集群中发生的事件一一对应。例如,用户 A 可能对应用程序清单进行了多次提交,但用户 B 可能只是在稍后将这些更改同步到集群。
为了补充 Git 修订历史记录,Argo CD 会发出应用程序活动的 Kubernetes 事件,并在适用时指明负责的参与者。例如:
$ kubectl get events
LAST SEEN FIRST SEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
1m 1m 1 guestbook.157f7c5edd33aeac Application Normal ResourceCreated argocd-server admin created application
1m 1m 1 guestbook.157f7c5f0f747acf Application Normal ResourceUpdated argocd-application-controller Updated sync status: -> OutOfSync
1m 1m 1 guestbook.157f7c5f0fbebbff Application Normal ResourceUpdated argocd-application-controller Updated health status: -> Missing
1m 1m 1 guestbook.157f7c6069e14f4d Application Normal OperationStarted argocd-server admin initiated sync to HEAD (8a1cb4a02d3538e54907c827352f66f20c3d7b0d)
1m 1m 1 guestbook.157f7c60a55a81a8 Application Normal OperationCompleted argocd-application-controller Sync operation to 8a1cb4a02d3538e54907c827352f66f20c3d7b0d succeeded
1m 1m 1 guestbook.157f7c60af1ccae2 Application Normal ResourceUpdated argocd-application-controller Updated sync status: OutOfSync -> Synced
1m 1m 1 guestbook.157f7c60af5bc4f0 Application Normal ResourceUpdated argocd-application-controller Updated health status: Missing -> Progressing
1m 1m 1 guestbook.157f7c651990e848 Application Normal ResourceUpdated argocd-application-controller Updated health status: Progressing -> Healthy
然后可以使用事件导出器或事件路由器等其他工具将这些事件保存更长时间。
WebHook 负载
来自 webhook 事件的有效负载被视为不受信任。Argo CD 仅检查有效负载以推断 webhook 事件所涉及的应用程序(例如,修改了哪个存储库),然后刷新相关应用程序以进行协调。此刷新与每隔三分钟定期发生的刷新相同,只是通过 webhook 事件进行了快速跟踪。
日志记录
安全属性
与安全相关的日志都标有安全字段,以便于查找、分析和报告。
界级别 | 友好程度 | 描述 | 示例 |
---|---|---|---|
1 | 低 | 正常、非恶意事件 | 成功访问 |
2 | 中 | 可能表示恶意事件,但很可能是用户/系统错误 | 拒绝访问 |
3 | 高 | 可能是恶意事件,但没有副作用或已被阻止 | 存储库中的符号链接超出范围 |
4 | 严重 | 任何有副作用的恶意或可利用事件 | 文件系统中遗留的密钥 |
5 | 急救 | 毫无疑问是恶意事件,绝不应该意外发生,并表示存在主动攻击 | 暴力破解账户 |
在适用的情况下,还会添加一个
CWE
字段,指定常见弱点枚举编号。
API 日志
Argo CD 记录大多数 API 请求的有效负载,但被视为敏感的请求除外,例如 /cluster.ClusterService/Create, /session.SessionService/Create
等。方法的完整列表可以在 server/server.go
中找到。
Argo CD 不会记录请求 API 端点的客户端的 IP 地址,因为 API 服务器通常位于代理后面。相反,建议配置在位于 API 服务器前面的代理服务器中记录 IP 地址。
应用程序集(ApplicationSets)
Argo CD 的 ApplicationSets 功能有其自身的安全注意事项。在使用 ApplicationSets 之前请注意这些问题。
限制目录应用程序内存使用量
2.2.10, 2.1.16, >2.3.5
目录类型应用程序(其源是原始 JSON
或 YAML
文件的应用程序)可能会消耗大量 repo 服务器内存,具体取决于 YAML
文件的大小和结构。
为了避免在 repo-server
中过度使用内存(可能导致崩溃和拒绝服务),请在 argocd-cmd-params-cm
中设置 reposerver.max.combined.directory.manifests.size
配置选项。
此选项限制单个应用中所有 JSON
或 YAML
文件的总大小。请注意,清单在内存中的表示形式可能高达磁盘上清单大小的 300
倍。另请注意,限制是针对每个应用的。如果一次为多个应用生成清单,内存使用量会更高。
例子:
假设你的 repo 服务器有 10G 的内存限制,并且有 10 个使用原始 JSON 或 YAML 文件的应用程序。要计算每个应用程序的最大安全组合文件大小,请将 10G 除以 300 * 10 个应用程序(300 是清单的最坏情况内存增长因子)。
10G / 300 * 10 = 3M
因此,此设置的合理安全配置是每个应用程序 3M 的限制。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
data:
reposerver.max.combined.directory.manifests.size: '3M'
300x 比率假设清单文件是恶意制作的。如果只想防止意外过度使用内存,使用较小的比率可能是安全的。
请记住,如果恶意用户可以创建其他应用程序,则可以增加总内存使用量。请谨慎授予应用程序创建权限。
Snyk 扫描
每个星期日,Snyk 都会针对 Argo CD 的主分支和最近三个次要版本的最新补丁生成扫描。
如需查看最新扫描,请查看文档的最新版本。您可以使用页面顶部的下拉选择器返回到您喜欢的文档站点版本。
版本扫描
- 具体参考
验证 Argo CD 清单
先决条件
- cosign
v2.0.0
或更高版本安装说明 - slsa-verifier 安装说明
- crane 安装说明(仅用于容器验证)
发布资源
| Asset | Description |
| argocd-darwin-amd64 | CLI Binary |
| argocd-darwin-arm64 | CLI Binary |
| argocd-linux_amd64 | CLI Binary |
| argocd-linux_arm64 | CLI Binary |
| argocd-linux_ppc64le | CLI Binary |
| argocd-linux_s390x | CLI Binary |
| argocd-windows_amd64 | CLI Binary |
| argocd-cli.intoto.jsonl | Attestation of CLI binaries |
| argocd-sbom.intoto.jsonl | Attestation of SBOM |
| cli_checksums.txt | Checksums of binaries |
| sbom.tar.gz | Sbom |
| sbom.tar.gz.pem | Certificate used to sign sbom |
| sbom.tar.gz.sig | Signature of sbom |
容器镜像验证
Argo CD 容器镜像使用基于身份(“无密钥”)的签名和透明度通过 cosign
进行签名。执行以下命令可用于验证容器镜像的签名:
cosign verify \
--certificate-identity-regexp https://github.com/argoproj/argo-cd/.github/workflows/image-reuse.yaml@refs/tags/v \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
quay.io/argoproj/argocd:v2.7.0 | jq
如果容器镜像被正确验证,该命令应该输出以下内容:
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- Any certificates were verified against the Fulcio roots.
[
{
"critical": {
"identity": {
"docker-reference": "quay.io/argoproj/argo-cd"
},
"image": {
"docker-manifest-digest": "sha256:63dc60481b1b2abf271e1f2b866be8a92962b0e53aaa728902caa8ac8d235277"
},
"type": "cosign container image signature"
},
"optional": {
"1.3.6.1.4.1.57264.1.1": "https://token.actions.githubusercontent.com",
"1.3.6.1.4.1.57264.1.2": "push",
"1.3.6.1.4.1.57264.1.3": "a6ec84da0eaa519cbd91a8f016cf4050c03323b2",
"1.3.6.1.4.1.57264.1.4": "Publish ArgoCD Release",
"1.3.6.1.4.1.57264.1.5": "argoproj/argo-cd",
"1.3.6.1.4.1.57264.1.6": "refs/tags/<version>",
...
使用 SLSA 证明验证容器映像
使用 slsa-github-generator
生成 SLSA 3 级出处。
以下命令将验证证明的签名及其颁发方式。它将包含 payloadType、payload 和签名。
根据slsa-verifier
文档运行以下命令:
# Get the immutable container image to prevent TOCTOU attacks https://github.com/slsa-framework/slsa-verifier#toctou-attacks
IMAGE=quay.io/argoproj/argocd:v2.7.0
IMAGE="${IMAGE}@"$(crane digest "${IMAGE}")
# Verify provenance, including the tag to prevent rollback attacks.
slsa-verifier verify-image "$IMAGE" \
--source-uri github.com/argoproj/argo-cd \
--source-tag v2.7.0
如果只想验证源存储库标签的主要版本或次要版本(而不是完整标签),请使用执行语义版本验证的 --source-versioned-tag
:
slsa-verifier verify-image "$IMAGE" \
--source-uri github.com/argoproj/argo-cd \
--source-versioned-tag v2 # Note: May use v2.7 for minor version verification.
证明有效负载包含不可伪造的出处,它是 base64 编码的,可以通过将 --print-provenance
选项传递给上面的命令来查看:
slsa-verifier verify-image "$IMAGE" \
--source-uri github.com/argoproj/argo-cd \
--source-tag v2.7.0 \
--print-provenance | jq
如果你更喜欢使用共同签名,请按照以下说明操作。
cosign
或slsa-verifier
均可用于验证镜像证明。请查看每个二进制文件的文档以获取详细说明。
使用 SLSA 证明验证 CLI 工件
每个版本都提供了单个证明 (argocd-cli.intoto.jsonl
)。这可以与 slsa-verifier
一起使用,以验证 CLI 二进制文件是否是使用 GitHub 上的 Argo CD 工作流生成的,并确保它已进行加密签名。
slsa-verifier verify-artifact argocd-linux-amd64 \
--provenance-path argocd-cli.intoto.jsonl \
--source-uri github.com/argoproj/argo-cd \
--source-tag v2.7.0
如果只想验证源存储库标签的主要版本或次要版本(而不是完整标签),请使用执行语义版本验证的 --source-versioned-tag
:
slsa-verifier verify-artifact argocd-linux-amd64 \
--provenance-path argocd-cli.intoto.jsonl \
--source-uri github.com/argoproj/argo-cd \
--source-versioned-tag v2 # Note: May use v2.7 for minor version verification.
有效载荷是不可伪造的来源,它是 base64
编码的,可以通过将 --print-provenance
选项传递给上面的命令来查看:
slsa-verifier verify-artifact argocd-linux-amd64 \
--provenance-path argocd-cli.intoto.jsonl \
--source-uri github.com/argoproj/argo-cd \
--source-tag v2.7.0 \
--print-provenance | jq
Sbom 验证
每个版本都提供一份单独的证明 (argocd-sbom.intoto.jsonl
) 以及 sbom (sbom.tar.gz)
。这可以与 slsa-verifier
一起使用,以验证 SBOM 是否是使用 GitHub 上的 Argo CD 工作流生成的,并确保它已加密签名。
slsa-verifier verify-artifact sbom.tar.gz \
--provenance-path argocd-sbom.intoto.jsonl \
--source-uri github.com/argoproj/argo-cd \
--source-tag v2.7.0
在 Kubernetes 上验证
策略控制器
我们鼓励所有用户使用选择的准入/策略控制器来验证签名和出处。这样做将验证我们在将映像部署到 Kubernetes 集群之前是否构建了该映像。
Cosign 签名和 SLSA 出处与多种类型的准入控制器兼容。请参阅 cosign 文档和 slsa-github-generator 了解受支持的控制器。
7.11.TLS 配置
Argo CD 提供了三个可配置的入站 TLS 端点:
argocd-server
工作负载面向用户的端点,为 UI 和 API 提供服务argocd-repo-server
的端点,由argocd-server
和argocd-application-controller
工作负载访问以请求存储库操作。argocd-dex-server
的端点,由argocd-server
访问以处理 OIDC 身份验证。
默认情况下,无需进一步配置,这些端点将被设置为使用自动生成的自签名证书。但是,大多数用户都希望明确配置这些 TLS 端点的证书,可能使用自动化方式(例如 cert-manager
)或使用他们自己的专用证书颁发机构。
为 argocd-server 配置 TLS
argocd-server
的入站 TLS 选项
可以通过设置命令行参数来为 argocd-server 工作负载配置某些 TLS 选项。可用的参数如下:
参数 | 默认 | 描述 |
---|---|---|
–insecure | false | 完全禁用 TLS |
–tlsminversion | 1.2 | 向客户端提供的最低 TLS 版本 |
–tlsmaxversion | 1.3 | 向客户端提供的最高 TLS 版本 |
–tlsciphers | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384 | 以冒号分隔的要提供给客户端的 TLS 密码套件列表 |
argocd-server
使用的 TLS 证书
有两种方法可以配置 argocd-server
使用的 TLS 证书:
- 设置
argocd-server-tls
密钥中的tls.crt
和tls.key
密钥以保存证书的 PEM 数据和相应的私钥。argocd-server-tls
密钥可以是tls
类型,但不一定非得是。 - 设置
argocd-secret
密钥中的tls.crt
和tls.key
密钥以保存证书的 PEM 数据和相应的私钥。此方法被视为已弃用,仅用于向后兼容。更改argocd-secret
不应再用于覆盖 TLS 证书。
Argo CD 决定为 argocd-server 的端点使用哪个 TLS 证书,如下所示:
- 如果
argocd-server-tls
密钥存在并且在tls.crt
和tls.key
密钥中包含有效的密钥对,则这将用于argocd-server
端点的证书。 - 否则,如果
argocd-secret
密钥在tls.crt
和tls.key
密钥中包含有效密钥对,则这将用作argocd-server
端点的证书。 - 如果在上述两个密钥中均未找到
tls.crt
和tls.key
密钥,Argo CD 将生成一个自签名证书并将其保存在argocd-secret
密钥中。
argocd-server-tls
密钥仅包含 argocd-server
使用的 TLS 配置信息,可通过 cert-manager
或 SealedSecrets 等第三方工具安全管理
要从现有密钥对手动创建此密钥,可以使用 kubectl
:
kubectl create -n argocd secret tls argocd-server-tls \
--cert=/path/to/cert.pem \
--key=/path/to/key.pem
Argo CD 将自动获取对 argocd-server-tls
机密的更改,并且不需要重新启动 pod
来使用更新的证书。
为 argocd-repo-server 配置入站 TLS
argocd-repo-server 的入站 TLS 选项
可以通过设置命令行参数来为 argocd-repo-server
工作负载配置某些 TLS 选项。可用的参数如下:
参数 | 默认 | 描述 |
---|---|---|
–insecure | false | 完全禁用 TLS |
–tlsminversion | 1.2 | 向客户端提供的最低 TLS 版本 |
–tlsmaxversion | 1.3 | 向客户端提供的最高 TLS 版本 |
–tlsciphers | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384 | 以冒号分隔的要提供给客户端的 TLS 密码套件列表 |
argocd-repo-server 使用的入站 TLS 证书
要配置 argocd-repo-server
工作负载使用的 TLS 证书,请在 Argo CD 运行的命名空间中创建一个名为 argocd-repo-server-tls
的密钥,并将证书的密钥对存储在 tls.crt
和 tls.key
密钥中。如果此密钥不存在,argocd-repo-server
将生成并使用自签名证书。
要创建此密钥,您可以使用 kubectl
:
kubectl create -n argocd secret tls argocd-repo-server-tls \
--cert=/path/to/cert.pem \
--key=/path/to/key.pem
如果证书是自签名的,还需要将 ca.crt
与 CA 证书的内容一起添加到密钥中。
请注意,与 argocd-server
不同,argocd-repo-server
无法自动获取此机密的更改。如果创建(或更新)此密钥,则需要重新启动 argocd-repo-server pod
。
另请注意,证书应使用 argocd-repo-server
的正确 SAN 条目颁发,至少包含 DNS:argocd-repo-server
和 DNS:argocd-repo-server.argo-cd.svc
的条目,具体取决于工作负载如何连接到存储库服务器。
为 argocd-dex-server 配置入站 TLS
argocd-dex-server 的入站 TLS 选项
可以通过设置命令行参数来为 argocd-dex-server
工作负载配置某些 TLS 选项。可用的参数如下:
参数 | 默认 | 描述 |
---|---|---|
–disable-tls | false | 完全禁用 TLS |
argocd-repo-server 使用的入站 TLS 证书
要配置 argocd-repo-server
工作负载使用的 TLS 证书,请在 Argo CD 运行的命名空间中创建一个名为 argocd-repo-server-tls
的密钥,并将证书的密钥对存储在 tls.crt
和 tls.key
密钥中。如果此密钥不存在,argocd-repo-server
将生成并使用自签名证书。
要创建此密钥,可以使用 kubectl
:
kubectl create -n argocd secret tls argocd-repo-server-tls \
--cert=/path/to/cert.pem \
--key=/path/to/key.pem
如果证书是自签名的,还需要将 ca.crt
与 CA 证书的内容一起添加到密钥中。
请注意,与 argocd-server
不同,argocd-repo-server
无法自动获取此密钥的更改。如果创建(或更新)此密钥,则需要重新启动 argocd-repo-server pod
。
另请注意,证书应使用 argocd-repo-server
的正确 SAN 条目颁发,至少包含 DNS:argocd-repo-server
和 DNS:argocd-repo-server.argo-cd.svc
的条目,具体取决于工作负载如何连接到存储库服务器。
为 argocd-dex-server 配置入站 TLS
argocd-dex-server 的入站 TLS 选项
可以通过设置命令行参数来为 argocd-dex-server
工作负载配置某些 TLS 选项。可用的参数如下:
参数 | 默认 | 描述 |
---|---|---|
–disable-tls | false | 完全禁用 TLS |
argocd-dex-server 使用的入站 TLS 证书
要配置 argocd-dex-server
工作负载使用的 TLS 证书,请在 Argo CD 运行的命名空间中创建一个名为 argocd-dex-server-tls
的密钥,并将证书的密钥对存储在 tls.crt
和 tls.key
密钥中。如果此密钥不存在,argocd-dex-server
将生成并使用自签名证书。
要创建此密钥,可以使用 kubectl
:
kubectl create -n argocd secret tls argocd-dex-server-tls \
--cert=/path/to/cert.pem \
--key=/path/to/key.pem
如果证书是自签名的,还需要将 ca.crt
与 CA 证书的内容一起添加到密钥中。
请注意,与 argocd-server
不同,argocd-dex-server
无法自动获取此密钥的更改。如果创建(或更新)此密钥,则需要重新启动 argocd-dex-server pod
。
另请注意,证书应使用 argocd-dex-server
的正确 SAN 条目颁发,至少包含 DNS:argocd-dex-server
和 DNS:argocd-dex-server.argo-cd.svc
的条目,具体取决于工作负载如何连接到存储库服务器。
在 Argo CD 组件之间配置 TLS
配置 TLS 到 argocd-repo-server
argocd-server
和 argocd-application-controller
都使用 TLS 上的 gRPC API 与 argocd-repo-server
通信。默认情况下,argocd-repo-server
会在启动时生成一个非持久的自签名证书,用于其 gRPC 端点。由于 argocd-repo-server
无法连接到 K8s 控制平面 API,因此外部消费者无法使用此证书进行验证。出于这个原因,argocd-server
和 argocd-application-server
都将使用非验证连接来连接到 argocd-repo-server
。
要通过让 argocd-server
和 argocd-application-controller
验证 argocd-repo-server
端点的 TLS 证书来改变此行为以使其更加安全,需要执行以下步骤:
- 创建持久的 TLS 证书供
argocd-repo-server
使用,如上所示 - 重新启动
argocd-repo-server pod
- 修改
argocd-server
和argocd-application-controller
的pod
启动参数,包含--repo-server-strict-tls
参数
argocd-server
和 argocd-application-controller
工作负载现在将使用存储在 argocd-repo-server-tls
密钥中的证书来验证 argocd-repo-server
的 TLS 证书。
请确保证书的有效期合适。请记住,当您必须替换证书时,必须重新启动所有工作负载才能再次正常工作。
配置 TLS 到 argocd-dex-server
argocd-server
使用 HTTPS API 通过 TLS 与 argocd-dex-server
通信。默认情况下,argocd-dex-server
会在启动时生成一个非持久性自签名证书,用于其 HTTPS 端点。由于 argocd-dex-server
无法连接到 K8s 控制平面 API,因此外部消费者无法使用此证书进行验证。出于这个原因,argocd-server
将使用非验证连接与 argocd-dex-server
建立连接。
要通过让 argocd-server
验证 argocd-dex-server
端点的 TLS 证书来改变此行为以使其更加安全,需要执行以下步骤:
- 创建持久的 TLS 证书以供
argocd-dex-server
使用,如上所示 - 重新启动
argocd-dex-server pod
- 修改
argocd-server
的pod
启动参数以包含--dex-server-strict-tls
参数。
rgocd-server
工作负载现在将使用存储在 argocd-dex-server-tls
密钥中的证书来验证 argocd-dex-server
的 TLS 证书。
请确保证书的有效期合适。请记住,当您必须替换证书时,必须重新启动所有工作负载才能再次正常工作。
禁用 argocd-repo-server 的 TLS
在某些涉及通过侧车代理进行 mTLS 的场景中(例如在服务网格中),可能希望将 argocd-server
和 argocd-application-controller
之间的连接配置为 argocd-repo-server
完全不使用 TLS。
在这种情况下,需要:
- 通过在 pod 容器的启动参数中指定
--disable-tls
参数,配置argocd-repo-server
并在 gRPC API 上禁用 TLS。此外,考虑通过指定--listen 127.0.0.1
参数将监听地址限制为环回接口,这样不安全的端点就不会暴露在pod
的网络接口上,但仍可供side-car
容器使用。 - 通过在
pod
容器的启动参数中指定参数--repo-server-plaintext
,配置argocd-server
和argocd-application-controller
以不使用 TLS 连接到argocd-repo-server
- 通过
--repo-server <address>
参数指定其地址,配置argocd-server
和argocd-application-controller
以连接到side-car
,而不是直接连接到argocd-repo-server
服务
进行此更改后,argocd-server
和 argocd-application-controller
将使用纯文本连接到 side-car
代理,该代理将处理 argocd-repo-server
的 TLS side-car
代理的 TLS 的所有方面。
禁用 argocd-dex-server 的 TLS
在某些涉及通过侧车代理进行 mTLS 的场景中(例如在服务网格中),可能希望将 argocd-server
和 argocd-dex-server
之间的连接配置为完全不使用 TLS。
在这种情况下,需要:
- 通过在
pod
容器的启动参数中指定--disable-tls
参数,配置argocd-dex-server
并在 HTTPS API 上禁用 TLS - 通过在
pod
容器的启动参数中指定参数--dex-server-plaintext
,配置argocd-server
以不使用 TLS 连接argocd-dex-server
- 通过在
--dex-server <address>
参数指定其地址,配置argocd-server
以连接到side-car
,而不是直接连接到argocd-dex-server
服务
进行此项更改后,argocd-server
将使用纯文本连接到侧车代理,该代理将处理 argocd-dex-server
的 TLS 侧车代理的 TLS 所有方面。
7.12.集群引导
本指南适用于已经安装 Argo CD、拥有新集群并希望在该集群中安装许多应用程序的操作员。
没有一种特定的模式可以解决这个问题,例如,可以编写脚本来创建应用程序,甚至可以手动创建它们。但是,Argo CD 的用户倾向于使用应用程序模式。
在任意项目中创建应用程序的能力是管理员级别的能力。只有管理员才应该拥有对父应用程序源存储库的推送访问权限。管理员应该审查对该存储库的拉取请求,特别注意每个应用程序中的项目字段。有权访问安装 Argo CD 的命名空间的项目实际上具有管理员级别的权限。
应用程序的应用程序模式
声明性地指定一个仅由其他应用程序组成的 Argo CD 应用程序。
Helm 示例
此示例展示了如何使用 Helm 来实现这一点。当然,如果你愿意,也可以使用其他工具。
Git 存储库的典型布局可能是:
├── Chart.yaml
├── templates
│ ├── guestbook.yaml
│ ├── helm-dependency.yaml
│ ├── helm-guestbook.yaml
│ └── kustomize-guestbook.yaml
└── values.yaml
Chart.yaml
是样板。
templates
为每个子应用程序包含一个文件,大致如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: argocd
server: {{ .Values.spec.destination.server }}
project: default
source:
path: guestbook
repoURL: https://github.com/argoproj/argocd-example-apps
targetRevision: HEAD
将同步策略设置为自动 + 修剪,这样当清单发生更改时,子应用会自动创建、同步和删除,但可能希望禁用此功能。我还添加了终结器,这将确保您的应用被正确删除。
将修订版本修复为特定的 Git 提交 SHA,以确保即使子应用程序存储库发生变化,应用程序也只会在父应用程序更改该修订版本时更改。或者,可以将其设置为 HEAD 或分支名称。
由于可能想要覆盖集群服务器,这是一个模板值。
values.yaml
包含默认值:
spec:
destination:
server: https://kubernetes.default.svc
接下来,需要创建并同步您的父应用程序,例如通过 CLI:
argocd app create apps \
--dest-namespace argocd \
--dest-server https://kubernetes.default.svc \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path apps
argocd app sync apps
父应用程序将显示为同步,但子应用程序将不同步:
注意:可能需要修改此行为以分批引导集群;有关更改此行为的信息,请参阅 v1.8 升级说明。
可以通过 UI 进行同步,首先通过正确的标签进行过滤:
然后选择“out of sync”的应用程序并sync:
或者通过 CLI:
argocd app sync -l app.kubernetes.io/instance=apps
在 GitHub 上查看示例。
级联删除
如果你想确保在删除父应用时删除子应用及其所有资源,请确保在应用程序定义中添加适当的终结器
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
...
7.13.密钥管理
Argo CD 对于如何管理密钥没有任何意见。有很多方法可以做到这一点,并且没有一刀切的解决方案。
许多解决方案使用插件将密钥注入应用程序清单。请参阅下面的“降低机密注入插件的风险”,以确保您安全地使用这些插件。
以下是人们实施 GitOps 密钥的一些方法:
- Bitnami Sealed Secrets
- External Secrets Operator
- Hashicorp Vault
- Bank-Vaults
- Helm Secrets
- Kustomize secret generator plugins
- aws-secret-operator
- KSOPS
- argocd-vault-plugin
- argocd-vault-replacer
- Kubernetes Secrets Store CSI Driver
- Vals-Operator
有关讨论,请参阅#1364
降低密钥注入插件的风险
Argo CD 将插件生成的清单以及注入的密钥缓存在其 Redis 实例中。这些清单也可通过 repo-server API(gRPC 服务)获取。这意味着任何有权访问 Redis 实例或 repo-server 的人都可以获取密钥。
考虑以下步骤来减轻密钥注入插件的风险:
- 设置网络策略以防止直接访问 Argo CD 组件(Redis 和 repo-server)。确保集群支持这些网络策略并可以实际执行它们。
- 考虑在其自己的集群上运行 Argo CD,并且不运行其他应用程序。
- 在 Redis 实例上启用密钥验证(当前仅支持非 HA Argo CD 安装)。
7.14.容灾
可以使用 argocd admin
导入和导出所有 Argo CD 数据。
确保 ~/.kube/config
指向 Argo CD 集群。
确定正在运行的 Argo CD 版本:
argocd version | grep server
# ...
export VERSION=v1.0.1
导出至备份:
docker run -v ~/.kube:/home/argocd/.kube --rm quay.io/argoproj/argocd:$VERSION argocd admin export > backup.yaml
从备份导入:
docker run -i -v ~/.kube:/home/argocd/.kube --rm quay.io/argoproj/argocd:$VERSION argocd admin import - < backup.yaml
如果在不同于默认的命名空间上运行 Argo CD,请记住传递命名空间参数 (-n)。如果在错误的命名空间中运行“
argocd admin export
”,它不会失败。
7.15.协调优化
默认情况下,每次属于 Argo CD 应用程序的资源发生变化时,它都会刷新。
Kubernetes 控制器经常会定期更新它们监视的资源,从而导致应用程序持续进行协调操作,并导致 argocd-application-controller 的 CPU 使用率过高。Argo CD 允许选择性地忽略跟踪资源的特定字段上的资源更新。
当忽略资源更新时,如果资源的健康状态没有改变,则此资源所属的应用程序将不会被协调。
系统级配置
Argo CD 允许使用 RFC6902 JSON 补丁和 JQ 路径表达式忽略特定 JSON 路径的资源更新。可以在 argocd-cm
ConfigMap 的 resource.customizations
键中为指定组和类型配置它。
该功能位于标志后面。要启用它,请在 argocd-cm
ConfigMap 中将 resource.ignoreResourceUpdatesEnabled
设置为true
。
以下是忽略 ExternalSecret 资源的 refreshTime 状态字段的自定义示例:
data:
resource.customizations.ignoreResourceUpdates.external-secrets.io_ExternalSecret: |
jsonPointers:
- /status/refreshTime
# JQ equivalent of the above:
# jqPathExpressions:
# - .status.refreshTime
可以配置 ignoreResourceUpdates
以应用于 Argo CD 实例管理的每个应用程序中的所有跟踪资源。为此,可以像以下示例一样配置资源自定义:
data:
resource.customizations.ignoreResourceUpdates.all: |
jsonPointers:
- /status
使用 ignoreDifferences
忽略协调
也可以使用现有的系统级 ignoreDifferences
自定义来忽略资源更新。无需复制所有配置,可以使用 ignoreDifferencesOnResourceUpdates
设置将所有忽略的差异添加为忽略的资源更新:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
resource.compareoptions: |
ignoreDifferencesOnResourceUpdates: true
默认配置
默认情况下,所有资源的元数据字段generation、resourceVersion和managedFields
都会被忽略。
寻找可以忽略的资源
当资源更改触发刷新时,应用程序控制器会记录日志。可以使用这些日志来查找高流失率的资源类型,然后检查这些资源以找出要忽略的字段。
要查找这些日志,请搜索“Requesting app refresh caused by object update”。日志包括 api-version 和 kind 的结构化字段。按 api-version
和kind
计算触发的刷新次数应该可以发现高流失率的资源类型。
这些日志属于debug级别。请将应用程序控制器的日志级别配置为debug。
一旦确定了一些经常更改的资源,就可以尝试确定哪些字段正在更改。以下是一种方法:
kubectl get <resource> -o yaml > /tmp/before.yaml
# Wait a minute or two.
kubectl get <resource> -o yaml > /tmp/after.yaml
diff /tmp/before.yaml /tmp/after
差异可以让你了解哪些字段正在发生变化并且可能应该被忽略。
检查资源更新是否被忽略
每当 Argo CD 由于忽略资源更新而跳过刷新时,控制器都会记录以下行:“Ignoring change of object because none of the watched resource fields have changed”。
在应用程序控制器日志中搜索此行以确认您的资源忽略规则正在被应用。
这些日志属于debug级别。请将应用程序控制器的日志级别配置为debug。
例子
argoproj.io/Application
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
resource.customizations.ignoreResourceUpdates.argoproj.io_Application: |
jsonPointers:
# Ignore when ownerReferences change, for example when a parent ApplicationSet changes often.
- /metadata/ownerReferences
# Ignore reconciledAt, since by itself it doesn't indicate any important change.
- /status/reconciledAt
jqPathExpressions:
# Ignore lastTransitionTime for conditions; helpful when SharedResourceWarnings are being regularly updated but not
# actually changing in content.
- .status.conditions[].lastTransitionTime
7.16.Git Webhook 配置
概述
Argo CD 每三分钟轮询一次 Git 存储库,以检测清单的更改。为了消除轮询延迟,可以配置 API 服务器以接收 webhook 事件。Argo CD 支持来自 GitHub、GitLab、Bitbucket、Bitbucket Server、Azure DevOps 和 Gogs 的 Git webhook 通知。以下内容介绍了如何为 GitHub 配置 Git webhook,但相同的过程也适用于其他提供商。
Webhook 处理程序不会区分分支事件和分支名称和标签名称相同的标签事件。推送到分支 x
的钩子事件将触发指向同一存储库且targetRevision: refs/tags/x
的应用的刷新。
1.在 Git 提供程序中创建 WebHook
在 Git 提供程序中,导航到可以配置 webhook 的设置页面。在 Git 提供程序中配置的有效负载 URL 应使用 Argo CD 实例的 /api/webhook
端点(例如 https://argocd.example.com/api/webhook
)。如果希望使用共享密钥,请在密钥中输入任意值。此值将在下一步配置 webhook 时使用。
Github
在 GitHub 中创建 webhook 时,“内容类型”需要设置为“application/json
”。用于处理钩子的库不支持默认值“application/x-www-form-urlencoded
”
2.使用 WebHook Secret 配置 Argo CD(可选)
配置 webhook 共享密钥是可选的,因为即使有未经身份验证的 webhook 事件,Argo CD 仍会刷新与 Git 存储库相关的应用程序。这样做是安全的,因为 webhook 有效负载的内容被视为不受信任,并且只会导致应用程序刷新(该过程已经以三分钟为间隔发生)。如果 Argo CD 可公开访问,则建议配置 webhook 密钥以防止 DDoS 攻击。
在 argocd-secret Kubernetes 密钥中,使用步骤 1 中配置的 Git 提供程序的 webhook 密钥配置以下密钥之一。
Provider K8s | Secret Key |
---|---|
GitHub | webhook.github.secret |
GitLab | webhook.gitlab.secret |
BitBucket | webhook.bitbucket.uuid |
BitBucketServer | webhook.bitbucketserver.secret |
Gogs | webhook.gogs.secret |
Azure DevOps | webhook.azuredevops.username |
webhook.azuredevops.password |
编辑 Argo CD Kubernetes 密钥:
kubectl edit secret argocd-secret -n argocd
提示:为了方便输入密钥,Kubernetes 支持在 stringData
字段中输入密钥,这样就省去了对值进行 base64 编码并将其复制到 data
字段的麻烦。只需将步骤 1 中创建的共享 webhook 密钥复制到 stringData
字段下相应的 GitHub/GitLab/BitBucket 密钥即可:
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
data:
...
stringData:
# github webhook secret
webhook.github.secret: shhhh! it's a GitHub secret
# gitlab webhook secret
webhook.gitlab.secret: shhhh! it's a GitLab secret
# bitbucket webhook secret
webhook.bitbucket.uuid: your-bitbucket-uuid
# bitbucket server webhook secret
webhook.bitbucketserver.secret: shhhh! it's a Bitbucket server secret
# gogs server webhook secret
webhook.gogs.secret: shhhh! it's a gogs server secret
# azuredevops username and password
webhook.azuredevops.username: admin
webhook.azuredevops.password: secret-password
保存后,更改将自动生效。
替代方案
如果想将 webhook 数据存储在另一个 Kubernetes Secret 中,而不是 argocd-secret 中。ArgoCD 知道检查 Kubernetes Secret 中数据下的密钥,这些密钥以 $ 开头,然后是 Kubernetes Secret 名称和 :(冒号)。
Syntax: $<k8s_secret_name>:<a_key_in_that_k8s_secret>
注意:Secret 必须有标签
app.kubernetes.io/part-of: argocd
7.17.资源运行状况
概述
Argo CD 为几种标准 Kubernetes 类型提供内置健康评估,然后将其反映到整个应用程序的健康状况中。针对特定类型的 Kubernetes 资源进行以下检查:
Deployment, ReplicaSet, StatefulSet, DaemonSet
- 观察到的一代等于期望的一代。
- 更新的副本数量等于所需副本数量。
Service
如果服务类型为 LoadBalancer
类型,则 status.loadBalancer.ingress
列表非空,并且至少有一个hostname
或 IP
值。
Ingress
status.loadBalancer.ingress
列表非空,至少有一个hostname
或 IP
值。
Job
如果作业 .spec.suspended
设置为true
,则该作业和应用程序运行状况将被标记为暂停(suspended)。
PersistentVolumeClaim
status.phase
是Bound
Argocd App
argoproj.io/Application
CRD 的健康评估已在 argocd 1.8 中删除(有关更多信息,请参阅 #3781)。如果使用 app-of-apps
模式并使用同步波编排同步,则可能需要恢复它。在 argocd-cm
ConfigMap 中添加以下资源自定义:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
resource.customizations: |
argoproj.io/Application:
health.lua: |
hs = {}
hs.status = "Progressing"
hs.message = ""
if obj.status ~= nil then
if obj.status.health ~= nil then
hs.status = obj.status.health.status
if obj.status.health.message ~= nil then
hs.message = obj.status.health.message
end
end
end
return hs
定制健康检查
Argo CD支持LUA编写的自定义健康检查。
由于资源控制器中的错误而受到入口或状态全部资源的影响,因此受到已知问题的影响。
拥有一个自定义资源,ARGO CD没有内置的健康检查。
有两种配置自定义健康检查的方法。接下来的两个部分描述了这些方法。
方式1.在ArgoCD-CM Configmap中定义自定义健康检查
可以定义自定义健康检查
resource.customizations: |
<group/kind>:
health.lua: |
ArgoCD-CM领域。如果您使用的是ArgoCD-operator,则Argocd-operator ResourceCustomizations覆盖了这一点。
以下示例演示了CERT-MANAGER.IO/certificate
的健康检查。
data:
resource.customizations: |
cert-manager.io/Certificate:
health.lua: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" and condition.status == "False" then
hs.status = "Degraded"
hs.message = condition.message
return hs
end
if condition.type == "Ready" and condition.status == "True" then
hs.status = "Healthy"
hs.message = condition.message
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for certificate"
return hs
为了防止重复自定义健康检查是否有潜在的多个资源,也可以在资源类型和资源组中的任何地方指定通配符,例如:
resource.customizations: |
ec2.aws.crossplane.io/*:
health.lua: |
...
resource.customizations: |
"*.aws.crossplane.io/*":
health.lua: |
...
如果通配符以
*
开头,请注意“资源自定义健康”部分中所需的引号。
obj
是包含资源的全局变量。脚本必须返回具有状态和可选消息字段的对象。自定义健康检查可能会返回以下健康状况之一:
Healthy
资源很健康Progressing
资源还不健康,但仍在取得进步,可能很快就会健康Degraded
资源退化Suspended
该资源被暂停,等待一些外部事件恢复(例如,暂停的Cronjob或暂停的部署)
默认情况下,健康通常返回Progressing
状态。
注意:作为一种安全措施,默认情况下将禁用对标准LUA库的访问。管理员可以通过设置资源来控制访问。customizations.useopenlibs。<group_kind>
。在下面的示例中,启用了标准库,以进行cert-manager.io/certificate
的健康检查。
data:
resource.customizations: |
cert-manager.io/Certificate:
health.lua.useOpenLibs: true
health.lua: |
# Lua standard libraries are enabled for this script
方式2.贡献自定义健康检查
可以将健康检查捆绑到Argo CD
中。自定义健康检查脚本位于https://github.com/argoproj/argo-cd
的resource_customizations
目录中。这必须具有以下目录结构:
argo-cd
|-- resource_customizations
| |-- your.crd.group.io # CRD group
| | |-- MyKind # Resource kind
| | | |-- health.lua # Health check
| | | |-- health_test.yaml # Test inputs and expected results
| | | +-- testdata # Directory with test resource YAML definitions
每个健康检查必须在health_test.yaml文件中定义测试。 health_test.yaml
是一个具有以下结构的YAML文件:
tests:
- healthStatus:
status: ExpectedStatus
message: Expected message
inputPath: testdata/test-resource-definition.yaml
要测试实施的自定义健康检查,请运行go test -v ./util/lua/
PR#1139是Cert Manager CRDS自定义健康检查的示例。
请注意,不支持使用通配符捆绑的健康检查。
健康检查
Argo CD应用程序的健康是根据其直接孩子资源的健康(来源控制中代表的资源)推断出来的。
但是,资源的健康不是从孩子资源中继承的 - 它仅使用有关资源本身的信息来计算。资源状态字段可能或可能不包含有关孩子资源健康的信息,资源的健康检查可能会或可能不会考虑到这些信息。
缺乏继承是设计。无法从子女那里推断出资源的健康,因为儿童资源的健康可能与父母资源的健康无关。例如,部署的健康不一定会受到其Pod健康状况的影响。
App (healthy)
└── Deployment (healthy)
└── ReplicaSet (healthy)
└── Pod (healthy)
└── ReplicaSet (unhealthy)
└── Pod (unhealthy)
如果希望孩子资源的健康影响其父母的健康,则需要配置父母的健康检查以考虑孩子的健康。由于只有父级资源的状态可用于健康检查,因此父级资源的控制器需要使子资源的健康在父级资源的状态字段中可用。
App (healthy)
└── CustomResource (healthy) <- This resource's health check needs to be fixed to mark the App as unhealthy
└── CustomChildResource (unhealthy)
7.18.资源动作
概述
Argo CD允许操作员定义用户可以在特定资源类型上执行的自定义操作。这用于内部用来提供诸如Daemonset restart或retry Argo推出之类的动作。
操作员可以以LUA脚本的形式将操作添加到自定义资源中,并扩展这些功能。
自定义资源操作
Argo CD支持LUA编写的自定义资源操作。
- 拥有一个自定义资源,Argo CD不提供任何内置操作。
- 具有通常执行的手动任务,如果用户通过kubectl执行可能会易于错误
资源动作对单个对象作用。
可以在argocd-cm ConfigMap中定义自己的自定义资源操作。
自定义资源操作类型
修改源资源的动作
此操作修改并返回源资源。这种动作是直到2.8的唯一一个可用的动作,并且仍然得到支持。
产生新资源或修改资源列表的动作
2.8中引入的alpha功能。
此操作返回了受影响资源的列表,每个受影响的资源都有K8S资源和可执行的操作。
当前支持的操作是“create”和“patch”,“patch”仅支持源资源。
通过为返回列表中的每个此类资源指定“create”操作,可以创建新资源。
通过为返回列表中的每个此类资源指定“create”操作,可以创建新资源。
返回的资源之一可以是修改后的源对象,如果需要,可以使用“patch”操作。
请参阅下面的定义示例。
在ArgoCD-CM Configmap中定义自定义资源操作
可以在资源中定义自定义资源操作。resource.customizations.actions.<group_kind>的字段。以下示例演示了Cronjob资源的一组自定义操作,每个此类操作都返回修改后的Cronjob。自定义密钥以resource.customizations.actions.<apiGroup_Kind>的格式。
resource.customizations.actions.batch_CronJob: |
discovery.lua: |
actions = {}
actions["suspend"] = {["disabled"] = true}
actions["resume"] = {["disabled"] = true}
local suspend = false
if obj.spec.suspend ~= nil then
suspend = obj.spec.suspend
end
if suspend then
actions["resume"]["disabled"] = false
else
actions["suspend"]["disabled"] = false
end
return actions
definitions:
- name: suspend
action.lua: |
obj.spec.suspend = true
return obj
- name: resume
action.lua: |
if obj.spec.suspend ~= nil and obj.spec.suspend then
obj.spec.suspend = false
end
return obj
Discovery.lua脚本必须返回一个键名代表操作名称的表。可以选择包含逻辑以启用或禁用基于当前对象状态的某些操作。
每个操作名称必须在定义列表中用随附的操作列表表示。LUA脚本以控制资源修改。 OBJ是包含资源的全局变量。每个操作脚本都返回资源的可选修改版本。在此示例中,我们只是将.spec.suspend
设置为true
或false
。
通过自定义动作创建新资源
通过Argo CD UI创建资源是与Gitops原则的有意,战略性的。建议很少使用此功能,仅用于不属于应用程序状态的资源。
调用操作的资源将称为源资源。
新的资源和所有作为隐性创建的资源必须在AppProject级别上允许,否则创建将失败。
通过自定义操作创建源资源孩子资源
如果新资源代表源资源的K8S孩子,则必须在新资源上设置源资源所有者Rereference。
这是一个示例LUA片段,它负责构建一个是源cronjob资源的工作资源 - OBJ是一个全局变量,其中包含源资源:
-- ...
ownerRef = {}
ownerRef.apiVersion = obj.apiVersion
ownerRef.kind = obj.kind
ownerRef.name = obj.metadata.name
ownerRef.uid = obj.metadata.uid
job = {}
job.metadata = {}
job.metadata.ownerReferences = {}
job.metadata.ownerReferences[1] = ownerRef
-- ...
通过自定义行动创建独立的孩子资源
如果新资源独立于源资源,则这种新资源的默认行为是,源资源的应用程序不知道它(因为它不是所需状态的一部分,也不是所有者Rereference)。
为了使应用程序了解新资源,必须在资源上设置app.kubernetes.io/instance
标签(或其他AgroCD跟踪标签,如果配置)。
它可以从源资源中复制,例如:
-- ...
newObj = {}
newObj.metadata = {}
newObj.metadata.labels = {}
newObj.metadata.labels["app.kubernetes.io/instance"] = obj.metadata.labels["app.kubernetes.io/instance"]
-- ...
虽然新资源将成为该应用程序的一部分,并将其跟踪标签制定到位,但如果在应用程序上设置了Auto Prune,它将立即删除。
要保留资源,请使用此LUA代码片段设置Prune = false
注释:
-- ...
newObj.metadata.annotations = {}
newObj.metadata.annotations["argocd.argoproj.io/sync-options"] = "Prune=false"
-- ...
资源和应用程序现在将出现在同步中 - 这是创建不属于所需状态一部分的资源时的预期ARGOCD行为。
如果想将该应用程序视为同步,请在LUA代码中添加以下资源注释:
产生资源列表的动作 - 一个完整的示例:
resource.customizations.actions.ConfigMap: |
discovery.lua: |
actions = {}
actions["do-things"] = {}
return actions
definitions:
- name: do-things
action.lua: |
-- Create a new ConfigMap
cm1 = {}
cm1.apiVersion = "v1"
cm1.kind = "ConfigMap"
cm1.metadata = {}
cm1.metadata.name = "cm1"
cm1.metadata.namespace = obj.metadata.namespace
cm1.metadata.labels = {}
-- Copy ArgoCD tracking label so that the resource is recognized by the App
cm1.metadata.labels["app.kubernetes.io/instance"] = obj.metadata.labels["app.kubernetes.io/instance"]
cm1.metadata.annotations = {}
-- For Apps with auto-prune, set the prune false on the resource, so it does not get deleted
cm1.metadata.annotations["argocd.argoproj.io/sync-options"] = "Prune=false"
-- Keep the App synced even though it has a resource that is not in Git
cm1.metadata.annotations["argocd.argoproj.io/compare-options"] = "IgnoreExtraneous"
cm1.data = {}
cm1.data.myKey1 = "myValue1"
impactedResource1 = {}
impactedResource1.operation = "create"
impactedResource1.resource = cm1
-- Patch the original cm
obj.metadata.labels["aKey"] = "aValue"
impactedResource2 = {}
impactedResource2.operation = "patch"
impactedResource2.resource = obj
result = {}
result[1] = impactedResource1
result[2] = impactedResource2
return result
7.18.自定义工具
Argo CD捆绑包的支持版本的模板工具(Helm,Kustomize,KS,JSONNET)作为其容器图像的一部分。有时,可能希望使用除argo cd束外的工具的特定版本。这样做的一些原因可能是:
- 由于错误或错误修复,要升级/降级到工具的特定版本。
- 要安装kustomize的ConfigMap/Secret Generators使用的其他依赖项。 (例如 curl, vault, gpg, AWS CLI)
- 安装配置管理插件。
由于Argo CD回购服务器是负责生成Kubernetes表现出的单一服务,因此可以自定义使用环境所需的替代工具链。
通过卷挂载添加工具
第一种技术是使用初始容器和卷来将不同版本的工具复制到repo-server容器中。在下面的示例中,初始容器正在覆盖与Argo CD中捆绑的版本不同版本的Helm二进制文件:
spec:
# 1. Define an emptyDir volume which will hold the custom binaries
volumes:
- name: custom-tools
emptyDir: {}
# 2. Use an init container to download/copy custom binaries into the emptyDir
initContainers:
- name: download-tools
image: alpine:3.8
command: [sh, -c]
args:
- wget -qO- https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz | tar -xvzf - &&
mv linux-amd64/helm /custom-tools/
volumeMounts:
- mountPath: /custom-tools
name: custom-tools
# 3. Volume mount the custom binary to the bin directory (overriding the existing version)
containers:
- name: argocd-repo-server
volumeMounts:
- mountPath: /usr/local/bin/helm
name: custom-tools
subPath: helm
BYOI (Build Your Own Image)
有时更换二进制是不够的,需要安装其他依赖项。以下示例从Dockerfile构建了一个完全自定义的回购服务器,安装了可能需要的额外依赖项。
FROM argoproj/argocd:v2.5.4 # Replace tag with the appropriate argo version
# Switch to root for the ability to perform install
USER root
# Install tools needed for your repo-server to retrieve & decrypt secrets, render manifests
# (e.g. curl, awscli, gpg, sops)
RUN apt-get update && \
apt-get install -y \
curl \
awscli \
gpg && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
curl -o /usr/local/bin/sops -L https://github.com/mozilla/sops/releases/download/3.2.0/sops-3.2.0.linux && \
chmod +x /usr/local/bin/sops
# Switch back to non-root user
USER $ARGOCD_USER_ID
7.19.定制样式
Argo CD从Argo-UI项目中进口了其大多数UI样式表。有时,可能希望将UI的某些组件自定义,或者有助于区分在不同环境中运行的Argo CD的多个实例。
可以通过将URL提供给远程托管的CSS文件,也可以通过将CSS文件直接加载到ArgOCD-Server容器中来应用此类自定义样式。这两种机制都是通过修改ArgoCD-CM ConfigMap来驱动的。
通过远程URL添加样式
第一个方法只需要将远程URL添加到ArgoCD-CM ConfigMap:
argocd-cm
---
apiVersion: v1
kind: ConfigMap
metadata:
...
name: argocd-cm
data:
ui.cssurl: "https://www.example.com/my-styles.css"
通过卷挂载添加样式
第二种方法需要将CSS文件直接安装到ArgoCD-Server容器上,然后为ArgoCD-CM提供正确配置的该文件的路径。在下面的示例中,CSS文件实际上是在单独的ConfigMap内部定义的(通过在InitContainer中生成或下载CSS文件可以实现相同的效果):
argocd-cm
---
apiVersion: v1
kind: ConfigMap
metadata:
...
name: argocd-cm
data:
ui.cssurl: "./custom/my-styles.css"
请注意,CSSURL应相对于“/shared/app”目录指定;不是绝对的路径。
argocd-styles-cm
---
apiVersion: v1
kind: ConfigMap
metadata:
...
name: argocd-styles-cm
data:
my-styles.css: |
.sidebar {
background: linear-gradient(to bottom, #999, #777, #333, #222, #111);
}
argocd-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
...
spec:
template:
...
spec:
containers:
- command:
...
volumeMounts:
...
- mountPath: /shared/app/custom
name: styles
...
volumes:
...
- configMap:
name: argocd-styles-cm
name: styles
请注意,CSS文件应安装在“/shared/app”目录(例如“/shared/app/custom”)的子目录中。否则,浏览器可能不会以“不正确的MIME类型”错误导入该文件。可以使用argocd-cmd-params-cm.yaml中
键为server.staticassets
更改子目录。
开发样式叠加
注入CSS文件中指定的样式应特定于Argo-UI中定义的组件和类。建议通过使用浏览器的内置开发人员工具来测试您希望首先应用的样式。为了获得更全面的体验,可能希望使用Argo CD UI Dev服务器构建一个单独的项目。
横幅:Banners
Argo CD可以选择显示横幅,该横幅可用于通知您的用户即将进行的维护和操作更改。可以通过使用ArgoCD-CM ConfigMap中的ui.bannercontent
字段指定横幅消息来启用此功能,而Argo CD将在每个UI页面的顶部显示此消息。您可以选择通过设置ui.bannerurl
添加此消息的链接。您还可以通过将ui.bannerpermanent
设置为TRUE并通过使用ui.bannerposition
将其位置更改为“bottom”,从而使横幅粘性(永久permanent)变为“”或“bottom”:“both”,允许横幅在顶部和底部显示,或ui.bannerposition
:“bottom”仅在底部显示。
argocd-cm
---
apiVersion: v1
kind: ConfigMap
metadata:
...
name: argocd-cm
data:
ui.bannercontent: "Banner message linked to a URL"
ui.bannerurl: "www.bannerlink.com"
ui.bannerpermanent: "true"
ui.bannerposition: "bottom"
7.20.UI自定义
默认应用程序详细信息视图
默认情况下,应用程序详细信息将显示Tree
视图。
可以通过应用程序来配置这一点,通过将pref.argocd.argoproj.io/default-view
注释设置为:接受:tree, pods, network, list作为值。
对于PODS视图,可以使用pref.argocd.argoproj.io/default-pod-sort
注释来配置默认分组机制,接受:node, parentResource, topLevelResource作为值之一。
7.21.指标
Argo CD揭露了每个服务器的不同集合量指标。
应用程序控制器指标
关于应用的指标。在ArgoCD-Metrics上 argocd-metrics:8082/metrics 端点。
Metric | Type | Description |
---|---|---|
argocd_app_info | gauge | 有关应用程序的信息。它包含诸如Sync_status和Health_status之类的标签,这些标签反映了Argo CD中的应用状态。 |
argocd_app_k8s_request_total | counter | 在申请对帐期间执行的Kubernetes请求数量 |
argocd_app_labels | gauge | Argo应用程序标签转换为Prometheus标签。默认情况下禁用。请参阅下面有关如何启用它的部分。 |
argocd_app_reconcile | histogram | 申请和解绩效。 |
argocd_app_sync_total | counter | 申请同步历史记录的计数器 |
argocd_cluster_api_resource_objects | gauge | 缓存中的K8S资源对象的数量。 |
argocd_cluster_api_resources | gauge | 受监控的Kubernetes API资源的数量。 |
argocd_cluster_cache_age_seconds | gauge | 群集缓存年龄在几秒钟内。 |
argocd_cluster_connection_status | gauge | K8S群集当前连接状态。 |
argocd_cluster_events_total | counter | 过程数量K8S资源事件。 |
argocd_cluster_info | gauge | 有关集群的信息。 |
argocd_kubectl_exec_pending | gauge | 待处理的kubectl执行次数 |
argocd_kubectl_exec_total | counter | kubectl执行的数量 |
argocd_redis_request_duration | histogram | REDIS请求持续时间。 |
argocd_redis_request_total | counter | 在申请核对期间执行的REDIS请求数量 |
如果将Argo CD与许多应用程序以及项目创建和删除一起使用,则指标页面将保持在您的应用程序和项目历史记录中。如果由于已删除的资源而导致大量的度量基数,遇到问题,则可以安排重置度量标准以使用应用程序控制器标志清洁历史记录。示例:--metrics-cache-expiration="24h0m0s"
。
将申请标签视为Prometheus指标
在某些用例中,Argo CD应用程序包含希望将其视为Prometheus指标的标签。一些例子是:
- 将团队名称作为标签,以允许将警报路由到特定的接收器
- 创建仪表板被业务部门分解
由于应用程序标签是针对每个公司的特定的,因此该功能默认情况下是禁用的。要启用它,请将--metrics-application-labels
标志添加到Argo CD应用程序控制器中。
下面的示例将使Argo CD应用程序标签team-name
和business-unit
与Prometheus:
containers:
- command:
- argocd-application-controller
- --metrics-application-labels
- team-name
- --metrics-application-labels
- business-unit
在这种情况下,指标看起来像:
# TYPE argocd_app_labels gauge
argocd_app_labels{label_business_unit="bu-id-1",label_team_name="my-team",name="my-app-1",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_business_unit="bu-id-1",label_team_name="my-team",name="my-app-2",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_business_unit="bu-id-2",label_team_name="another-team",name="my-app-3",namespace="argocd",project="important-project"} 1
API服务器指标
有关API服务器API请求和响应活动的指标(请求总计,响应代码等)。argocd-server-metrics:8083/metrics
端点。
Metric | Type | Description |
---|---|---|
argocd_redis_request_duration | histogram | REDIS请求持续时间。 |
argocd_redis_request_total | counter | 在申请对帐期间执行的Kubernetes请求数量。 |
grpc_server_handled_total | counter | 无论成功或故障如何,服务器上完成的RPC总数。 |
grpc_server_msg_sent_total | counter | 服务器发送的GRPC流消息的总数。 |
argocd_proxy_extension_request_total | 反向发送到配置的代理扩展名的请求数。 | |
argocd_proxy_extension_request_duration_seconds | histogram | 在Argo CD API服务器和代理扩展后端之间的几秒钟内请求持续时间。 |
存储服务器指标
关于远程服务器的指标。在argocd-repo-server:8084/metrics
。
Metric | Type | Description |
---|---|---|
argocd_git_request_duration_seconds | histogram | GIT请求持续时间秒。 |
argocd_git_request_total | counter | Repo服务器执行的GIT请求数量 |
argocd_git_fetch_fail_total | counter | repo服务器的git提取请求失败数量 |
argocd_redis_request_duration_seconds | histogram | REDIS请求持续时间秒。 |
argocd_redis_request_total | counter | 在申请对帐期间执行的Kubernetes请求数量。 |
argocd_repo_pending_request_total | gauge | 需要存储库锁的待处理请求数量 |
Prometheus操作员
如果使用Prometheus操作员,则可以使用以下服务示例清单。添加一个安装Argo CD的名称空间,然后将元数据更改为Prometheus选择的标签名称。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-metrics
endpoints:
- port: metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-server-metrics
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server-metrics
endpoints:
- port: metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-repo-server-metrics
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
endpoints:
- port: metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-applicationset-controller-metrics
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-applicationset-controller
endpoints:
- port: metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-dex-server
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-dex-server
endpoints:
- port: metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-redis-haproxy-metrics
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-redis-ha-haproxy
endpoints:
- port: http-exporter-port
对于通知控制器,需要另外添加以下方式:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-notifications-controller
labels:
release: prometheus-operator
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-notifications-controller-metrics
endpoints:
- port: metrics
仪表板
可以在此处找到一个示例Grafana仪表板或检查演示实例仪表板。
7.22.基于Web的终端
自v2.4以来,Argo CD具有基于Web的终端,可以像Kubectl Exec一样在运行吊舱内获取外壳。基本上是您的浏览器,完整的ANSI颜色支持等等!但是,对于安全性,默认情况下,此功能将被禁用。
这是一种强大的特权。它允许用户在由具有exec/create
特权的应用程序管理的任何POD上运行任意代码。如果POD安装了ServiceAccount令牌(这是Kubernetes的默认行为),则用户具有与ServiceAccount相同的特权。
启用终端
- 将
exec.enabled
键设置为true
在argocd-cm
ConfigMap上。 - 修补
argocd-server
Role(如果使用命名空间为Argo)或ClusterRole(如果使用簇Argo)允许argocd-server
execte exec
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
添加RBAC规则以允许的用户create exec pods,即
p, role:myrole, exec, create, */*, allow
有关更多信息,请参见RBAC配置。
更改允许的脚本
默认情况下,Argo CD尝试按以下顺序执行脚本:
- bash
- sh
- powershell
- cmd
如果找不到脚本,则终端会话将失败。要添加或更改允许的脚本,请更改exec.shells
键中的argocd-cm
ConfigMap中的键,并用逗号将它们分开。
7.23.配置管理插件
Argo CD的“native
”配置管理工具是Helm,Jsonnet和Kustomize。如果要使用其他配置管理工具,或者Argo CD的native工具支持不包括所需的功能,则可能需要转到配置管理插件(CMP)。
Argo CD “repo server
” 组件负责构建Kubernetes根据Helm,OCI或GIT存储库中的某些源文件表现出来。当正确配置配置管理插件时,Repo服务器可以将构建的任务委托给插件。
以下各节将描述如何创建,安装和使用插件。查看示例插件以获取其他指南。
插件对Argo CD系统具有信任程度,因此安全地实现插件很重要。 Argo CD管理员只能从可信赖的来源安装插件,他们应审核插件以权衡其特定风险和收益。
安装配置管理插件
SideCar插件
操作员可以通过SIDECAR配置插件工具到repo-server。需要以下更改来配置新插件:
写插件配置文件
插件将通过位于插件容器内部的ConfigmanagementPlugin清单进行配置。
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
# The name of the plugin must be unique within a given Argo CD instance.
name: my-plugin
spec:
# The version of your plugin. Optional. If specified, the Application's spec.source.plugin.name field
# must be <plugin name>-<plugin version>.
version: v1.0
# The init command runs in the Application source directory at the beginning of each manifest generation. The init
# command can output anything. A non-zero status code will fail manifest generation.
init:
# Init always happens immediately before generate, but its output is not treated as manifests.
# This is a good place to, for example, download chart dependencies.
command: [sh]
args: [-c, 'echo "Initializing..."']
# The generate command runs in the Application source directory each time manifests are generated. Standard output
# must be ONLY valid Kubernetes Objects in either YAML or JSON. A non-zero exit code will fail manifest generation.
# To write log messages from the command, write them to stderr, it will always be displayed.
# Error output will be sent to the UI, so avoid printing sensitive information (such as secrets).
generate:
command: [sh, -c]
args:
- |
echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"
# The discovery config is applied to a repository. If every configured discovery tool matches, then the plugin may be
# used to generate manifests for Applications using the repository. If the discovery config is omitted then the plugin
# will not match any application but can still be invoked explicitly by specifying the plugin name in the app spec.
# Only one of fileName, find.glob, or find.command should be specified. If multiple are specified then only the
# first (in that order) is evaluated.
discover:
# fileName is a glob pattern (https://pkg.go.dev/path/filepath#Glob) that is applied to the Application's source
# directory. If there is a match, this plugin may be used for the Application.
fileName: "./subdir/s*.yaml"
find:
# This does the same thing as fileName, but it supports double-start (nested directory) glob patterns.
glob: "**/Chart.yaml"
# The find command runs in the repository's root directory. To match, it must exit with status code 0 _and_
# produce non-empty output to standard out.
command: [sh, -c, find . -name env.yaml]
# The parameters config describes what parameters the UI should display for an Application. It is up to the user to
# actually set parameters in the Application manifest (in spec.source.plugin.parameters). The announcements _only_
# inform the "Parameters" tab in the App Details page of the UI.
parameters:
# Static parameter announcements are sent to the UI for _all_ Applications handled by this plugin.
# Think of the `string`, `array`, and `map` values set here as "defaults". It is up to the plugin author to make
# sure that these default values actually reflect the plugin's behavior if the user doesn't explicitly set different
# values for those parameters.
static:
- name: string-param
title: Description of the string param
tooltip: Tooltip shown when the user hovers the
# If this field is set, the UI will indicate to the user that they must set the value.
required: false
# itemType tells the UI how to present the parameter's value (or, for arrays and maps, values). Default is
# "string". Examples of other types which may be supported in the future are "boolean" or "number".
# Even if the itemType is not "string", the parameter value from the Application spec will be sent to the plugin
# as a string. It's up to the plugin to do the appropriate conversion.
itemType: ""
# collectionType describes what type of value this parameter accepts (string, array, or map) and allows the UI
# to present a form to match that type. Default is "string". This field must be present for non-string types.
# It will not be inferred from the presence of an `array` or `map` field.
collectionType: ""
# This field communicates the parameter's default value to the UI. Setting this field is optional.
string: default-string-value
# All the fields above besides "string" apply to both the array and map type parameter announcements.
- name: array-param
# This field communicates the parameter's default value to the UI. Setting this field is optional.
array: [default, items]
collectionType: array
- name: map-param
# This field communicates the parameter's default value to the UI. Setting this field is optional.
map:
some: value
collectionType: map
# Dynamic parameter announcements are announcements specific to an Application handled by this plugin. For example,
# the values for a Helm chart's values.yaml file could be sent as parameter announcements.
dynamic:
# The command is run in an Application's source directory. Standard output must be JSON matching the schema of the
# static parameter announcements list.
command: [echo, '[{"name": "example-param", "string": "default-string-value"}]']
# If set to `true` then the plugin receives repository files with original file mode. Dangerous since the repository
# might have executable files. Set to true only if you trust the CMP plugin authors.
preserveFileMode: false
虽然ConfigManagementPlugin看起来像Kubernetes对象,但实际上并不是自定义资源。它仅遵循Kubernetes风格的规格约定。
生成命令必须将有效的kubernetes yaml或json对象流打印为stdout。初始化和生成命令均在应用程序源目录中执行。
discover.filename
用作Glob模式,以确定插件是否支持应用程序存储库。
discover:
find:
command: [sh, -c, find . -name env.yaml]
如果未提供discover.fileName
,则执行discover.find.command
,以确定插件是否支持应用程序存储库。在支持应用程序源类型时,FIND命令应返回非错误退出代码并产生输出。
将插件配置文件放在sidecar
中
Argo CD期望插件配置文件位于sidecar中的/home/argocd/cmp-server/config/plugin.yaml
。
如果为 sidecar 使用自定义镜像,则可以将文件直接添加到该镜像中。
WORKDIR /home/argocd/cmp-server/config/
COPY plugin.yaml ./
如果使用库存图片作为 sidecar,或者宁愿在 ConfigMap 中维护插件配置,只需将插件配置文件嵌套在 plugin.yaml
键下的 ConfigMap 中,然后将 ConfigMap 挂载到 sidecar
中(参见下一部分)。
apiVersion: v1
kind: ConfigMap
metadata:
name: my-plugin-config
data:
plugin.yaml: |
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: my-plugin
spec:
version: v1.0
init:
command: [sh, -c, 'echo "Initializing..."']
generate:
command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"']
discover:
fileName: "./subdir/s*.yaml"
注册插件 sidecar
要安装插件,请修补 argocd-repo-server
以将插件容器作为sidecar
运行,并使用 argocd-cmp-server
作为其入口点。可以使用现成的或定制的插件映像作为 sidecar
映像。例如:
containers:
- name: my-plugin
command: [/var/run/argocd/argocd-cmp-server] # Entrypoint should be Argo CD lightweight CMP server i.e. argocd-cmp-server
image: busybox # This can be off-the-shelf or custom-built image
securityContext:
runAsNonRoot: true
runAsUser: 999
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
- mountPath: /home/argocd/cmp-server/plugins
name: plugins
# Remove this volumeMount if you've chosen to bake the config file into the sidecar image.
- mountPath: /home/argocd/cmp-server/config/plugin.yaml
subPath: plugin.yaml
name: my-plugin-config
# Starting with v2.4, do NOT mount the same tmp volume as the repo-server container. The filesystem separation helps
# mitigate path traversal attacks.
- mountPath: /tmp
name: cmp-tmp
volumes:
- configMap:
name: my-plugin-config
name: my-plugin-config
- emptyDir: {}
name: cmp-tmp
确保使用
/var/run/argocd/argocd-cmp-server
作为入口点。argocd-cmp-server
是一种轻量级 GRPC 服务,允许 Argo CD 与插件交互。
确保sidecar
容器以用户 999 身份运行。
确保插件配置文件位于/home/argocd/cmp-server/config/plugin.yaml
。它可以通过configmap
进行卷映射或嵌入到图像中。
在插件中使用环境变量
插件命令可以访问
sidecar
的系统环境变量- 标准构建环境变量
- 应用程序规范中的变量(对系统和构建变量的引用将插入到变量的值中):
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
plugin:
env:
- name: FOO
value: bar
- name: REV
value: test-$ARGOCD_APP_REVISION
在到达 init.command, generate.command, discover.find.command
命令之前,Argo CD 会为所有用户提供的环境变量(上面的 #3)添加 ARGOCD_ENV_
前缀。这可防止用户直接设置可能敏感的环境变量。
- 应用程序规范中的参数:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
plugin:
parameters:
- name: values-files
array: [values-dev.yaml]
- name: helm-parameters
map:
image.tag: v1.2.3
这些参数在 ARGOCD_APP_PARAMETERS
环境变量中以 JSON 形式提供。上面的示例将生成以下 JSON:
[
{
"name": "values-files",
"array": [
"values-dev.yaml"
]
},
{
"name": "helm-parameters",
"map": {
"image.tag": "v1.2.3"
}
}
]
即使指定了默认值,参数声明也不会发送到
ARGOCD_APP_PARAMETERS
中的插件。只有在应用程序规范中明确设置的参数才会发送到插件。插件将应用与 UI 中声明的相同的默认值。
相同的参数也可用作单独的环境变量。环境变量的名称遵循以下约定:
- name: some-string-param
string: some-string-value
# PARAM_SOME_STRING_PARAM=some-string-value
- name: some-array-param
value: [item1, item2]
# PARAM_SOME_ARRAY_PARAM_0=item1
# PARAM_SOME_ARRAY_PARAM_1=item2
- name: some-map-param
map:
image.tag: v1.2.3
# PARAM_SOME_MAP_PARAM_IMAGE_TAG=v1.2.3
作为 Argo CD 清单生成系统的一部分,配置管理插件受到一定程度的信任。请务必在插件中转义用户输入,以防止恶意输入导致不良行为。
在应用程序中使用配置管理插件
可以将插件部分中的name
字段留空,以便根据其发现规则自动将plugin
与应用程序匹配。如果确实提到了名称,请确保它是 <metadata.name>-<spec.version>
(如果在 ConfigManagementPlugin
规范中提到了版本),否则只是 <metadata.name>
。当明确指定名称时,只有当其发现pattern/command
与提供的应用程序存储库匹配时,才会使用该特定插件。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
plugin:
env:
- name: FOO
value: bar
如果不需要设置任何环境变量,您可以设置一个空的插件部分。
plugin: {}
如果 CMP 命令运行时间过长,该命令将被终止,并且 UI 将显示错误。CMP 服务器尊重
argocd-cm
中的server.repo.server.timeout.seconds
和controller.repo.server.timeout.seconds
项设置的超时。将其值从默认的60
秒增加。
每个 CMP 命令还将在为 CMP
sidecar
设置的ARGOCD_EXEC_TIMEOUT
上独立超时。默认值为90
秒。因此,如果将 repo 服务器超时时间增加到90
秒以上,请务必在sidecar
上设置ARGOCD_EXEC_TIMEOUT
。
每个应用程序一次只能配置一个配置管理插件。如果要将通过
argocd-cm
ConfigMap 配置的现有插件转换为sidecar
,请确保将插件名称更新为<metadata.name>-<spec.version>
(如果ConfigManagementPlugin
规范中提到了版本),否则只需使用<metadata.name>
。也可以完全删除名称并让自动发现识别插件。
如果 CMP 呈现空白的清单,并且
prune
设置为 true,Argo CD 将自动删除资源。CMP 插件作者应确保错误是退出代码的一部分。通常,像kustomize build . | cat
这样的命令不会因为管道而传递错误。考虑设置set -o pipefail
,这样任何管道都会在失败时传递错误。
调试 CMP
如果正在积极开发安装有 sidecar
的 CMP,请记住以下几点:
- 如果从 ConfigMap 安装
plugin.yaml
,则必须重新启动repo-server
Pod,以便插件能够获取更改。 - 如果已将
plugin.yaml
嵌入到镜像中,则必须在repo-server
Pod 上构建、推送并强制重新拉取该镜像,以便插件能够获取更改。如果使用的是:latest
,Pod 将始终拉取新镜像。如果您使用的是不同的静态标签,请在 CMP 的 sidecar 容器上设置imagePullPolicy: Always
。 - CMP 错误由 Redis 中的
repo-server
缓存。重新启动repo-server
Pod 不会清除缓存。在积极开发 CMP 时,请务必执行“Hard Refresh
”,以便获得最新的输出。 - 通过查看 Pod 并看到两个容器正在运行,验证你的
sidecar
是否已正确启动kubectl get pod -l app.kubernetes.io/component=repo-server -n argocd
- 将日志消息写入
stderr
并在sidecar
中设置--loglevel=info
标志。这将打印写入stderr
的所有内容,即使命令执行成功。
其他常见错误
Error Message | Cause |
---|---|
no matches for kind “ConfigManagementPlugin” in version “argoproj.io/v1alpha1” | ConfigManagementPlugin CRD 在 Argo CD 2.4 中已弃用,并在 2.8 中被删除。此错误意味着您尝试将插件的配置直接作为 CRD 放入 Kubernetes。 |
插件 tar 流排除
为了提高清单(manifest)生成速度,可以排除某些文件和文件夹,使其不发送到插件。如果没有必要,我们建议排除 .git
文件夹。使用 Go 的 filepatch.Match 语法。例如,.git/*
排除 .git
文件夹。
可以通过以下三种方式之一进行设置:
- 存储库服务器上的
--plugin-tar-exclude
参数。 - 如果使用
argocd-cmd-params-cm
,则需要reposerver.plugin.tar.exclusions
键 - 直接在
repo
服务器上设置ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
环境变量。
对于选项 1,该标志可以重复多次。对于选项 2 和 3,可以指定多个 glob,并用分号分隔它们。
从 argocd-cm 插件迁移
通过修改 argocd-cm
ConfigMap 来安装插件的方法从 v2.4 开始已被弃用,并且从 v2.8 开始已被完全删除。
CMP 插件的工作原理是将 sidecar 添加到
argocd-repo-server,并在该
sidecar中配置位于
/home/argocd/cmp-server/config/plugin.yaml的配置。
argocd-cm` 插件可以通过以下步骤轻松转换。
将 ConfigMap 条目转换为配置文件
首先,将插件的配置复制到其自己的 YAML 文件中。例如以下 ConfigMap 条目:
data:
configManagementPlugins: |
- name: pluginName
init: # Optional command to initialize application source directory
command: ["sample command"]
args: ["sample args"]
generate: # Command to generate Kubernetes Objects in either YAML or JSON
command: ["sample command"]
args: ["sample args"]
lockRepo: true # Defaults to false. See below.
pluginName
项将转换为这样的配置文件:
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: pluginName
spec:
init: # Optional command to initialize application source directory
command: ["sample command"]
args: ["sample args"]
generate: # Command to generate Kubernetes Objects in either YAML or JSON
command: ["sample command"]
args: ["sample args"]
lockRepo
键与sidecar
插件无关,因为sidecar
插件在生成清单时不共享单个源 repo 目录。
接下来,我们需要决定如何将此yaml
添加到 sidecar
。我们可以将 yaml
直接嵌入到镜像中,也可以从 ConfigMap 中挂载它。
如果使用 ConfigMap,我们的示例将如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: pluginName
namespace: argocd
data:
pluginName.yaml: |
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: pluginName
spec:
init: # Optional command to initialize application source directory
command: ["sample command"]
args: ["sample args"]
generate: # Command to generate Kubernetes Objects in either YAML or JSON
command: ["sample command"]
args: ["sample args"]
然后它将被安装在我们的插件边车(sidecar)中。
为你的插件编写发现规则
sidecar 插件可以使用发现规则或插件名称来将应用程序与插件进行匹配。如果省略发现规则,则必须在应用规范中通过名称明确指定插件,否则该特定插件将不会与任何应用程序匹配。
如果想使用发现而不是插件名称来将应用程序与你的插件匹配,请使用上述说明编写适用于你的插件的规则并将其添加到你的配置文件中。
要使用名称而不是发现,请将应用程序清单中的名称更新为 <metadata.name>-<spec.version>
(如果在 ConfigManagementPlugin
规范中提到了版本),否则只需使用 <metadata.name>
。例如:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
spec:
source:
plugin:
name: pluginName # Delete this for auto-discovery (and set `plugin: {}` if `name` was the only value) or use proper sidecar plugin name
确保插件可以访问其所需的工具
使用 argocd-cm
配置的插件在 Argo CD 映像上运行。这使其可以默认访问该映像上安装的所有工具(请参阅 Dockerfile 以了解基本映像和已安装的工具)。
可以使用库存映像(例如 busybox
或 alpine/k8s
),也可以使用插件所需的工具设计自己的基础映像。出于安全考虑,请避免使用安装的二进制文件多于插件实际需要的映像。
测试插件
按照上述说明将插件安装为 sidecar 后,请先在几个应用程序上进行测试,然后再将它们全部迁移到 sidecar 插件。
测试完成后,从 argocd-cm ConfigMap 中删除插件条目。
其他设置
保留存储库文件模式
默认情况下,配置管理插件会以重置文件模式接收源存储库文件。这样做是出于安全原因。如果想保留原始文件模式,可以在插件规范中将preserveFileMode
设置为true
:
确保信任所使用的插件。如果将preserveFileMode
设置为true
,那么插件可能会接收具有可执行权限的文件,这可能会带来安全风险。
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: pluginName
spec:
init:
command: ["sample command"]
args: ["sample args"]
generate:
command: ["sample command"]
args: ["sample args"]
preserveFileMode: true
7.24.深层链接
深层链接允许用户从 Argo CD 用户界面快速重定向到第三方系统,例如 Splunk、Datadog 等。
Argo CD 管理员将能够通过提供在 argocd-cm
中配置的深度链接模板来配置指向第三方系统的链接。这些模板可以有条件地呈现,并能够引用与链接显示位置相关的不同类型的资源,其中包括项目、应用程序或单个资源(pod、服务等)。
配置深层链接
Deep Links 的配置在 argocd-cm
中以 <location>.links
字段的形式存在,其中 <location>
确定其显示位置。<location>
的可能值为:
- `project:此字段下的所有链接都将显示在 Argo CD UI 中的项目选项卡中
application
:此字段下的所有链接都将显示在应用程序摘要选项卡中resource
:此字段下的所有链接都将显示在资源(部署、pod、服务等)摘要选项卡中
列表中的每个链接都有五个子字段:
title
与该链接对应的 UI 中将显示的 title/tagurl
深层链接将重定向到的实际 URL,此字段可以模板化以使用来自相应应用程序、项目或资源对象(取决于其所在位置)的数据。这使用text/template pkg
进行模板化description
可选 深度链接的描述icon.class
可选 在下拉菜单中显示链接时使用的 font-awesome 图标类if
可选 一个结果为真或假的条件语句,它也可以访问与 url 字段相同的数据。如果条件解析为真,则将显示深层链接 - 否则将隐藏。如果省略该字段,则默认将显示深层链接。这使用antonmedv/expr
来评估条件
对于 Secret 类型的资源,数据字段已被删除,但其他字段可用于模板深层链接。
确保验证 URL 模板和输入,以防止数据泄露或可能生成任何恶意链接。
如前所述,可以模板化链接和条件以使用来自资源的数据,每个类别的链接都可以访问链接到该资源的不同类型的数据。总的来说,我们在系统中有以下 4 种资源可用于模板化:
app
或application
该键用于访问应用程序资源数据。resource
此键用于访问实际的 k8s 资源的值。cluster
此键用于访问相关的目标集群数据,如名称、服务器、命名空间等。project
此键用于访问项目资源数据。
上述资源可通过特定的链接类别访问,以下是每个类别中可用资源的列表:
resource.links
:resource, application, cluster, project
application.links
:app/application, cluster
project.links
:project
具有深层链接及其变体的示例 argocd-cm.yaml
文件:
# sample project level links
project.links: |
- url: https://myaudit-system.com?project={{.project.metadata.name}}
title: Audit
description: system audit logs
icon.class: "fa-book"
# sample application level links
application.links: |
# pkg.go.dev/text/template is used for evaluating url templates
- url: https://mycompany.splunk.com?search={{.app.spec.destination.namespace}}&env={{.project.metadata.labels.env}}
title: Splunk
# conditionally show link e.g. for specific project
# github.com/antonmedv/expr is used for evaluation of conditions
- url: https://mycompany.splunk.com?search={{.app.spec.destination.namespace}}
title: Splunk
if: application.spec.project == "default"
- url: https://{{.app.metadata.annotations.splunkhost}}?search={{.app.spec.destination.namespace}}
title: Splunk
if: app.metadata.annotations.splunkhost != ""
# sample resource level links
resource.links: |
- url: https://mycompany.splunk.com?search={{.resource.metadata.name}}&env={{.project.metadata.labels.env}}
title: Splunk
if: resource.kind == "Pod" || resource.kind == "Deployment"