理解 Argo CD

引言

Kubernetes 的出现改变了业界对软件持续交付的看法。发布复杂软件意味着需要处理配置和环境。配置、环境设置和基础设施来源逐渐以 Git 作为事实上的标准。Git 成为软件代码和基础设施代码的"真理源"。GitOps 是一种运维框架,将 DevOps 最佳实践与 Git 作为真理源相结合。Argo CD 就是这样一个为 Kubernetes 设计的 GitOps 操作工具。

根据官方定义,Argo CD 是一个面向 Kubernetes 的声明式 GitOps 持续交付工具。

在这个背景下,Argo CD 作为专门为 Kubernetes 构建的 GitOps 持续交付工具应运而生。它以声明式方式管理应用部署,确保实际基础设施状态始终与 Git 仓库中定义的期望状态保持一致。理解 Argo CD 的架构、组件和运行模式,对于在 Kubernetes 环境中实施有效的 GitOps 实践至关重要。

章节结构

本章将讨论以下主题:

  • 认识 Argo CD
  • 在 minikube 中部署 Argo CD
  • 使用 Argo CD CLI
  • Argo CD 架构
  • Argo CD 概念与术语
  • Argo CD 声明式配置

目标

本章将介绍 GitOps 的基础原则,并探讨这些原则如何体现在 Argo CD 的架构中。首先对比声明式和命令式范式的哲学差异,进而阐述版本控制作为现代基础设施管理中单一真理源的重要角色。接着深入解析 Argo CD 复杂的架构,重点分析其核心组件------API 服务器、仓库服务器和应用控制器,如何协同实现强大的 GitOps。我们还将审视关键的支撑基础设施,包括用于缓存的 Redis、用于身份验证的 Dex 以及通知系统。

理论基础部分之后,将通过在 minikube 环境下部署 Argo CD 进行实操演示,涵盖配置方法、命令行界面操作,以及多集群部署编排的细节。通过对应用和项目等核心概念的讲解,帮助读者全面理解状态管理和应用源整合,包括 Helm charts、Kustomize 配置和原始 YAML 清单。

此外,本章还将展示 Argo CD 与 Kubernetes 原生模式的集成,说明基础设施定义、项目配置和凭证管理如何与 GitOps 原则保持一致,同时保障安全与运维效率。这一综合探讨将为读者构建理论与实践相结合的 Argo CD 架构和运行模式认知,为在生产环境中实施 GitOps 打下坚实基础。

认识 Argo CD

Argo CD 是 Kubernetes 的工具,我们可以用命令式或声明式方式配置 Kubernetes 来创建资源。这两种方式各有优势。命令式配置是直接通过命令行在 Kubernetes 集群中创建资源;声明式配置则是先定义资源的清单文件,再将其应用于集群。

那么,声明式到底是什么意思?术语解释如下:

  • 声明式编程是一种描述"做什么"(WHAT)的范式。
  • 命令式编程是一种描述"怎么做"(HOW)的范式。

例如,SQL 是声明式语言。当我们执行 SELECT * FROM users WHERE id <= 500 语句时,表达的是"我想要前 500 个用户",具体如何获取这些数据由 SQL 引擎实现。HTML 也是一种声明式方式,告诉机器我们想要什么。

下面是 Kubernetes 中声明式创建 Pod 的示例:

yaml 复制代码
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: declarative-pod
  labels:
    role: myrole
spec:
  containers:
    - name: declarative-pod
      image: nginx
      ports:
        - name: declarative-pod
          containerPort: 80
          protocol: TCP
EOF

通过创建 YAML 清单文件来声明式创建 Pod。

而命令式创建 Pod 则为:

lua 复制代码
kubectl create deploy imperative-pod --image nginx

接下来我们讨论 GitOps。

GitOps 介绍

GitOps 是一种运维框架,使用 Git 仓库作为声明式基础设施和应用代码的单一真理源。它将 Git 的版本控制、协作和合规功能应用于基础设施自动化和应用部署。

Argo CD 通过使用 Git 仓库定义和控制期望的应用状态,实现了 GitOps 原则。这确保了整个部署过程具备版本控制、可审计和可复现的特性。

使用 Argo CD 实现 GitOps 的关键优势包括:

  • 应用代码和基础设施的版本控制
  • 自动漂移检测与纠正
  • 完整的变更审计轨迹
  • 内置回滚能力
  • 集群间一致的部署模式

要体验这些功能,Argo CD 提供了公共演示实例:cd.apps.argoproj.io 。该示例展示了自管理的 Argo CD 安装及其 GitOps 能力。

关于 Argo CD 的常见误解

