Skip to content

云原生

平台团队可以从 Crossplane v2.2 中期待什么

Crossplane v2.2 指南:管道调试、元数据校验、依赖感知的运行时配置,以及对构建 Kubernetes 控制平面的影响。

Ivan Porta

创始人兼 Principal Engineer

8 分钟阅读
#crossplane#kubernetes#platform-engineering#control-plane#iac#gitops
平台团队可以从 Crossplane v2.2 中期待什么

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 之类的工具在覆盖范围上有重叠(都能给你创建一个云数据库),但做法不同。正确的选择,取决于你的平台已经落在哪儿。

控制循环手动 apply(或流水线)手动创建/更新 stack持续协调
漂移处理plan 检测,手动修正漂移检测动作,通过 stack 更新修正自动检测并自动修正
状态由你保护的远端后端中的 tfstate(如启用版本控制的 S3、HCP Terraform)由 AWS 管理(服务端)管理集群 etcd 中的 Kubernetes API 对象
工作流与应用部署分离与应用部署分离kubectl apply 一致
抽象ModuleNested Stack、ModuleXRD + Composition + 函数
语言HCL、JSONYAML、JSONYAML、Go、Python、KCL、CUE、HCL(通过 composition 函数)
内置策略变量校验和前/后置条件(OSS);HCP Terraform / Enterprise 中的 Sentinel 与 OPA 集成cfn-guard、HooksXRD 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 控制器会拦截每一次 RunFunctionRequestRunFunctionResponse,并通过 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。

本网站使用Cookie进行分析。