ArgoCD 部署使用

ArgoCD 是目前 Kubernetes 生态中最流行的 GitOps 持续交付(CD)工具。它的核心理念是将 Git 仓库视为集群状态的“唯一真理来源”。

ArgoCD 的核心工作原理

  • 声明式管理 :你不在集群里手动运行 kubectl ,而是将所有的资源清单(YAML、Helm、Kustomize)存放在 Git 中管理。

  • 同步与漂移检测 :ArgoCD 会持续监控 Git 仓库和 EKS 集群。如果两者状态不一致(即发生“漂移”),它会报警或自动将集群恢复到 Git 定义的状态。

Argo CD 核心概念说明

ArgoCD Application 删除时的 Propagation Policy

在 Argo CD 中,当你删除一个 Application 时,Propagation Policy(传播策略) 决定了该应用下属的 Kubernetes 资源(如 Deployment, Service, ConfigMap 等) 应该如何处理。本质上是调用了 Kubernetes API 的删除机制,Argo CD 利用 K8s 的 Finalizer 机制来实现这一逻辑

策略名称 行为描述 结果
Foreground Cascade(前台级联) 最常用。先删除子资源,最后删除 Application 本身。 集群资源被彻底清理,最安全。
Background Cascade(后台级联) 立即删除 Application,子资源在后台由 K8s 垃圾回收机制静默删除。 最终结果同上,但 Application 对象消失得更快。
Orphan (Non-cascading ,孤儿模式) 只删壳,不删内容。只删除 Application 对象,保留集群里的实际资源。 资源继续运行,不再受 Argo CD 管控。
这通常用于 迁移场景 :你只想让 Argo CD 不再管这个应用,但不想让业务停掉。

在 Kubernetes 集群中安装 ArgoCD

# kubectl create namespace argocd
namespace/argocd created

# kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml --server-side
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io serverside-applied
serviceaccount/argocd-application-controller serverside-applied
...
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy serverside-applied
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy serverside-applied
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy serverside-applied
networkpolicy.networking.k8s.io/argocd-redis-network-policy serverside-applied
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy serverside-applied
networkpolicy.networking.k8s.io/argocd-server-network-policy serverside-applied

  • --server-side 选项用于解决可能的报错: The CustomResourceDefinition "applicationsets.argoproj.io" is invalid: metadata.annotations: Too long: may not be more than 262144 bytes

等待 ArgoCD 相关 Pod 运行正常

# kubectl get pods -n argocd
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 6m11s
argocd-applicationset-controller-77475dfcf-qzvsf 1/1 Running 1 (3m47s ago) 6m15s
argocd-dex-server-6485c5ddf5-4ms4f 1/1 Running 0 6m14s
argocd-notifications-controller-758f795776-4n5rb 1/1 Running 0 6m14s
argocd-redis-6cc4bb5db5-svpwm 1/1 Running 0 6m13s
argocd-repo-server-c76cf57cd-pv8sb 1/1 Running 0 6m12s
argocd-server-6f85b59c87-zhmqh 1/1 Running 0 6m12s

创建 Ingress 对外开放 ArgoCD UI,本示例中 IngressClass 为 AWS alb

argocd_ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd
namespace: argocd
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip

spec:
ingressClassName: alb
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80


创建并检查 Ingress

# kubectl apply -f argocd_ingress.yml 
ingress.networking.k8s.io/argocd configured

# kubectl get ingresses -A
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
argocd argocd alb argocd.example.com k8s-argocd-argocd-8e8cb.ap-east-1.elb.amazonaws.com 80 8m22s

ArgoCD Pod 强制开启了 TLS (HTTPS),而 ALB 却在使用 HTTP 进行健康检查。会因为健康检查失败无法访问

在集群中的 Pod 中尝试请求 argocd-server Pod 的地址,可以看到默认返回了重定向到 HTTPS 的响应,ALB 会因为证书问题对 Pod 健康检查失败