在深入学习前,需要澄清几个关于 Argo CD 的常见误解。首先,Argo CD 不是持续集成(CI)工具,它不负责构建 Docker 镜像或执行集成测试。相反,它专门作为 Kubernetes 的持续交付工具设计。

在 minikube 中部署 Argo CD

让我们通过在本地 Kubernetes 集群(使用 minikube)中部署 Argo CD 来动手实践。在开始之前,请确保实验环境具备以下已正确配置的前置条件:

在安装 Argo CD 之前,需要先启动 minikube 集群:

css 复制代码
# 启动一个专为 Argo CD 配置的 Minikube 集群
# --memory:分配 4GB 内存
# --cpus:使用 2 个 CPU 核心
# --kubernetes-version:指定 Kubernetes 版本
# --driver:使用 Docker 驱动
# --profile:创建指定名称的集群配置文件
minikube start --memory=4096 --cpus=2 --kubernetes-version=1.23.1 --driver=docker --profile argocd-cluster

该命令将创建名为 argocd-cluster 的 minikube 集群,Kubernetes 版本为指定版本。为了探讨生产环境相关的多集群话题,我们需要多个 Kubernetes 集群。Argo CD 可以部署在它自身运行的集群,也可以部署到其他目标集群,操作人员可根据需求选择。

我们可以使用以下命令快速安装 Argo CD:

ruby 复制代码
# 创建 Argo CD 专用命名空间
kubectl create namespace argocd

# 使用官方清单安装 Argo CD 组件
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Argo CD 的安装清单位于 manifests 文件夹。核心安装是基础组件,不包含 UI、单点登录(SSO)和多集群功能。(这些安装选项将在相关章节中讨论。)

部署清单时,运行状态可能如下所示:

sql 复制代码
kubectl get pod -n argocd

NAME                                               READY   STATUS    RESTARTS        
argocd-application-controller-0                    1/1     Running   1 (4m17s ago)
argocd-applicationset-controller-7f466f7cc-kn5rr   1/1     Running   1 (4m17s ago)
argocd-dex-server-54cd4596c4-dwtp7                 1/1     Running   1 (4m17s ago)
argocd-notifications-controller-8445d56d96-9wg2h   1/1     Running   1 (4m17s ago)
argocd-redis-65596bf87-4msq9                       1/1     Running   1 (4m17s ago)
argocd-repo-server-5ccf4bd568-rblwr                1/1     Running   1 (4m17s ago)
argocd-server-7dff66c8f8-vgmkf                     1/1     Running   1 (4m17s ago)

上述输出中包括以下组件,我们将在 Argo CD 架构章节逐一探讨:

  • argocd-server
  • argocd-repo-server
  • argocd-redis
  • argocd-notifications-controller
  • argocd-applicationset-controller
  • argocd-application-controller

如果所有 Pod 都处于运行状态,我们即可通过端口转发访问 Argo CD 的 Web UI:

bash 复制代码
# 将 Argo CD API 服务器端口转发到本地以访问 Web UI
# 8080:本地端口
# 443:Argo CD 服务器端口
kubectl port-forward svc/argocd-server -n argocd 8080:443

此时可以通过 https://localhost:8080 访问 Argo CD UI。(见图 2.1)

现在我们需要获取 admin 账户的初始密码,可以使用 kubectl 来检索:

ini 复制代码
# 从 Kubernetes Secret 中获取自动生成的 admin 密码
# 密码是 base64 编码的,需要解码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

通过上述命令获取的密码是自动生成的明文密码。该管理员密码在安装过程中自动生成,并作为 Kubernetes Secret 存储在 argocd 命名空间中,Secret 名称为 argocd-initial-admin-secret。此默认配置仅供首次访问使用,不应直接用于生产环境。

在生产环境部署中,请执行以下操作:

  • 在完成适当的身份认证配置后,删除初始管理员 Secret
  • 配置与企业身份认证系统集成(如 LDAP、OIDC 或 SSO)
  • 为团队成员实施基于角色的访问控制(RBAC)
  • 遵循凭证管理的安全最佳实践

安全注意事项如下:

  • 初始管理员密码以 base64 编码形式存储,并非加密
  • 配置其他认证方式后,应删除该 Secret
  • 访问该 Secret 需严格控制权限

关于生产环境中安全认证与授权的详细实施说明,包括与中央认证系统的集成,请参阅第 3 章《在生产环境中运行 Argo CD》。

接下来,使用刚才获取的密码和用户名 admin 登录 Argo CD(参见图 2.2)。

