Crossplane K8s 控制平面
Crossplane 是什么
Crossplane 是一个开源的 Kubernetes 插件,它将你的 Kubernetes 集群转变为一个通用控制平面。借助 Crossplane,你不再需要用不同工具分别管理云基础设施、数据库、消息队列等外部资源,而是可以直接通过标准的 Kubernetes API 来声明、编排和管理所有基础设施和服务,就像管理 Pod 和 Deployment 一样。
简单来说,Crossplane 把 Kubernetes 的控制平面能力延伸到了云世界,让你用 kubectl 就能创建 RDS 实例、GKE 集群、IAM 策略等一切外部资源,真正实现“一切皆声明式”。
为什么需要 Crossplane
传统基础设施管理常面临以下痛点:
- 工具碎片化:Terraform、CloudFormation、SDK 各自为战,难以统一编排。
- GitOps 割裂:基础设施变更无法和应用部署纳管在同一个流程中。
- 缺乏自愈与调和能力:出现偏离期望状态时,无法自动修复。
- 多租户繁琐:为不同团队提供自助基础设施服务需要大量自定义平台开发。
Crossplane 利用 Kubernetes 原生的调和循环、自愈能力、RBAC 和声明式 API,一揽子解决上述问题。它让你在一个统一的平面上构建自己的内部开发平台,赋能开发者自主创建基础设施,同时保持治理和安全控制。
核心概念速览
在深入动手之前,先理解几个关键对象:
- Provider(提供者):负责连接外部 API(如 AWS、Azure、GCP)的组件。相当于基础设施的驱动,Crossplane 不自己管理资源,而是通过 Provider 将外部资源映射为 Kubernetes 自定义资源。
- Managed Resource(托管资源):代表一个外部基础设施的细粒度组件,例如 AWS 的一个
VPC或EC2实例。它们由 Provider 直接控制。 - Composite Resource (XR,复合资源):你自己定义的平台级抽象,比如“标准应用环境”可以包含数据库、缓存、网络等。XR 由一个 CompositeResourceDefinition (XRD) 定义。
- Composition(组合):规定如何将抽象 XR 转化为具体的一堆 Managed Resources 的配置模版,类似于“配方”。开发者只关心 XR 的简单接口,而平台团队通过 Composition 决定底层实现细节。
- Claim (XRC):是终端用户请求 XR 时创建的资源,例如用户创建一个
MySQLInstanceClaim,平台自动配给对应的 RDS 实例、Secret 等。
用生活化比喻:XR 是“点菜菜单”(比如“双人套餐”),Composition 是“后厨配方”(里面包含牛排、沙拉、红酒),Managed Resources 是“具体食材”(供应商的牛排),Claim 就是服务员接到的一张订单。
环境准备与安装
Kubernetes 集群
任何标准的 Kubernetes 集群均可,建议使用 1.22+ 版本。本地开发可使用 kind、minikube 或 k3d。
安装 Crossplane
使用 Helm 快速部署:
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane \
--namespace crossplane-system \
--create-namespace \
crossplane-stable/crossplane
等待所有 Pod 就绪:
kubectl get pods -n crossplane-system
出现 crossplane 和 crossplane-rbac-manager 等容器状态为 Running 即表示安装成功。
安装 Provider
以 AWS 为例,创建一个 Provider 对象:
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws
spec:
package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.47.1
应用后,Crossplane 会自动下载并安装 Provider 的 CRD 和相关控制器:
kubectl apply -f provider-aws.yaml
kubectl get providers
当 Provider 状态为 HEALTHY 且 INSTALLED 为 True 时,即就绪。
配置 Provider 凭证
Crossplane Provider 需要外部云的访问凭证。通常是创建一个 Kubernetes Secret 包含云服务商的密钥,然后通过 ProviderConfig 引用。
创建 AWS 凭证 Secret(提前准备好 aws_access_key_id 和 aws_secret_access_key):
kubectl create secret generic aws-secret \
-n crossplane-system \
--from-literal=creds="$(printf '[default]\naws_access_key_id = %s\naws_secret_access_key = %s\n' <YOUR_KEY_ID> <YOUR_SECRET>)"
再创建 ProviderConfig 引用该 Secret:
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-secret
key: creds
应用后,你就可以在 AWS 上创建资源了。
快速体验:创建第一个云资源
下面的例子直接使用 Managed Resource 创建一个 AWS S3 存储桶(注意:直接使用 Managed Resource 不是推荐的最终用户使用方式,但有助于理解内部机制)。
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
name: my-first-crossplane-bucket
spec:
forProvider:
region: us-east-1
acl: private
providerConfigRef:
name: default
应用:
kubectl apply -f bucket.yaml
查看状态:
kubectl get bucket
当 READY 和 SYNCED 均为 True 时,存储桶已在 AWS 创建完成。你可以登录 AWS 控制台确认。同时,如果你删除了该 Kubernetes 对象,Crossplane 会自动删除对应的云资源。
构建平台抽象:Composite Resources 与 Composition
直接暴露原始云资源给开发者会带来复杂度且缺乏治理。现在让我们定义自己的“平台 API”。
定义 CompositeResourceDefinition (XRD)
创建一个名为 XPostgreSQLInstance 的自定义抽象,暴露存储、引擎版本、密码策略等字段:
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresqlinstances.platform.example.org
spec:
group: platform.example.org
names:
kind: XPostgreSQLInstance
plural: xpostgresqlinstances
claimNames:
kind: PostgreSQLInstance
plural: postgresqlinstances
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
storageGB:
type: integer
engineVersion:
type: string
passwordSecretName:
type: string
required:
- storageGB
- engineVersion
这里我们同时定义了 Claim 的名称(PostgreSQLInstance),用户将通过 Claim 来请求实例。
编写 Composition
Composition 指定当创建 XPostgreSQLInstance 时要生成哪些 AWS 资源。以下例子创建一个 RDS 实例、一个子网组和一个安全组,并自动生成密码存入 Secret。
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xpostgresqlinstances.aws.platform.example.org
labels:
provider: aws
db: postgres
spec:
compositeTypeRef:
apiVersion: platform.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: subnetgroup
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: SubnetGroup
spec:
forProvider:
region: us-east-1
description: Subnet group for PostgreSQL
subnetIdRefs:
- name: default-subnet-a
- name: default-subnet-b
- name: securitygroup
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: SecurityGroup
spec:
forProvider:
region: us-east-1
description: PostgreSQL access
vpcIdRef:
name: default-vpc
ingress:
- fromPort: 5432
toPort: 5432
protocol: tcp
cidrBlocks:
- 0.0.0.0/0
- name: rdsinstance
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
spec:
forProvider:
region: us-east-1
dbSubnetGroupNameSelector:
matchControllerRef: true
vpcSecurityGroupIdSelector:
matchControllerRef: true
allocatedStorage: 20
engine: postgres
engineVersion: "14"
instanceClass: db.t3.micro
masterUsername: masteruser
passwordSecretRef:
name: psql-password
namespace: crossplane-system
key: password
skipFinalSnapshotBeforeDeletion: true
publiclyAccessible: false
patches:
- fromFieldPath: spec.storageGB
toFieldPath: spec.forProvider.allocatedStorage
- fromFieldPath: spec.engineVersion
toFieldPath: spec.forProvider.engineVersion
- fromFieldPath: spec.passwordSecretName
toFieldPath: spec.forProvider.passwordSecretRef.name
注意 patches 部分,它们将抽象字段(来自 XR 的 spec)映射到具体 Managed Resource 的属性上,使 Composition 能够参数化。
应用 XRD 和 Composition:
kubectl apply -f xrd.yaml
kubectl apply -f composition.yaml
kubectl get composition
kubectl get compositeresourcedefinitions
开发者的自助体验:创建 Claim
现在开发者只需创建一个简单的 PostgreSQLInstance Claim:
apiVersion: platform.example.org/v1alpha1
kind: PostgreSQLInstance
metadata:
name: my-db
namespace: dev-team
spec:
storageGB: 50
engineVersion: "15"
passwordSecretName: my-db-password
应用后,Crossplane 会在后台自动创建 XPostgreSQLInstance,然后根据 Composition 调谐出 RDS 实例、安全组等。Claim 最终会变成 Ready 状态,同时生成的密码会写入指定的 Secret 中。
开发者无需知道底层是 RDS 还是 Aurora,也不用操心网络配置,只需定义自身的需求。
生产化建议
多租户与命名空间隔离
可以利用 Kubernetes 命名空间和 RBAC 限制不同团队只能看到自己的 Claims,使平台团队提供统一 API,而开发团队互不干扰。
使用 Package 管理配置
将 XRD 和 Composition 打包成 OCI 镜像并推送到镜像仓库,形成 Configuration Package,方便版本化管理和分发。
例如定义一个 Configuration 来安装整个平台栈:
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: my-platform
spec:
package: xpkg.example.io/my-platform:v1.0.0
GitOps 集成
Crossplane 的声明式 API 可以完美融入 ArgoCD 或 Flux,将所有基础设施定义与应用代码存储在同一 Git 仓库,实现真正的 GitOps 工作流。
观测与调试
使用以下命令查看资源状态:
kubectl get claim -A
kubectl get composite -A
kubectl get managed
kubectl describe <resource-type> <name>
Crossplane 的日志和事件能帮助你了解调谐过程,通过 kubectl describe 可以明确看到哪一步出错。
生产 Secret 管理
应避免将密码字段直接在 Composition 中硬编码或使用弱 Secret。建议集成外部 Secret 管理方案(如 Vault 或云密钥管理服务),使用 Crossplane 的 external-secrets 插件或自定义补丁将密码写入安全存储。
小结
Crossplane 将 Kubernetes 打造成统一控制平面,大幅降低基础设施管理的碎片化程度。通过 Provider 接入云资源,用 XRD 和 Composition 构建自服务 API,让开发者以原生 Kubernetes 的方式管理一切。它不替代 Terraform,而是在更高的抽象层提供持续的协调和治理能力。
掌握了本文的安装、核心概念、抽象构建流程后,你已经可以开始在自己的集群中搭建平台。接下来可以尝试接入更多 Provider(GCP、Azure),探索更复杂的 Composition 技术(多资源、连接详情、自动绑定),逐步迈向真正的内部开发平台。