# curl -Iv 172.31.68.215:8080
> HEAD / HTTP/1.1
> Host: 172.31.68.215:8080
> User-Agent: curl/8.18.0
> Accept: */*
>

HTTP/1.1 307 Temporary Redirect
Location: https://172.31.68.215:8080/


可以配置 ArgoCD 接受 HTTP 协议请求。 修改 ArgoCD Server 启动参数 ,执行命令 kubectl edit deployment argocd-server -n argocd 编辑 argocd-server 的 Deployment,在启动命令( command )中添加 --insecure 参数。

containers:
- args:
- /usr/local/bin/argocd-server
- --insecure

修改后等待 Pod 自动重启

$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
argocd argocd-server-6ff754765c-pt5z6 0/1 Running 0 18s

再次观察 ALB 的 Target 健康检查状态

ArgeCD 可以正常访问后,执行以下命令获取初始 admin 账户的密码

kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d

ArgoCD UI 常用操作

创建 Project

Project 可以实现资源或者 APP 的逻辑隔离,可以通过 Project 限制 APP 对以下资源的使用:

  • SOURCE REPOSITORIES :限制该 Project 下的 Application 只能从指定的 Git Reop 或者 Helm 仓库拉取配置(Manifest)。防止越权拉取。
  • SCOPED REPOSITORIES : 只允许属于 Project 的 APP 从指定的 Reop 拉取代码(Manifest)
  • DESTINATIONS / SCOPED CLUSTERS: 限制属于 Project 的 APP 只能部署到指定的 Kubernetes 集群((Server URL/Name))和 Namespace。支持通配符。例如限制只能部署到 in-clusterdev-* 命名空间。
  • cluster resource allow list / cluster resource deny list : Kubernetes Cluster 范围内允许/拒绝使用的资源,针对 非命名空间资源(如 ClusterRole, CustomResourceDefinition, Namespace, StorageClass)
  • namespace resource allow list / namespace resource deny list : Namespace 范围的资源限制/允许,针对 命名空间资源(如 Deployment, Service, Secret, ConfigMap)

多用户与权限控制

Argo CD 有两个核心组件控制权限:

  • argocd-server(认证)

  • argocd-rbac-cm(授权)

Argo CD 支持三种用户方式

  1. 本地用户(不推荐生产)

  2. SSO(推荐生产) ,支持:

    • GitHub

    • GitLab

    • Azure AD

    • Google

    • OIDC

    • LDAP

    • Okta

    • Keycloak

  3. Kubernetes RBAC 模式(高级) 。可以让 ServiceAccount 调用 Argo API。

使用配置文件批量管理 ArgoCD APP

在 ArgoCD 的实践中, Root App(根应用) 模式通常被称为 App of Apps(应用集应用) 模式。它是管理大规模 Kubernetes 集群和多租户环境的核心架构方案。

简单来说,与其在 ArgoCD 界面上手动一个个创建应用,不如创建一个 Root App(父应用) ,由它来自动管理和同步所有的 Application(子应用)

在 Kubernetes 中,ArgoCD 的一切配置都是资源(CRD)。一个 Application 资源的 YAML 定义了:

  • Source: 代码仓库地址、路径、分支。

  • Destination: 目标集群和命名空间。

Root App 的逻辑是:建立一个特殊的 Root Application ,它的 Source 指向一个存放了多个子应用(Application) YAML 文件的 Git 目录。当 Root App 同步时,它会在集群中生成这些子应用资源,随后 ArgoCD 监听到这些新生成的子应用,进而去同步具体的业务代码。

为什么需要 Root App?

  • 声明式管理 (GitOps) :所有的应用配置都在 Git 中。如果你想增加一个微服务,只需在 Git 里加一个 Application YAML 文件,Root App 会自动感知并创建。

  • 灾备恢复 :如果 ArgoCD 挂了或需要迁移,你只需要手动部署这一个 Root App,它会像树根一样带出整棵应用的“树”。

  • 应用权限控制 :管理员只需要把控 Root App 的权限,普通开发人员在指定目录下提交代码即可。

创建 Root App

推荐 Git 仓库结构如下:

.
├── apps # 存放 ArgoCD Application 的定义文件以及应用负载(如 Deployment, Service, ConfigMap 等)的配置文件
│   ├── infrastructure # 存放基础设施及运维基本应用的配置文件
│   │   ├── cert-manager
│   │   │   ├── app.yaml
│   │   │   ├── manifests
│   │   │   │   └── cert-manager.crds.yaml
│   │   │   └── values.yaml
│   │   ├── confluence
│   │   │   ├── app.yaml # 定义 ArgoCD Application 的 YAML 文件,在 ArgoCD Root App 中配置仅同步 “*/*/app.yaml” 文件。其他资源文件(如 manifests/deploy.yaml)由 app.yaml 定义的 ArgoCD Application 管理,不会被 ArgoCD Root App 同步。
│   │   │   └── manifests
│   │   │   └── deploy.yaml # 定义应用负载的 YAML 文件,如 Deployment, Service, ConfigMap 等,由 app.yaml 中定义的 ArgoCD Application 管理。
│   │   ├── harbor
│   │   │   └── app.yaml
│   │   ├── kubernetes-metrics-server
│   │   │   └── app.yaml
│   │   ├── postgresql
│   │   │   └── app.yaml
│   │   └── rancher
│   │   └── app.yaml
│   └── project # 存放项目应用的配置文件
└── bootstrap
├── argocd_ingress_alb.yaml
├── argocd_install.yaml
├── aws-ebs-gp3-storageclass.yaml
└── root-app.yaml # 定义 ArgoCD Root App 的 YAML 文件,每次更改后需要 kubectl apply -f root-app.yaml 来同步。ArgoCD Root App 递归管理同步 apps 目录下的所有 Application 定义文件(“*/*/app.yaml”)。