现在,我们可以配置 Argo CD 来部署应用,选择在同一个 Kubernetes 集群中部署应用,或者将一个或多个集群注册到 Argo CD 作为目标集群。

虽然 Argo CD 的 UI 提供了大部分操作的友好界面,但 CLI 在自动化或无浏览器环境下更具灵活性。下面我们来学习如何有效使用 CLI。

本书中"使用 Argo CD CLI"章节会详细介绍 Argo CD CLI。

要开始使用 CLI,首先需要用 admin 凭据进行认证并进行如下设置:

确保在终端中已将 Argo CD 服务端口转发,或后台运行该命令:

bash 复制代码
kubectl -n argocd port-forward svc/argocd-server 2746:80 &

将 admin 密码存入环境变量:

ini 复制代码
ARGOCDPASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo)

使用 admin 账号登录 Argo CD:

bash 复制代码
argocd login 127.0.0.1:2746 --username admin --password $ARGOCDPASSWORD

注意:生产环境中,操作员通常会通过内外部负载均衡器暴露 argocd 服务器,此时无需端口转发。

登录成功后,执行 argocd context,会看到带星号 * 的上下文条目表示选中状态:

markdown 复制代码
CURRENT  NAME             SERVER
*        127.0.0.1:8080   127.0.0.1:8080
         127.0.0.1:2746   127.0.0.1:2746

此时即可开始部署应用。以创建示例的 guestbook 应用为例,执行:

lua 复制代码
argocd app create guestbook \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-server https://kubernetes.default.svc \
--dest-namespace default

仔细看这个命令中的参数:

  • --repo 指定要同步的 Git 仓库地址。
  • --path guestbook 指定仓库中的子目录,只同步此目录内容(适合单仓库管理多项目时精确同步)。
  • --dest-server https://kubernetes.default.svc 指定目标集群,这里是 Argo CD 自身所在的集群。
  • --dest-namespace default 指定目标命名空间。

至此,我们已经在 Argo CD 中添加了一个应用。通过以下命令查看应用列表:

复制代码
argocd app list

示例输出:

sql 复制代码
Handling connection for 2746
NAME       CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH       TARGET
guestbook  https://kubernetes.default.svc  default    default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git  guestbook

查看应用详情:

arduino 复制代码
argocd app get guestbook

输出示例(部分):

vbnet 复制代码
Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://127.0.0.1:2746/applications/guestbook
Repo:               https://github.com/argoproj/argocd-example-apps.git
Path:               guestbook
Sync Status:        OutOfSync from  (53e28ff)
Health Status:      Missing
...

如上,Sync Status 显示为 OutOfSync,表示应用当前状态与 Git 中定义的期望状态不一致。根据同步策略,Argo CD 可自动同步,也可手动同步。自动同步适合开发集群,生产环境建议人工把控同步流程。

在同步前,可先查看差异:

复制代码
argocd app diff guestbook

输出差异示例(节选):

shell 复制代码
===== /Service default/guestbook-ui ======
0a1,13
> apiVersion: v1
> kind: Service
> metadata:
>   labels:
>     app.kubernetes.io/instance: guestbook
>   name: guestbook-ui
>   namespace: default
> spec:
>   ports:
>   - port: 80
>     targetPort: 80
>   selector:
>     app: guestbook-ui
...

确认差异符合预期后,执行同步部署:

bash 复制代码
argocd app sync guestbook

同步过程示例日志:

arduino 复制代码
2022-09-17T21:02:46+02:00   apps  Deployment     default          guestbook-ui    Synced  Progressing              deployment.apps/guestbook-ui created
...

再次查看应用状态:

arduino 复制代码
argocd app get guestbook

状态显示同步完成且健康:

yaml 复制代码
Sync Status:        Synced to  (53e28ff)
Health Status:      Healthy
...

同样的操作也可以通过 UI 进行查看和管理,如图 2.3 所示。

在不同集群中部署应用

我们可以使用 minikube 创建另一个集群,命名为 apps-cluster。由于目标是让 Argo CD 在该集群中进行变更操作,需要确保该集群的 API 服务器对 Argo CD 集群可访问。因此,创建 apps-cluster 时需要添加参数 --apiserver-ips=<宿主机IP>
$(ipconfig getifaddr en0) 是 macOS 特有的命令,用于获取宿主机 IP。请根据操作系统和环境调整命令,例如:

scss 复制代码
minikube start --memory=2096 --cpus=2 --kubernetes-version=1.23.1 --apiserver-ips=$(ipconfig getifaddr en0) --driver=docker --profile apps-cluster

现在我们有两个 minikube 集群,查看 kubeconfig 文件:

