3. 项目级准入策略的配置入口:Argo CD Project CRD 结构、spec 字段详解、policy 字段的定位与作用
在 Argo CD 的多租户架构中,项目(Project)是资源隔离与安全策略的核心边界。所有准入控制规则最终都附着在 AppProject 自定义资源(CRD)之上。理解该 CRD 的结构,尤其是 spec 与 policy 字段,是设计项目级准入策略的第一步。
3.1 AppProject CRD 顶层结构
一个标准的 AppProject 资源由以下顶层字段构成:
| 字段 | 类型 | 说明 |
|---|---|---|
apiVersion |
string | 固定为 argoproj.io/v1alpha1 |
kind |
string | 固定为 AppProject |
metadata |
ObjectMeta | 项目名称、命名空间(通常为 argocd)、标签、注解 |
spec |
AppProjectSpec | 核心配置区,包含所有准入策略与资源约束 |
关键认知: Argo CD 的 RBAC 控制“谁可以操作项目”,而
spec 中的策略控制“项目内允许部署什么”。两者互补,缺一不可。
3.2 spec 字段详解:准入策略的载体
spec 字段是 AppProjectSpec 类型,它承载了项目级准入策略的全部配置。以下是与准入控制直接相关的核心字段:
| 字段名 | 类型 | 准入控制作用 |
|---|---|---|
sourceRepos |
[]string | 允许的 Git 仓库 URL 列表(支持通配符) |
destinations |
[]ApplicationDestination | 允许的目标集群与命名空间(server/namespace 白名单) |
clusterResourceWhitelist |
[]metav1.GroupKind | 允许部署的集群级别资源类型白名单 |
clusterResourceBlacklist |
[]metav1.GroupKind | 禁止部署的集群级别资源类型黑名单 |
namespaceResourceWhitelist |
[]metav1.GroupKind | 允许部署的命名空间级别资源类型白名单 |
namespaceResourceBlacklist |
[]metav1.GroupKind | 禁止部署的命名空间级别资源类型黑名单 |
orphanedResources |
OrphanedResourcesMonitorSettings | 是否监控并警告项目内的孤儿资源 |
syncWindows |
[]SyncWindow | 同步时间窗口策略(禁止/允许时段) |
roles |
[]ProjectRole | 项目级 RBAC 角色定义(JWT 令牌与策略绑定) |
policy |
string | 内联 CUE/JSON 策略引擎规则 |
设计原则: 白名单优先于黑名单。在多数生产环境中,建议先配置
whitelist 明确允许的资源,再通过 blacklist 补充例外禁止项,避免因遗漏导致安全漏洞。
3.3 policy 字段的定位与作用
policy 字段是 Argo CD 2.6+ 引入的可编程准入策略引擎入口。它允许运维人员使用 CUE 语言或 JSON 格式编写自定义校验规则,对 Application 的 spec 进行深度校验。
3.3.1 定位:从静态配置到动态策略
- 传统方式:通过
sourceRepos、destinations、whitelist/blacklist做粗粒度静态过滤。 - policy 方式:允许对 Application 的任意字段(如
spec.source.helm.values、spec.syncPolicy)编写条件规则,实现细粒度动态准入。
3.3.2 作用:三大核心能力
| 能力 | 说明 | 示例场景 |
|---|---|---|
| 字段值校验 | 检查 Application 中特定字段的值是否符合预期 | 禁止 syncPolicy.automated.prune 为 true |
| 跨字段约束 | 校验多个字段之间的逻辑关系 | 若 destination.namespace 为 production,则必须设置 syncPolicy |
| 环境感知规则 | 根据目标集群或命名空间动态调整策略 | 生产集群禁止使用 latest 镜像标签 |
注意:
policy 字段的规则在 Application 创建或更新时由 Argo CD API Server 执行。规则失败会直接拒绝请求,不会创建或更新 Application。务必在测试环境充分验证 CUE 语法。
3.4 配置入口关系图
下图展示了 AppProject CRD 中准入策略的配置入口层级关系:
3.5 policy 字段的配置示例
以下是一个使用 CUE 语言编写的 policy 示例,它实现了两个准入规则:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production-apps
namespace: argocd
spec:
sourceRepos:
- 'https://git.internal.company.com/*'
destinations:
- namespace: 'prod-*'
server: 'https://kubernetes.default.svc'
# 内联策略引擎规则
policy: |
// 规则1:禁止在生产命名空间中使用 latest 镜像标签
if application.spec.source.targetRevision == "latest" {
if application.spec.destination.namespace =~ "^prod-" {
deny: "不允许在生产环境使用 latest 镜像标签"
}
}
// 规则2:若启用了自动同步,必须同时设置 prune=false
if application.spec.syncPolicy?.automated != _|_ {
if application.spec.syncPolicy.automated.prune == true {
deny: "自动同步时禁止启用 prune,请手动确认后再操作"
}
}
clusterResourceWhitelist:
- group: '*'
kind: 'Namespace'
namespaceResourceBlacklist:
- group: 'rbac.authorization.k8s.io'
kind: 'ClusterRoleBinding'
最佳实践: 将
policy 字段的 CUE 规则视为代码,纳入 Git 仓库进行版本管理。建议在 CI 流水线中使用 cue vet 命令预校验规则语法,避免语法错误导致整个项目无法创建 Application。
3.6 静态策略与动态策略的对比
| 对比维度 | 静态策略(spec 字段) | 动态策略(policy 字段) |
|---|---|---|
| 校验粒度 | 资源来源、目标、类型 | Application 任意字段 |
| 表达能力 | 白名单/黑名单匹配 | 条件判断、跨字段约束、正则匹配 |
| 维护复杂度 | 低(声明式列表) | 中高(需掌握 CUE 语法) |
| 适用场景 | 基础隔离、租户边界 | 合规检查、安全加固、环境差异化 |
| 执行时机 | Application 创建/更新时 | Application 创建/更新时 |
在实际架构设计中,静态策略应作为第一道防线,快速拦截明显不合规的请求;动态策略作为第二道防线,处理需要业务逻辑判断的复杂场景。两者配合使用,才能构建完整的项目级准入策略体系。