云原生
平台团队可以从 Crossplane v2.2 中期待什么
Crossplane v2.2 指南:管道调试、元数据校验、依赖感知的运行时配置,以及对构建 Kubernetes 控制平面的影响。
Ivan Porta
创始人兼 Principal Engineer

Crossplane 是一个通过 Kubernetes API 管理云基础设施的 CNCF 控制平面,它像 Kubernetes 协调 Pod 那样持续协调你声明的资源;v2.2 是一个瞄准生产短板的版本,加入了 alpha 阶段的 Pipeline Inspector、可作用于 spec 之外的 CEL 校验,以及依赖感知的运行时配置。当基础设施应当成为平台 API 时用它;如果 plan-and-apply 就够了,选 Terraform。
开发者提交一张工单申请一个数据库。三天后,平台团队回复了,但配置不太对。开发者再开一张工单,再等。到了第三周,数据库可能才终于就绪。这套循环在每一支团队和每一个环境里都在重复,造就了大多数平台团队都熟悉的日常:开发者把大量时间花在等待基础设施上,平台团队则疲于应付源源不断的请求。
可用于资源置备的好工具有很多。Terraform 与平台无关,使用很广泛。CloudFormation 是 AWS 上的首选,每家云厂商也都提供自家的控制台和 CLI。每个工具都把自己的活儿干得不错。这篇文章不是为了挑出哪个最好,而是换一个角度看这个问题。
Crossplane 提供了一种以 Kubernetes 为原生的方式来管理云资源。它不在集群外面单独搭基础设施再回连过来,而是把这些基础设施纳入和你的应用相同的控制循环。这与许多团队当下的工作方式自然契合。配合 GitOps,Pull Request 就成了变更管理的主要入口,集群会持续向期望状态收敛。
过去一年这个项目进展很快。2025 年 8 月,Crossplane v2 引入了不小的改动,例如移除 Claims、加入命名空间作用域的 Composite 与 Managed Resource。最新版本 v2.2 又增加了一个处于 alpha 阶段、用于排错的 Pipeline Inspector,更广覆盖的 CEL 校验,以及若干其他改进。
Crossplane 实际上是什么?
Crossplane 是面向平台工程的控制平面框架。你把它装进一个被称为管理集群的 Kubernetes 集群,这个集群就成了集群外一切事物的控制平面:云账户、SaaS API、内部工具,乃至其他 Kubernetes 集群。这一切都通过你的应用已经在用的同一套 Kubernetes API 来管理。管理集群本身要单独搭好,Crossplane 不会替你创建。Crossplane 一旦运行起来,就既没有状态文件也没有独立工作流。漂移由那条让 Deployment 保持健康的相同协调循环来纠正。
Crossplane 有四个主要组件。你可以全部用上,也可以只用需要的。
-
**Managed Resources(MR)**是直接对应外部云资源的 Kubernetes 对象。例如,AWS 的 S3 或 Azure 的 ResourceGroup 都被视作 MR。Crossplane 以
spec.forProvider为主参考,让真实的云资源与之保持同步。MR 通过 kubectl 创建,置备和协调由 provider 处理。 -
Composition 让你用一条函数管道来构造自定义 API。需要理解的核心有三件事:
CompositeResourceDefinition(XRD)定义模式(schema)。它在告诉 Kubernetes:「这是我要新建的一种自定义 API kind,这些是它的字段。」可以把它看作给 Crossplane 加了若干特性的 CRD。Composition像一份配方。它说:「当有人创建一个 kind 为 Foo 的 XR 时,运行下面这组函数来创建这些 MR 或其他 Kubernetes 资源。」在 v2 里,它总是使用一条函数管道。Composite Resource(XR)是你用 XRD 定义出的那个 API 的实例。当用户创建一个 XR 时,Crossplane 会用与之匹配的 Composition 的管道来生成所需的资源。函数可以用 YAML、KCL、Python 或 Go 编写。
-
Operations 像 Kubernetes Job 一样,把函数管道执行到完成。有三种模式:Operation(一次性)、CronOperation(按计划)、WatchOperation(事件驱动)。Operations 目前为 alpha 阶段。
-
包管理器负责安装和升级 provider、configuration 和 function。
Crossplane 请求是怎样流动的
根据你提交的对象不同,这条流程有两个入口。
当开发者或流水线在某个命名空间里创建一个 XR 时,composition 引擎会监听它,运行配置好的函数管道,并创建所需的资源。这些资源可以是其他 Kubernetes 资源、managed resource,或两者的组合。
当用户直接(单独地或作为某个 Composition 的一部分)apply 一个 MR 时,由 provider 接管。它通过 Kubernetes API 监控这个 MR,调用外部系统去创建或更新真实资源,然后更新状态。之后它会持续巡检:如果真实资源相对 spec.forProvider 发生了变化,provider 就把它修回来。所有状态都存在 etcd 里,因此没有独立的状态文件。
何时反而该用传统 IaC?
Crossplane 与 Terraform、CloudFormation 之类的工具在覆盖范围上有重叠(都能给你创建一个云数据库),但做法不同。正确的选择,取决于你的平台已经落在哪儿。
| 能力 / 特性 | Terraform | CloudFormation | Crossplane |
|---|---|---|---|
| 控制循环 | 手动 apply(或流水线) | 手动创建/更新 stack | 持续协调 |
| 漂移处理 | 用 plan 检测,手动修正 | 漂移检测动作,通过 stack 更新修正 | 自动检测并自动修正 |
| 状态 | 由你保护的远端后端中的 tfstate(如启用版本控制的 S3、HCP Terraform) | 由 AWS 管理(服务端) | 管理集群 etcd 中的 Kubernetes API 对象 |
| 工作流 | 与应用部署分离 | 与应用部署分离 | 与 kubectl apply 一致 |
| 抽象 | Module | Nested Stack、Module | XRD + Composition + 函数 |
| 语言 | HCL、JSON | YAML、JSON | YAML、Go、Python、KCL、CUE、HCL(通过 composition 函数) |
| 内置策略 | 变量校验和前/后置条件(OSS);HCP Terraform / Enterprise 中的 Sentinel 与 OPA 集成 | cfn-guard、Hooks | XRD CEL 校验(v2.2 起含 metadata) |
| 多云 | 每朵云一个 provider,状态各自独立 | AWS 优先(第三方类型通过 CloudFormation 注册表接入) | 一个控制平面,一套 API 表面 |
| 体积 | 一个二进制 | AWS 托管服务(仅 CLI/SDK) | 由 etcd 支撑的 Kubernetes 控制平面(Crossplane 核心、provider、function) |
| 在 Kubernetes 之外运行 | ✓ | ✓ | ✕(需要一个管理集群) |
如果你的团队不用 Kubernetes,那 Crossplane 不是合适的起点;Terraform 更简单,也不需要控制平面。但如果你们已经在用 Kubernetes,尤其是已经在用 Argo CD 或 Flux,那么用同一种方式去管基础设施会很顺手。在「以代码定义基础设施、并把它当作其余声明式集群状态那样去对待」这件事上,Crossplane 是最接近的选项。
v2.2 带来了什么新东西?
v2.2 加了五项你在实际使用中会立刻注意到的功能,外加两项默默提升可靠性的改动。每一项都补上了平台团队在生产里一直碰到的某个具体短板。
-
Pipeline Inspector(alpha):
Composition的函数功能强大,但一直不好调试。当一条管道在运行中的控制平面上出问题时,要看到每个函数的输入与返回,过去只能写测试、本地跑crossplane render,或者自己加埋点。v2.2 加入了 pipeline inspector。开启特性开关后,Crossplane 控制器会拦截每一次RunFunctionRequest与RunFunctionResponse,并通过 gRPC 转发到你设置的 Unix socket。一个 sidecar 从这个 socket 读取数据,然后按你的需要处理:开发时把它流式打到 stdout,生产环境则推到审计管道。要启用,请在 Crossplane 上加上--enable-pipeline-inspector。默认 socket 路径为/var/run/pipeline-inspector/socket,可以用--pipeline-inspector-socket修改。# 开启 pipeline inspector 特性开关 args: - --enable-pipeline-inspector - --pipeline-inspector-socket=/var/run/pipeline-inspector/socket # 注入 pipeline inspector sidecar sidecarsCrossplane: - name: pipeline-inspector image: xpkg.crossplane.io/crossplane/inspector-sidecar:v0.0.3 args: - --socket-path=/var/run/pipeline-inspector/socket - --max-recv-msg-size=8388608 # 8MB volumeMounts: - name: pipeline-inspector-socket mountPath: /var/run/pipeline-inspector resources: requests: { cpu: 10m, memory: 64Mi } limits: { cpu: 100m, memory: 128Mi } # 为 Unix socket 通信添加共享卷 extraVolumesCrossplane: - name: pipeline-inspector-socket emptyDir: {} extraVolumeMountsCrossplane: - name: pipeline-inspector-socket mountPath: /var/run/pipeline-inspector -
spec之外的 XRD 校验:XRD 中x-kubernetes-validations(Kubernetes 基于 CEL 的校验规则)此前只能作用在 XR 的spec之下的字段上。如果你想强制类似「所有 Database 名字必须以db-开头」这样的规则,就得借助 Kyverno、OPA/Gatekeeper 或自写 webhook 这类外部 admission controller。v2.2 取消了这个限制:现在你可以在spec之外写 CEL 规则,由 API server 在准入阶段强制执行。apiVersion: apiextensions.crossplane.io/v1 kind: CompositeResourceDefinition metadata: name: databases.platform.example.org spec: group: platform.example.org names: kind: Database plural: databases versions: - name: v1alpha1 served: true referenceable: true schema: openAPIV3Schema: type: object x-kubernetes-validations: - rule: "self.metadata.name.startsWith('db-')" message: "Database names must start with 'db-'" properties: spec: type: object properties: region: type: string -
依赖项的
ImageConfig运行时:包括 Provider 在内的 Crossplane 包以 Deployment 形式运行。要定制这个 Deployment,比如加 service account 注解、Pod 标签或容器参数,可以用DeploymentRuntimeConfig并在包里引用它。
kind: Provider
spec:
package: xpkg.crossplane.io/crossplane-contrib/provider-azure-network:v1.0.0
runtimeConfigRef:
name: azure-workload-identity当你直接安装某个包时,这套办法可以工作。但 Crossplane 也会把包作为依赖项安装。在那种情况下,对作为依赖项安装的 provider,你无法应用 Workload Identity 或其他运行时定制。
ImageConfig 是一个集群作用域的资源,它根据镜像前缀来匹配包,而不看具体是哪个 Provider 或 Configuration 对象创建的。v2.2 增加了一个新字段 spec.runtime.configRef。有了这一改动,凡镜像匹配的包,无论以哪种方式安装,Crossplane 都会为其应用 DeploymentRuntimeConfig。
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
name: azure-workload-identity
spec:
matchImages:
- prefix: xpkg.crossplane.io/crossplane-contrib/provider-azure-
- prefix: xpkg.crossplane.io/crossplane-contrib/provider-family-azure
runtime:
configRef:
name: azure-workload-identity所有 Azure 家族的 provider,无论是直接安装还是被作为依赖加进来,都会拿到这份运行时配置。
-
函数的
RequiredSchemas:composition 与函数有时需要某个资源的 OpenAPI 模式,用来校验输入、做基于模式的判断或动态生成资源。在 v2.2 之前,你只能让 Crossplane 把对应的 CRD 作为RequiredResource提供给你,再自行解析、抽出模式;而且这只对自定义资源管用,因为像 Deployment 这样的内置 kind 没有 CRD。v2.2 在RunFunctionResponse上引入了RequiredSchemas,可以返回任意 kind 的模式,无论内置还是自定义。 -
crossplane beta trace的改进:现在你可以传入一个 kind(也可以再加一个命名空间),而不是一个具体资源,从而拿到该 kind 下每个实例的依赖树。同时--watch(别名-w)会像kubectl get -w那样让输出保持实时。 -
函数包不再安装其捆绑的 CRD:函数包里随附的 CRD 不再被应用到集群中。另外,对于带未知或不被允许的 kind 的包,安装可以正常完成,那些对象会被直接跳过。以前这种情况会让安装失败。
-
包缓存的布局有变:缓存文件名现在来自包的 OCI 源和摘要,而不是 PackageRevision 的 Kubernetes 名称。这一改动会影响某些 provider e2e 测试套件中使用的旁路加载(side-loading)。
运维层面的现实
-
管理集群就是你的状态。 Crossplane 不使用外部状态文件。所有 XRD、Composition、XR 与 managed resource 都存在管理集群的 etcd 里。如果在没有备份的情况下丢掉了那个集群,云资源会照常运行,但 Crossplane 会失去对它们的视野并停止协调,悄悄的漂移就会逐渐积累。请把管理集群当成对生产关键的 Kubernetes 集群来对待:使用高可用的控制平面、给 etcd 做备份、不要在你的笔记本上跑它。本地的 k3s 或 kind 集群拿来学习、做演示、走 Get Started 指南没有问题,但承载关键状态不行。这是不要 Terraform 状态文件的代价:你解决了一个运维问题,但获得了另一个更容易被忽略的问题。
-
要经过 v2.1 升级,而不是直接跳。 Crossplane 会在每个次版本升级时执行 CRD 迁移,所以跳版本会让你错过重要的迁移。如果你在 v1.x,请按 Crossplane v2 升级指南来。如果你已经在 v2.1,可以直接升到 v2.2。
-
v1.20 还没到生命周期终点。 v1.20 仍受支持,还没到 EOL。不过既然你已经在一个仅维护的分支上了,是时候开始规划升级到 v2.x 了。
-
Pipeline Inspector 处于 alpha 阶段。 该开关默认关闭,API 契约还可能变。Sidecar 镜像的版本管理也尚未稳定。可以在开发环境里试用(能看见函数管道之后,理解起来会容易得多),但先别把它写进事故响应的 runbook。
-
命名空间化的 MR 还没完全普及。 AWS 的 managed resource 已经完全命名空间化。被广泛使用的 Upbound Azure 和 GCP provider,还在逐步推开这个特性。
-
v2 移除了一些功能。 原生的 patch-and-transform composition、
ControllerConfig类型、外部 secret store、composite resource 的连接信息(connection details),以及包的默认注册表都已不再可用。大多数用户不需要破坏性变更也能升级,但如果你在用这些功能,那就得做一轮清理。升级前请运行kubectl get pkg,确认每个包都使用完全限定的镜像,比如registry.example.com/repo/package:tag。
一个实用的建议
如果你正在为自己的 Kubernetes 平台考虑控制平面,又没有非要继续用 Terraform 的强理由,先把 Crossplane v2.2 试一遍。Get Started 指南在任何 Kubernetes 集群上一个下午就能走完。如果 Crossplane 能满足你的需求,就可以用一套声明式模型同时管理应用和基础设施的工作流。如果不能,你也会拿到一个明确、有据可查的理由,去说明为什么继续保留现有工具。
如果你已经在用 Crossplane v2.1,请升级到 v2.2。即便你不打算用 pipeline inspector,MRD 控制器上的 server-side apply、依赖感知的运行时配置、函数的模式访问、更好的 trace 输出这些功能也值回票价。如果你还在 v1.x,先把版本钉在 v1.20 上,把那些不再支持的特性迁掉,再升到 v2.x,然后从那里继续往前走。v2 提供了不错的向后兼容性,但弃用是认真的,那些功能真的会被移除。
FAQ
关于这次发布,我们最常被问到的三个问题。
Crossplane 是 Terraform 的替代品吗?
不是。Terraform 是运行在 Kubernetes 之外的、更简单的工作流工具。Crossplane 是一个持续运行的控制平面;如果你们已经在用 Kubernetes 和 GitOps,它会更合适。
用 Crossplane 一定要用 composition 吗?
不必。你可以直接使用 provider 和 managed resource。composition 是可选项,主要用于构建更高层、可复用的抽象。
v2 系列里有哪些变化是我应该提前规划的?
资源默认按命名空间作用域、composition 支持任意 K8s 资源、Claims 被命名空间和 RBAC 替代、operations 可以承载工作流。Legacy 模式依然支持 v1。
如果你不想自己来跑这次推出,Todea 可以作为我们托管平台服务的一部分,把 Crossplane 的安装与运维一并接手。