bash 复制代码
cat ~/.kube/config

部分内容示例:

yaml 复制代码
apiVersion: v1
clusters:
  - cluster:
      certificate-authority: /Users/<username>/.minikube/ca.crt
      extensions:
        - extension:
            last-update: Sat, 17 Sep 2022 20:46:01 CEST
            provider: minikube.sigs.k8s.io
            version: v1.26.1
          name: cluster_info
      server: https://127.0.0.1:53981
    name: apps-cluster
  - cluster:
      certificate-authority: /Users/<username>/.minikube/ca.crt
      extensions:
        - extension:
            last-update: Sat, 17 Sep 2022 20:45:28 CEST
            provider: minikube.sigs.k8s.io
            version: v1.26.1
          name: cluster_info
      server: https://127.0.0.1:53928
    name: argocd-cluster

在将 apps-cluster 添加到 Argo CD 之前,需要修改第 11 行(示例中)中 server: https://127.0.0.1:53981server: https://<宿主机IP>:53981

你可以手动编辑 ~/.kube/config 文件,也可以使用如下脚本自动修改(macOS 环境示例):

bash 复制代码
LOCALIP=$(ipconfig getifaddr en0)
ARGOAPSCLUSTERPORT=$(cat ~/.kube/config | yq '.clusters[] | select(.name == "apps-cluster") | .cluster.server'| cut -f 3 -d ':')
yq eval '(.clusters[] | select(has("name")) | select(.name == "apps-cluster")).cluster.server = "https://'$LOCALIP':'$ARGOAPSCLUSTERPORT'"' -i ~/.kube/config

修改后,配置文件应类似如下(以宿主机 IP 192.168.0.4 为例):

yaml 复制代码
apiVersion: v1
clusters:
  - cluster:
      certificate-authority: /Users/<username>/.minikube/ca.crt
      extensions:
        - extension:
            last-update: Sat, 17 Sep 2022 20:46:01 CEST
            provider: minikube.sigs.k8s.io
            version: v1.26.1
          name: cluster_info
      server: https://192.168.0.4:53981
    name: apps-cluster
  - cluster:
      certificate-authority: /Users/<username>/.minikube/ca.crt
      extensions:
        - extension:
            last-update: Sat, 17 Sep 2022 20:45:28 CEST
            provider: minikube.sigs.k8s.io
            version: v1.26.1
          name: cluster_info
      server: https://127.0.0.1:53928
    name: argocd-cluster

现在,我们可以将 apps-cluster 添加到 Argo CD。

首先确保使用正确的 kube 上下文,并且已登录 Argo CD(本例仅处理两个 minikube 集群):

bash 复制代码
kubectl config use-context argocd-cluster
ARGOCDPASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo)
argocd login 127.0.0.1:2746 --username admin --password $ARGOCDPASSWORD

接下来注册目标集群,以便部署应用:

csharp 复制代码
argocd cluster add apps-cluster

创建应用示例:

lua 复制代码
argocd app create guestbook \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-server https://192.168.0.4:53981 \
--dest-namespace default

到此为止,我们已经了解了 Argo CD 并完成了简单的部署流程。请记住,生产环境部署需要遵循不同的安装路径。接下来,让我们进一步熟悉 Argo CD CLI 和架构。

使用 Argo CD CLI

Argo CD CLI 是与 Argo CD 交互的强大工具。学习 CLI 最好的方法是多练习和经常使用,但先简单了解其功能也很有帮助。本节汇总了本书中用到的所有命令,方便读者随时回顾。

你可以通过 CLI 或 Web UI 与 Argo CD 交互。关于 Argo CD CLI 在所有支持环境下的安装说明,详见官方文档:argo-cd.readthedocs.io/en/stable/c...

在 macOS 上,可以用下面的简单命令安装 argocd CLI:

复制代码
brew install argocd

Argo CD CLI 自带帮助功能,使用 -h 查看帮助菜单:

复制代码
argocd -h

输出示例:

sql 复制代码
argocd controls a Argo CD server
Usage:
  argocd [flags]
  argocd [command]

Available Commands:
  account     Manage account settings
  admin       Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access
  app         Manage applications
  cert        Manage repository certificates and SSH known hosts entries
  cluster     Manage cluster credentials
  completion  output shell completion code for the specified shell (bash or zsh)
  context     Switch between contexts
  gpg         Manage GPG keys used for signature verification
  help        Help about any command
  login       Log in to Argo CD
  logout      Log out from Argo CD
  proj        Manage projects
  relogin     Refresh an expired authenticate token
  repo        Manage repository connection parameters
  repocreds   Manage repository connection parameters
  version     Print version information