Root App 的 YAML 定义如下:

apiVersion: argoproj.io/v1alpha1
kind: Application

metadata:
name: root-app
namespace: argocd

spec:
project: default

source:
repoURL: https://github.com/argo-gitops/argo-gitops.git

targetRevision: main

path: argocd/apps # 指向 apps 目录,递归包含所有的 ArgoCD Application 定义文件

directory:
recurse: true # 递归扫描 path: argocd/apps 目录下的所有目录,配合 include 查找 "*/*/app.yaml" 文件作为 Application 定义。
include: "*/*/app.yaml" # 在递归子目录中,只查找 "*/*/app.yaml" 文件作为 Application 定义。这样可以在同一个目录下定义 ArgoCD Application(app.yaml),然后同样在此目录下定义其他资源文件并通过 ArgoCD Application(app.yaml) 进行管理。否则 ArgoCD 会产生告警:SharedResourceWarning(资源同时被 ArgoCD Root App 和应用 ArgoCD Application 管理)


destination:
server: https://kubernetes.default.svc
namespace: argocd

syncPolicy:
automated:
prune: true
selfHeal: true


手动部署 Root App

kubectl apply -f argocd/bootstrap/root-app.yaml

ArgoCD 会创建 Root App 资源,随后会根据 YAML 定义自动创建所有的子应用资源。

子应用资源只需在 argocd/apps/infrastructure 目录下创建即可。例如创建 cert-manager 应用:

app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application

metadata:
name: cert-manager
namespace: argocd

spec:
project: default

source:
repoURL: https://charts.jetstack.io

chart: cert-manager

targetRevision: v1.18.2

helm:
valueFiles:
- values.yaml

destination:
server: https://kubernetes.default.svc
namespace: cert-manager

syncPolicy:
automated:
prune: true
selfHeal: true

syncOptions:
- CreateNamespace=true

将代码提交到 Git 仓库后,ArgoCD 会自动感知 spec.source.path (本示例为 argocd/apps/ )下的(递归)目录并创建相应的应用,比如 cert-manager 。在成熟的生产环境下,基本不会手动点击 “Create App”,而是通过维护一个 Git 仓库,利用 Root App 模式实现“配置即代码”的全自动化运维。

ArgoCD 的 spec.source.path 只能配置一个目录路径; recurse 只能向下递归该目录, 不能跨目录 (例如同时扫 argocd/infrastructureargocd/projects

Terraform 和 ArgoCD 自动化部署 EKS 集群以及常用应用的 Github 仓库 ,包括以下内容:

  • Terraform 配置 EKS Auto Mode 集群

  • ArgoCD 部署到 EKS 集群

  • ArgoCD Root App 配置

  • 常用应用的 YAML 定义

    • cert-manager
    • rancher
    • kubenetes-metrics-server
    • Harbor
    • postgresql
    • Confluence 破解版,依赖于数据库 postgresql
    • Prometheus Stack 监控 EKS