创建应用示例:

lua 复制代码
argocd app create guestbook \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-server https://kubernetes.default.svc \
--dest-namespace default

参数简述:

  • --repo https://github.com/argoproj/argocd-example-apps.git:指定 Argo CD 要同步的 Git 仓库。
  • --path guestbook:指定仓库中同步的子目录。
  • --dest-server https://kubernetes.default.svc:目标 Kubernetes 集群,Argo CD 将部署资源到该集群。
  • --dest-namespace default:目标集群中要同步的命名空间。

同步应用:

创建应用后,需要执行同步操作才能开始部署。查看应用状态:

arduino 复制代码
argocd app get guestbook

示例输出:

vbnet 复制代码
Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://127.0.0.1:2746/applications/guestbook
Repo:               https://github.com/argoproj/argocd-example-apps.git
Path:               guestbook
Sync Status:        OutOfSync
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing

使用以下命令同步应用,Argo CD 会比对与目标集群的差异并执行同步:

bash 复制代码
argocd app sync guestbook

通过 CLI 添加 Git 仓库:

csharp 复制代码
argocd repo add https://github.com/argoproj/argocd-example-apps.git

查看已添加的仓库列表:

复制代码
argocd repo list

示例输出:

bash 复制代码
TYPE  NAME  REPO                                                 INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         https://github.com/argoproj/argocd-example-apps.git  false     false  false  false  Successful

查看仓库相关的 Kubernetes Secret:

arduino 复制代码
kubectl get secret -n argocd
kubectl get secret repo-3973969552 -n argocd
kubectl get secret repo-3973969552 -n argocd -o yaml

-o yaml 输出示例片段:

yaml 复制代码
apiVersion: v1
data:
  type: Z2l0
  url: aHR0cHM6Ly9naXRodWIuY29tL2FyZ29wcm9qL2FyZ29jZC1leGFtcGxlLWFwcHMuZ2l0
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  creationTimestamp: "2022-09-18T12:03:10Z"
  labels:
    argocd.argoproj.io/secret-type: repository
  name: repo-3973969552
  namespace: argocd
type: Opaque

你可以使用 echo <base64字符串> | base64 -d 解码 url 字段,查看原始仓库地址。

Argo CD 架构

要理解 Argo CD 的架构,首先来看一个高层次的概览。Argo CD 的 CLI 和 UI 都与 API 服务器进行交互。显然,Argo CD 需要一个组件来处理源码仓库的变更,另一个组件负责与 Kubernetes 进行交互。

现在,想象一个典型的 CI/CD 流程:开发者向 Git 仓库(比如 GitHub、GitLab、BitBucket,或者组织内部使用的其他平台)提交一个 Pull Request(PR)。CI 流程开始执行,包括测试、代码规范检查(linting)以及其他必要的检查,如凭证泄露扫描。如果所有集成检查通过,系统会创建一个 Docker 容器镜像,并将其上传到容器镜像仓库(例如 Docker Hub、Amazon ECR、GCR,或者组织指定的其他仓库)。

接下来,生成 Kubernetes 清单文件(manifests),并提交到由 Argo CD 管理的单独 Git 仓库。Argo CD 监测到目标状态的变更后,会在预先配置好的 Kubernetes 集群中部署新的基础设施或应用程序。

如图 2.4 所示的高层架构图展示了 Argo CD 的一个看似简单的核心组件实现。在最基本的层面,Argo CD 需要克隆包含清单文件的 Git 仓库,检测期望状态与实际状态之间的差异,并应用必要的更改以纠正配置偏差。然而,当需要在多个团队和集群(开发、测试、生产)中扩展这一流程时,复杂性随之增加,必须依赖复杂的编排和管理机制。

为有效应对这些挑战,Argo CD 架构划分为几个关键组件:

  • API 服务器:处理用户交互和身份认证
  • 仓库服务器:管理 Git 操作和清单生成
  • 应用控制器:负责状态对齐和部署
  • Redis:提供缓存功能以提升性能
  • Dex 服务器:支持与外部身份提供者的身份认证集成
  • 通知控制器:负责向外部系统发送部署状态和事件的通知

下面让我们详细了解这些组件,探讨它们如何协同工作以实现可扩展的 GitOps 实践。

API 服务器

API 服务器是一个 gRPC/REST 服务,向 Web UI、CLI 和 CI/CD 系统暴露 API。它负责应用管理和状态报告,并响应外部 UI 或 CLI 发起的应用操作请求(如同步、回滚及用户自定义操作)。同时,API 服务器负责生成并返回 Kubernetes 清单文件。它还提供仓库和集群凭据管理的 API。

该组件将认证和授权委托给外部身份提供者,并实施基于角色的访问控制(RBAC)。我们可以通过其 Swagger UI(基于 Web 的 API 文档界面)查看所有 API,Swagger UI 提供了一个交互式界面,用于探索和测试 Argo CD 的 API。

启动端口转发命令:

bash 复制代码
kubectl port-forward svc/argocd-server -n argocd 8080:443

然后通过浏览器访问:http://localhost:8080/swagger-ui (见图 2.5)。

API 服务器的一个重要职责是监听并转发 Git webhook 事件。

你可以克隆并在本地运行 Argo CD 的 API 服务器以深入了解它:

bash 复制代码
git clone https://github.com/argoproj/argo-cd.git
cd argo-cd
make build
cd dist
./argocd-server -h

简要输出示例:

bash 复制代码
Usage:
  argocd-server [flags]
  argocd-server [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  version     Print version information

Flags:
      --app-state-cache-expiration duration           Cache expiration for app state (default 1h0m0s)

仓库服务器(Repository server)

仓库服务器是承担大量核心工作的重要组件之一。它负责将 Git 仓库克隆到本地存储,并生成可直接使用的 Kubernetes 清单 YAML 文件。虽然克隆仓库本身是简单的任务,但为了避免重复下载仓库,Argo 仓库服务器实现了本地缓存机制,并支持 Git fetch 功能,仅下载远程仓库中的最新变更。

不过,保持仓库大小合理是用户的责任。GitOps 的最佳实践建议将应用源代码与部署清单分离,部署仓库应尽可能小,避免占用过多磁盘空间。

另一个仓库服务器需要管理的挑战是内存利用率,尤其是在生成清单时。以下是用户可调优的几个方向:

  • 开发者通常偏好使用配置管理工具,如 Kustomize、Helm 或 Jsonnet。这些工具能有效引入变更,避免 YAML 内容重复。因此,部署仓库中通常不是简单的 YAML 文件。Argo CD 支持即时生成清单。
  • Argo CD 支持多种配置管理工具,也允许配置其他自定义工具。
  • 在清单生成期间,仓库服务器会运行配置管理工具,返回生成的清单文件,这通常会消耗较多内存和 CPU。
  • 为解决内存压力,Argo CD 允许用户减少并行清单生成的数量,并通过增加仓库服务器实例数提升性能。
  • Argo CD 操作人员需根据需求调整 repo-server 副本数量,确保快速生成清单。

应用控制器(Application controller)

"控制器"是指一种控制循环(control loop),它是一个不终止的循环,用于调节系统状态,常见于机器人和自动化领域。在 Kubernetes 中,控制器至少追踪一种 Kubernetes 资源类型。由于 Argo CD 在 Kubernetes 内运行且负责 Kubernetes 上的部署,故其采用 Kubernetes 控制器模式。argocd-application-controller 组件实现了状态对齐(reconciliation)阶段。

控制器会加载当前 Kubernetes 集群的状态,与由 argocd-repo-server 提供的期望清单进行对比,并修补偏离期望状态的资源。GitOps 操作人员需要从集群中获取每个资源,比较并准确更新需要变更的部分,这是最具挑战性的工作之一。

控制器使用轻量级缓存管理每个集群状态,并通过 Kubernetes 的 Watch API 在后台更新所有状态。

这些数据存储在 Redis 集群中,方便快速呈现给用户。通过数据缓存,控制器能够实现多集群的横向扩展,高效执行应用的状态对齐。

简而言之,应用控制器是一个 Kubernetes 控制器,持续追踪运行中的应用,将实际状态与仓库中定义的目标状态对比,识别 OutOfSync(不同步)状态,并在必要时启动纠正操作。它还负责调用用户定义的生命周期钩子(如 PreSync、Sync、PostSync)。

请继续阅读本书中关于 Argo CD 概念与术语的章节,深入了解 Argo。

Argocd 服务器(argocd-server)

Argo CD 架构中的最后一个关键组件是 argocd-server ,它负责将状态对齐(reconciliation)的结果展示给终端用户。虽然大部分工作已由 argocd-repo-serverargocd-application-controller 完成,但最终阶段对系统的稳定性和可靠性要求最高。该组件负责加载对齐结果信息,Web 用户界面本身是无状态服务。

Argo CD Dex

Dex 是一款使用 OpenID Connect(OIDC)驱动认证的身份服务,Argo CD 内部通过 Dex 实现用户认证。了解 Argo CD 使用的组件对操作人员后续排查问题非常关键。

Argo CD 安装时会内嵌并打包 Dex,允许将认证委托给第三方身份服务。支持多种身份提供者,包括 OpenID Connect(OIDC)、LDAP、SAML、GitHub 等。

尽管掌握了这一关键组件的原理,我们仍需熟悉一些额外的概念和术语。

ApplicationSet 控制器

ApplicationSet 控制器不是 Argo CD 一开始就具备的组件,它与现有的 Argo CD 协同工作。该控制器允许使用单个 Kubernetes 清单同时针对多个 Kubernetes 集群,增强了对单一仓库(mono repo)的支持。

它还提升了团队在多租户集群中使用 Argo CD 部署应用的能力,无需提升权限。第 3 章《在生产环境中运行 Argo CD》有专门章节介绍 ApplicationSet 控制器。

通知(Notifications)

Argo CD Notifications 提供了一种可定制的机制,用于在持续监控 Argo CD 应用状态时,向用户发送应用状态的重大变化警报。

用户可以通过灵活的触发器和模板框架设置通知的时机和内容。Argo CD Notifications 自带丰富的触发器和模板列表,用户可以直接使用,无需重新创建。

Argo CD 概念与术语

本书假设读者已熟悉 Git、Docker、Kubernetes、持续交付和 GitOps 的基础知识。以下是读者需要立即了解的 Argo CD 相关核心内容。

应用(Application)

应用是一个自定义资源定义(Custom Resource Definition,CRD)。Argo CD 的核心是 Application CRD。这个基本概念定义了 Argo CD 如何将源 Git 仓库与目标 Kubernetes 集群连接起来。

目标(destination)是 Kubernetes 服务器及其目标命名空间。argocd 控制器会监测这个 CRD,并根据其中的信息执行操作,例如:

yaml 复制代码
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 source type)

Argo CD 不仅支持普通的 YAML 文件,还支持使用 Helm、Kustomize、Jsonnet 等清单生成工具。Argo CD 用来生成清单的工具称为"应用源类型"。

Argo CD 域中应了解的基本概念和术语

  • 目标状态(Target state) :应用的期望状态,由 Git 仓库中的文件表示。
  • 实时状态(Live state) :应用的当前运行状态,指目标集群中实际运行的 Pod 和其他 Kubernetes 资源。
  • 同步状态(Sync status) :表示期望状态与实时状态是否一致。部署的应用应与 Git 中定义的保持一致。同步状态可能为"已同步"、"不同步"或"同步中"。
  • 同步(Sync) :应用为达到期望状态而执行的操作,例如修改 Kubernetes 集群中的资源。

Argo CD 声明式配置

此时,读者应掌握 Argo CD 的核心概念。本书开篇时曾提及声明式和命令式配置,至今我们一直使用 CLI 进行命令式部署。

本节将探讨如何使用 Kubernetes 清单以声明式方式定义 Argo CD 的应用(Applications)、项目(Projects)及相关设置。定义完成后,可以通过 kubectl apply 应用它们,或使用另一个 Argo CD 进行同步!听起来是不是有点"先有鸡还是先有蛋"的问题?请继续往下看。

Argo CD 只定义了少数几个自定义资源(CRD)。它通过 CRD 扩展了 Kubernetes API。运行命令 kubectl get crd -n argocd 可以列出 Argo CD 在 argocd 命名空间中创建的所有 CRD。其余设置则通过 Secret 和 ConfigMap 管理:

arduino 复制代码
kubectl get crd -n argocd

输出示例:

lua 复制代码
NAME                          CREATED AT
applications.argoproj.io      2022-09-17T18:45:31Z
applicationsets.argoproj.io   2022-09-17T18:45:32Z
appprojects.argoproj.io       2022-09-17T18:45:32Z

Argo CD 控制器会监视这些 CRD 对象的新增、删除或修改。我们从项目(Project)开始讲起。

项目(Projects,Kind: AppProject)

AppProject 是 Argo CD 引入的 Kubernetes 资源,用于表示应用的逻辑分组,因为 Argo CD 支持同时管理多个应用。AppProject 规范示例如下:

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: my-project
  namespace: argocd
  # finalizer 确保项目被引用时不被删除
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  description: Example Project
  # 允许从任意 Git 仓库部署清单
  sourceRepos:
  - '*'
  # 只允许部署到同一集群的 guestbook 命名空间
  destinations:
  - namespace: guestbook
    server: https://kubernetes.default.svc
  # 禁止创建除 Namespace 以外的所有集群级资源
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace
  # 禁止创建以下命名空间级资源
  namespaceResourceBlacklist:
  - group: ''
    kind: ResourceQuota
  - group: ''
    kind: LimitRange
  - group: ''
    kind: NetworkPolicy
  # 允许创建以下命名空间级资源
  namespaceResourceWhitelist:
  - group: 'apps'
    kind: Deployment
  - group: 'apps'
    kind: StatefulSet
  roles:
  # 定义只读权限角色
  - 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
  # 定义只针对 guestbook-dev 应用的同步权限角色
  - name: ci-role
    description: Sync privileges for guestbook-dev
    policies:
    - p, proj:my-project:ci-role, applications, sync, my-project/guestbook-dev, allow
    jwtTokens:
    - iat: 1535390316

简要说明关键部分:

  • sourceRepos:指定项目允许使用的 Git 仓库。
  • destinations:定义可部署的目标集群和命名空间。
  • roles:定义项目内不同角色的权限和访问范围。

应用(Applications,Kind: Application)

Application CRD 非常简单,最少需要提供关联的项目名称。
source 定义 Git 仓库中应用的期望状态(包含 Kubernetes 清单或 Kustomize、Helm、Jsonnet 等),destination 指向目标集群和命名空间,还可以配置仓库版本(revision)、路径(path)等。

示例:

yaml 复制代码
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

其余信息通过 Secret 和 ConfigMap 管理:

arduino 复制代码
kubectl get secret -n argocd
kubectl get configmap -n argocd

仓库、集群及 Helm 仓库凭据

仓库、集群和 Helm 仓库的凭据及详细信息存储于 Kubernetes Secret 中。配置仓库时需创建包含相应详情的 Secret,其他类型资源同理。详细说明见官方文档:argo-cd.readthedocs.io/en/stable/o...

本书示例配置文件位于路径 ../argo/resources/argocd/declarative/。创建项目和应用:

复制代码
kubectl apply -f project.yaml
kubectl apply -f application.yaml
kubectl apply -f argocd-cm.yaml

argocd-cm.yaml 用于注册 Argo CD 中支持的 Kustomize 版本。近期 Argo CD 已支持按应用指定不同的 Kustomize 版本。详情见 PR:github.com/argoproj/ar...


配置完成后,Argo CD 可根据你定义的凭据和设置访问并管理你的仓库、集群和 Helm charts。声明式配置允许你将 Argo CD 配置与应用代码一起版本管理,遵循 GitOps 最佳实践。

结合使用 Secret 存储敏感数据(如仓库凭据)与 ConfigMap 管理配置信息,为 Argo CD 与外部资源的交互提供了灵活且安全的方式。随着部署需求增长,可方便地用同样的 Kubernetes 原生方法增删改配置。

请注意,本节涵盖的是基础配置,Argo CD 还支持更复杂的场景配置,如多集群管理、使用 SSH 密钥访问仓库、为私有仓库配置自定义证书等,这些也都能通过声明式方式完成。

掌握项目、应用及配置管理基础后,下一步将探讨如何高效使用 Argo CD 实现生产环境的持续部署。

总结

本章向读者介绍了 Argo CD 以及两种编程范式:命令式(imperative)和声明式(declarative)。

首先,读者体验了一个正在运行的 Argo CD 实例,学习了如何在 minikube 中部署 Argo CD,并熟悉了 Argo CD 的 CLI 和 UI。

本章还提供了 Argo CD 的架构概览以及相关术语和概念介绍。最后,展示了一个声明式 Argo CD 安装的示例操作流程。

下一章,我们将讨论生产环境下 Argo CD 的安装方案及一些使用 Argo CD 管理部署的策略。

相关推荐
Auv开心7 小时前
【git stash切换】
经验分享·git
swbook13 小时前
CentOS8.3+Kubernetes1.32.5+Docker28.2.2高可用集群二进制部署
linux·运维·kubernetes
Twilight-pending14 小时前
K8s工作流程与YAML实用指南
云原生·容器·kubernetes
星霜旅人15 小时前
【Linux】Git原理与使用
git
半吊子运维16 小时前
k8s node 修改挂载点操作指导手册
kubernetes
zhangphil17 小时前
git reset --hard HEAD~1与git reset --hard origin/xxx
git
格格巫ZYX18 小时前
Git GitHub Gitee
git·gitee·github
!Polaris20 小时前
【git-首次初始化本地项目、关联远程仓库】
git
mosaicwang21 小时前
创建ipv6 only和ipv6+ip4的k8s集群的注意事项
云原生·容器·kubernetes
孔令飞21 小时前
经典面试题:一文了解常见的缓存问题
缓存·ai·云原生·面试·golang·kubernetes