Crossplane
Crossplane 徹底解説 — クラウドネイティブなインフラストラクチャ管理の新標準
1. はじめに
1.1 Crossplane とは何か
Crossplane は、Kubernetes をコントロールプレーンとして活用し、あらゆるクラウドインフラストラクチャをKubernetes のカスタムリソース (CR) として宣言的に管理するためのオープンソースフレームワークである。CNCF (Cloud Native Computing Foundation) のインキュベーションプロジェクトとして2020年に採択され、その後2023年9月にGraduatedプロジェクトに昇格した。
従来の Infrastructure as Code (IaC) ツールである Terraform や Pulumi が「プロビジョニングツール」としての役割を担うのに対し、Crossplane は Kubernetes のコントロールループ(Reconciliation Loop)を活用した「継続的なインフラストラクチャ管理プラットフォーム」としての位置づけを持つ。これにより、インフラストラクチャの状態を常に監視し、宣言された望ましい状態(Desired State)と実際の状態(Actual State)の差分を検出して自動的に修復する仕組みを実現する。
1.2 Crossplane が解決する課題
現代のクラウドネイティブ環境において、インフラストラクチャ管理は以下のような課題を抱えている。
マルチクラウド管理の複雑性
企業は複数のクラウドプロバイダー(AWS、GCP、Azure など)を利用することが一般的になっている。各プロバイダーは独自の API、CLI、SDK を提供しており、それぞれの操作方法やリソースモデルを理解する必要がある。Crossplane はこれらの差異を Kubernetes API の背後に抽象化し、統一的なインターフェースを提供する。
インフラストラクチャとアプリケーションの管理の分断
従来の IaC ツールでは、インフラストラクチャの管理とアプリケーションのデプロイは別々のワークフローで行われることが多い。Crossplane は両方を Kubernetes マニフェストとして統一的に管理できるため、GitOps ワークフローとの親和性が非常に高い。
セルフサービスインフラストラクチャの実現困難
開発チームがインフラストラクチャを必要とする際、従来はプラットフォームチームやインフラチームへの依頼が必要であった。Crossplane の Composition 機能を活用することで、プラットフォームチームが安全で標準化された「インフラストラクチャの型(テンプレート)」を定義し、開発チームはそれを自由に利用できるセルフサービスモデルを構築できる。
ドリフト(構成のずれ)の検出と修復
Terraform などの IaC ツールでは、terraform apply を実行した後にクラウドコンソール等から手動で変更が加えられると、コードと実際の状態に乖離(ドリフト)が発生する。Crossplane は Kubernetes のコントロールループにより、このドリフトを継続的に検出し自動修復する。
1.3 Crossplane の歴史と背景
Crossplane は Upbound 社によって2018年に開発が開始された。Upbound 社の創業者である Bassam Tabbara は、かつて Rook(Kubernetes 上のストレージオーケストレーション)プロジェクトの創始者でもあり、Kubernetes のオペレーターパターンに深い知見を持っていた。
| 年月 | マイルストーン |
|---|---|
| 2018年12月 | Crossplane プロジェクト開始、GitHub でオープンソースとして公開 |
| 2020年6月 | CNCF Sandbox プロジェクトとして採択 |
| 2021年9月 | CNCF Incubation プロジェクトに昇格 |
| 2022年 | Composition Functions の概念導入 |
| 2023年6月 | Crossplane v1.13 リリース(Composition Functions GA) |
| 2023年9月 | CNCF Graduated プロジェクトに昇格 |
| 2024年 | Provider v1 の安定化、エコシステムの成熟 |
| 2025年 | Crossplane v1.17+ リリース、Composition Functions v2 の進化 |
1.4 Crossplane と他の IaC ツールとの比較
Crossplane を理解するために、主要な IaC ツールとの比較を行う。
| 特徴 | Crossplane | Terraform | Pulumi | AWS CDK |
|---|---|---|---|---|
| 宣言的管理 | ○ (YAML) | ○ (HCL) | △ (命令的+宣言的) | × (命令的) |
| 継続的リコンシリエーション | ○ | × | × | × |
| ドリフト自動修復 | ○ | × (手動 plan/apply) | × | × |
| Kubernetes ネイティブ | ○ | × | × | × |
| GitOps 親和性 | ◎ | △ | △ | × |
| 抽象化レイヤー | ○ (Compositions) | △ (Modules) | ○ (Components) | ○ (Constructs) |
| マルチクラウド対応 | ○ | ○ | ○ | × (AWS のみ) |
| ステート管理 | Kubernetes etcd | tfstate ファイル | Pulumi Cloud/自前 | CloudFormation |
| 学習コスト | 中〜高 | 中 | 低〜中 | 中 |
| コミュニティ | 成長中 | 非常に大きい | 成長中 | 中程度 |
Terraform との最大の違いは「ステート管理」と「継続的リコンシリエーション」にある。Terraform では tfstate ファイルを別途管理する必要があり、ステートのロックやバックエンドの設定が必要となる。一方、Crossplane は Kubernetes の etcd をステートストアとして活用するため、追加のステート管理インフラが不要である。また、Terraform は plan と apply のコマンドを手動(または CI/CD パイプライン経由)で実行する必要があるが、Crossplane はコントロールループにより自動的かつ継続的にリコンシリエーションを行う。
1.5 本記事の構成
本記事では、Crossplane の全体像を理解するために以下の構成で解説を進める。
- はじめに(本章)
- アーキテクチャの全体像
- コアコンポーネントの詳細
- Provider の仕組みと設定
- Managed Resources の管理
- Composition と XRD によるインフラストラクチャの抽象化
- Composition Functions による高度なロジック
- パッケージ管理
- RBAC とセキュリティ
- GitOps との統合
- 実践的なユースケースと設定例
- 運用とトラブルシューティング
- パフォーマンスとスケーラビリティ
- エコシステムと今後の展望
- まとめ
2. アーキテクチャの全体像
2.1 Crossplane のアーキテクチャ概要
Crossplane のアーキテクチャは、Kubernetes のエクステンションメカニズムを最大限に活用した設計となっている。その中心には以下の要素がある。
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Crossplane Core │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │ │
│ │ │ Composition │ │ Package │ │ RBAC │ │ │
│ │ │ Engine │ │ Manager │ │ Manager │ │ │
│ │ └─────────────┘ └──────────────┘ └───────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Providers │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │
│ │ │ AWS │ │ GCP │ │ Azure │ │ Helm │ │ │
│ │ │ Provider │ │ Provider │ │ Provider │ │ Provider│ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │ │
│ └───────┼──────────────┼──────────────┼─────────────┼──────┘ │
│ │ │ │ │ │
└──────────┼──────────────┼──────────────┼─────────────┼──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐
│ AWS │ │ GCP │ │ Azure │ │ Helm │
│ API │ │ API │ │ API │ │ Charts │
└─────────┘ └─────────┘ └──────────┘ └──────────┘
2.2 コントロールプレーンとしての Kubernetes
Crossplane が Kubernetes をコントロールプレーンとして採用している理由は複数存在する。
宣言的 API の活用
Kubernetes API サーバーは、リソースの望ましい状態(Desired State)を宣言的に記述し、それを API として公開する仕組みを提供する。Crossplane はこの仕組みを拡張し、クラウドリソースに対しても同様の宣言的管理を実現する。
Custom Resource Definition (CRD) によるスキーマ拡張
Kubernetes の CRD メカニズムにより、任意のリソース型を定義できる。Crossplane の各 Provider は、対象クラウドサービスのリソースに対応する CRD を登録する。例えば、AWS Provider をインストールすると、s3.aws.upbound.io/Bucket、ec2.aws.upbound.io/Instance などの CRD が自動的に登録される。
コントロールループ(Reconciliation Loop)
Kubernetes のコントローラーマネージャーは、各リソースに対して「observe → analyze → act」のループを繰り返し実行する。Crossplane のコントローラーは以下のサイクルを回す。
┌──────────┐
│ Observe │ ← 外部リソースの現在の状態を取得
└────┬─────┘
│
┌────▼─────┐
│ Compare │ ← Desired State と Actual State を比較
└────┬─────┘
│
┌────▼─────┐
│ Act │ ← 差分があれば API を呼び出して修正
└────┬─────┘
│
└──────→ ループを繰り返す(デフォルト: 1分間隔)
etcd による状態管理
Kubernetes の etcd がステートストアとして機能するため、Terraform の tfstate のような外部ステート管理が不要となる。ただし、etcd のサイズ制限(デフォルト 2GB)に注意が必要であり、大量のリソースを管理する場合は etcd のチューニングが必要となる場合がある。
2.3 リソースモデルの階層構造
Crossplane のリソースモデルは、以下の3つの階層で構成される。
┌─────────────────────────────────────────────────────────┐
│ Claim (XC) │
│ 開発者が利用する高レベルの抽象化されたリソース │
│ 例: DatabaseClaim, KubernetesClusterClaim │
│ → Namespace スコープ │
└─────────────────────┬───────────────────────────────────┘
│ 参照
┌─────────────────────▼───────────────────────────────────┐
│ Composite Resource (XR) │
│ 複数のManagedResourceを束ねる中間層 │
│ 例: XDatabase, XKubernetesCluster │
│ → Cluster スコープ │
└─────────────────────┬───────────────────────────────────┘
│ 所有
┌─────────────────────▼───────────────────────────────────┐
│ Managed Resource (MR) │
│ 外部クラウドリソースと1:1で対応する低レベルリソース │
│ 例: Bucket, Instance, VPC, Subnet │
│ → Cluster スコープ │
└─────────────────────────────────────────────────────────┘
Claim (XC)
Claim はアプリケーション開発者が利用する最上位の抽象化レイヤーである。Namespace スコープで作成されるため、Kubernetes の名前空間ベースのマルチテナント設計と親和性が高い。
Composite Resource (XR)
XR は Composition の結果として生成される中間層のリソースである。Cluster スコープで存在し、1つ以上の Managed Resource を所有する。
Managed Resource (MR)
MR は外部のクラウドリソースと1対1で対応するリソースである。各 Provider が定義する CRD に基づいて作成される。
2.4 データフローの全体像
ユーザーが Claim を作成してから実際のクラウドリソースがプロビジョニングされるまでのデータフローを示す。
[ユーザー/GitOps]
│
│ kubectl apply -f claim.yaml
▼
[Kubernetes API Server]
│
│ Claim リソースが etcd に保存
▼
[Crossplane Composition Engine]
│
│ 1. Claim を検出
│ 2. 対応する XRD/Composition を検索
│ 3. Composition に基づいて XR を生成
│ 4. XR に基づいて Managed Resources を生成
▼
[Provider Controller]
│
│ 1. Managed Resource を検出
│ 2. 外部リソースの状態を確認(Observe)
│ 3. 必要に応じてリソースを作成/更新(Create/Update)
│ 4. ステータスを Managed Resource に反映
▼
[Cloud Provider API]
│
│ 実際のクラウドリソースが作成される
▼
[クラウドリソース]
(S3バケット, RDSインスタンス, VPC 等)
2.5 ネットワーキングとセキュリティの観点
Crossplane のコントロールプレーンは Kubernetes クラスター内で動作するため、クラウドプロバイダーの API エンドポイントへの外向き通信が必要となる。セキュリティの観点から以下の点に注意が必要である。
- 認証情報の管理: Provider が使用するクラウド認証情報は Kubernetes Secret として管理される。IRSA (IAM Roles for Service Accounts)、Workload Identity などの Pod Identity メカニズムの利用が推奨される
- ネットワークポリシー: Provider Pod からクラウド API への通信のみを許可するネットワークポリシーの設定が望ましい
- RBAC: Crossplane は独自の RBAC マネージャーを持ち、Composition 作成者とClaim 利用者の権限を分離できる
3. コアコンポーネントの詳細
3.1 Crossplane Pod の構成
Crossplane をインストールすると、以下の Pod が展開される。
$ kubectl get pods -n crossplane-system
NAME READY STATUS RESTARTS AGE
crossplane-7c9b4c6f5d-xxxxx 1/1 Running 0 5m
crossplane-rbac-manager-6d8f6b4c9-yyyyy 1/1 Running 0 5m
crossplane Pod
メインの Crossplane コントローラーであり、以下の機能を担当する。
- Composition Engine: XRD、Composition、Claim、XR の管理
- Package Manager: Provider、Configuration パッケージのインストールと管理
- CRD の動的登録と管理
crossplane-rbac-manager Pod
Crossplane が定義するリソースに対する RBAC ポリシーを自動管理するコンポーネントである。新しい CRD が登録されると、自動的に適切な ClusterRole を生成する。
3.2 Composition Engine
Composition Engine は Crossplane の中核となるコンポーネントであり、以下の責務を持つ。
- XRD (CompositeResourceDefinition) の管理: XRD が作成されると、対応する CRD を動的に生成し、Kubernetes API サーバーに登録する
- Composition の選択: XR が作成されると、CompositionSelector や CompositionRef に基づいて適切な Composition を選択する
- リソースのレンダリング: 選択された Composition のテンプレートに基づいて Managed Resource を生成する
- ステータスの伝播: Managed Resource のステータスを XR、さらに Claim へと伝播させる
3.3 Package Manager
Package Manager は OCI (Open Container Initiative) レジストリからパッケージをダウンロードし、インストールする機能を提供する。Crossplane のパッケージは OCI イメージとして配布される。
パッケージの種類は以下の通り。
| パッケージ種別 | 説明 | 例 |
|---|---|---|
| Provider | クラウドプロバイダーの CRD とコントローラー | provider-aws, provider-gcp |
| Configuration | XRD と Composition のセット | platform-ref-aws |
| Function | Composition Functions の実装 | function-patch-and-transform |
3.4 Managed Resource コントローラーのライフサイクル
各 Managed Resource コントローラーは、以下のライフサイクルステートを管理する。
┌─────────────────┐
│ Created │
│ (Pending) │
└────────┬────────┘
│
┌────────▼────────┐
│ Provisioning │
│ (Creating) │
└────────┬────────┘
│
┌────────▼────────┐
┌─────│ Available │──────┐
│ │ (Ready) │ │
│ └────────┬────────┘ │
│ │ │
ドリフト検出 更新要求 削除要求
│ │ │
┌────────▼────────┐ │ ┌─────────▼────────┐
│ Reconciling │ │ │ Deleting │
│ (Syncing) │ │ │ │
└────────┬────────┘ │ └─────────┬─────────┘
│ │ │
└──────────────┘ ┌─────────▼─────────┐
│ Deleted │
└───────────────────┘
ステータス条件(Status Conditions)は以下の通りである。
- Synced: 外部リソースとの同期状態を示す。
Trueは同期済み、Falseはエラーが発生していることを示す - Ready: リソースが利用可能な状態かを示す。
Trueはリソースが完全にプロビジョニングされ利用可能であることを示す - LastAsyncOperation: 非同期操作の結果を示す(一部の Provider で使用)
4. Provider の仕組みと設定
4.1 Provider の概要
Provider は Crossplane のプラグインシステムであり、特定のクラウドプロバイダーや外部サービスの API と通信するためのコントローラーと CRD のセットを提供する。各 Provider は OCI イメージとしてパッケージングされ、Crossplane の Package Manager によってインストールされる。
4.2 主要な Provider
Crossplane エコシステムには多数の Provider が存在する。以下に代表的なものを示す。
| Provider | 対象 | CRD 数(概算) | メンテナー |
|---|---|---|---|
| provider-aws-* (Upbound family) | Amazon Web Services | 1000+ | Upbound |
| provider-gcp-* (Upbound family) | Google Cloud Platform | 800+ | Upbound |
| provider-azure-* (Upbound family) | Microsoft Azure | 900+ | Upbound |
| provider-kubernetes | Kubernetes クラスター | N/A (動的) | コミュニティ |
| provider-helm | Helm チャート | N/A (動的) | コミュニティ |
| provider-terraform | Terraform モジュール | N/A (動的) | Upbound |
| provider-sql | SQL データベース | 10+ | コミュニティ |
Upbound 公式 Provider(Family Provider)
Upbound 社は、各クラウドプロバイダー向けに「Family Provider」というモジュール化された Provider セットを提供している。例えば AWS 向けには以下のような構成となる。
provider-family-aws ← 基盤となる Provider(認証管理)
├── provider-aws-s3 ← S3 関連の CRD とコントローラー
├── provider-aws-ec2 ← EC2 関連の CRD とコントローラー
├── provider-aws-rds ← RDS 関連の CRD とコントローラー
├── provider-aws-iam ← IAM 関連の CRD とコントローラー
├── provider-aws-eks ← EKS 関連の CRD とコントローラー
├── provider-aws-lambda ← Lambda 関連の CRD とコントローラー
├── provider-aws-vpc ← VPC 関連の CRD とコントローラー
└── ... (その他多数)
この設計により、必要なサービスの Provider のみをインストールできるため、CRD の数を抑えてクラスターへの負荷を軽減できる。
4.3 Provider のインストール
Provider のインストールは Provider リソースを作成することで行う。
# provider-aws-s3.yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws-s3
spec:
package: xpkg.upbound.io/upbound/provider-aws-s3:v1.14.0
runtimeConfigRef:
name: default
v1.14 以降では DeploymentRuntimeConfig を使用してProvider のランタイム設定をカスタマイズする。
# deployment-runtime-config.yaml
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: aws-runtime-config
spec:
deploymentTemplate:
spec:
replicas: 1
selector: {}
template:
spec:
containers:
- name: package-runtime
resources:
limits:
memory: 512Mi
cpu: 500m
requests:
memory: 256Mi
cpu: 250m
env:
- name: HTTPS_PROXY
value: "http://proxy.example.com:8080"
serviceAccountName: provider-aws-sa
nodeSelector:
node-role: crossplane
tolerations:
- key: "dedicated"
operator: "Equal"
value: "crossplane"
effect: "NoSchedule"
4.4 Provider の認証設定(ProviderConfig)
Provider がクラウド API にアクセスするための認証情報は ProviderConfig リソースで設定する。
AWS の認証設定例(アクセスキー方式)
apiVersion: v1
kind: Secret
metadata:
name: aws-credentials
namespace: crossplane-system
type: Opaque
stringData:
credentials: |
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
---
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-credentials
key: credentials
AWS の認証設定例(IRSA 方式 -- 推奨)
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: IRSA
IRSA(IAM Roles for Service Accounts)を使用する場合は、以下の設定が前提となる。
- EKS クラスターで OIDC Provider が有効化されていること
- IAM ロールが作成され、適切な信頼ポリシーが設定されていること
- Provider の ServiceAccount に IAM ロールのアノテーションが付与されていること
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: aws-irsa-config
spec:
serviceAccountTemplate:
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/crossplane-provider-aws
GCP の認証設定例(Workload Identity 方式)
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
projectID: my-gcp-project-id
credentials:
source: InjectedIdentity
Azure の認証設定例(Service Principal 方式)
apiVersion: v1
kind: Secret
metadata:
name: azure-credentials
namespace: crossplane-system
type: Opaque
stringData:
credentials: |
{
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientSecret": "your-client-secret",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": "https://management.azure.com/"
}
---
apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: azure-credentials
key: credentials
4.5 複数の ProviderConfig によるマルチアカウント管理
Crossplane は複数の ProviderConfig を定義することで、マルチアカウント・マルチリージョンの管理を実現できる。
# 本番環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-production
spec:
credentials:
source: IRSA
assumeRoleChain:
- roleARN: arn:aws:iam::111111111111:role/crossplane-production
---
# ステージング環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-staging
spec:
credentials:
source: IRSA
assumeRoleChain:
- roleARN: arn:aws:iam::222222222222:role/crossplane-staging
---
# 開発環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-development
spec:
credentials:
source: IRSA
assumeRoleChain:
- roleARN: arn:aws:iam::333333333333:role/crossplane-development
Managed Resource から ProviderConfig を参照する際は providerConfigRef を使用する。
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
name: my-production-bucket
spec:
forProvider:
region: ap-northeast-1
providerConfigRef:
name: aws-production # 本番アカウントの認証情報を使用
5. Managed Resources の管理
5.1 Managed Resource の基本構造
Managed Resource は外部クラウドリソースと1対1で対応する Kubernetes カスタムリソースである。その基本的な構造は以下の通り。
apiVersion: <provider-group>/<version>
kind: <ResourceKind>
metadata:
name: <resource-name>
annotations:
crossplane.io/external-name: "actual-cloud-resource-name"
spec:
forProvider:
region: ap-northeast-1
providerConfigRef:
name: default
deletionPolicy: Delete # Delete (デフォルト) or Orphan
managementPolicies:
- "*" # デフォルト: すべての操作を管理
writeConnectionSecretToRef:
name: my-resource-connection
namespace: crossplane-system
status:
conditions:
- type: Ready
status: "True"
reason: Available
- type: Synced
status: "True"
reason: ReconcileSuccess
atProvider:
arn: "arn:aws:s3:::my-bucket-name"
id: "my-bucket-name"
5.2 具体的な Managed Resource の例
S3 バケットの作成
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
name: my-application-bucket
annotations:
crossplane.io/external-name: "my-app-bucket-prod-2024"
spec:
forProvider:
region: ap-northeast-1
tags:
Environment: production
Team: platform
ManagedBy: crossplane
providerConfigRef:
name: aws-production
deletionPolicy: Delete
---
apiVersion: s3.aws.upbound.io/v1beta1
kind: BucketVersioning
metadata:
name: my-application-bucket-versioning
spec:
forProvider:
bucketRef:
name: my-application-bucket
versioningConfiguration:
- status: Enabled
providerConfigRef:
name: aws-production
---
apiVersion: s3.aws.upbound.io/v1beta2
kind: BucketServerSideEncryptionConfiguration
metadata:
name: my-application-bucket-encryption
spec:
forProvider:
bucketRef:
name: my-application-bucket
rule:
- applyServerSideEncryptionByDefault:
- sseAlgorithm: aws:kms
kmsMasterKeyId: "arn:aws:kms:ap-northeast-1:123456789012:key/xxxxxxxx"
providerConfigRef:
name: aws-production
RDS PostgreSQL インスタンスの作成
apiVersion: rds.aws.upbound.io/v1beta2
kind: Instance
metadata:
name: my-postgresql-instance
spec:
forProvider:
region: ap-northeast-1
allocatedStorage: 100
maxAllocatedStorage: 500
engine: postgres
engineVersion: "15.4"
instanceClass: db.r6g.large
dbName: myapplication
username: admin
autoGeneratePassword: true
dbSubnetGroupNameRef:
name: my-db-subnet-group
vpcSecurityGroupIdRefs:
- name: database-sg
multiAz: true
storageType: gp3
storageEncrypted: true
backupRetentionPeriod: 7
deletionProtection: true
tags:
Environment: production
providerConfigRef:
name: aws-production
writeConnectionSecretToRef:
name: my-postgresql-connection
namespace: crossplane-system
deletionPolicy: Orphan
5.3 リソース間の参照(References)
Crossplane の Managed Resource 間では、リソースの参照(Reference)機能を使用して依存関係を表現できる。
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
name: my-vpc
spec:
forProvider:
region: ap-northeast-1
cidrBlock: "10.0.0.0/16"
enableDnsHostnames: true
enableDnsSupport: true
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
name: private-subnet-1a
spec:
forProvider:
region: ap-northeast-1
availabilityZone: ap-northeast-1a
cidrBlock: "10.0.1.0/24"
vpcIdRef:
name: my-vpc # 名前ベースの参照
参照の方式は以下の2種類がある。
| 方式 | フィールド名 | 説明 |
|---|---|---|
| 名前参照 | *Ref (例: vpcIdRef) | リソースの名前で参照 |
| セレクタ参照 | *Selector (例: vpcIdSelector) | ラベルセレクタで参照 |
5.4 削除ポリシーと管理ポリシー
削除ポリシー(DeletionPolicy)
Delete: Managed Resource が削除されると外部リソースも削除(デフォルト)Orphan: Managed Resource が削除されても外部リソースは残る
管理ポリシー(ManagementPolicies)-- v1.14+
spec:
managementPolicies:
- "*" # すべての操作を管理(デフォルト)
# - Create # リソースの作成のみ
# - Update # リソースの更新のみ
# - Delete # リソースの削除のみ
# - Observe # リソースの状態監視のみ
既存のクラウドリソースを Crossplane にインポートしたい場合は、Observe のみを指定することで読み取り専用のリソースとして管理できる。
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
name: existing-vpc
annotations:
crossplane.io/external-name: "vpc-0123456789abcdef0"
spec:
forProvider:
region: ap-northeast-1
managementPolicies:
- Observe
providerConfigRef:
name: aws-production
6. Composition と XRD によるインフラストラクチャの抽象化
6.1 Composition の概念
Composition は Crossplane の最も強力な機能の1つであり、複数の Managed Resource を1つの高レベルな抽象リソースとしてまとめる仕組みを提供する。これにより、プラットフォームチームが組織固有のインフラストラクチャ「ビルディングブロック」を定義し、開発チームはその詳細を知ることなくインフラストラクチャをセルフサービスで利用できるようになる。
┌─────────────────────────────────────────────────────────────┐
│ CompositeResourceDefinition (XRD) │
│ - API スキーマの定義 │
│ - Claim と XR のインターフェースを規定 │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Composition │
│ - XRD のパラメータから Managed Resources への │
│ マッピングを定義 │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Claim (XC) / Composite Resource (XR) │
│ - ユーザーが作成するリソースインスタンス │
└─────────────────────────────────────────────────────────────┘
6.2 CompositeResourceDefinition (XRD) の定義
XRD は Kubernetes の CRD を生成するための「メタ CRD」とも呼べるリソースである。
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.platform.example.com
spec:
group: platform.example.com
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
engine:
type: string
enum: [postgres, mysql]
default: postgres
size:
type: string
enum: [small, medium, large]
default: small
storageGB:
type: integer
minimum: 20
maximum: 10000
default: 50
region:
type: string
default: ap-northeast-1
highAvailability:
type: boolean
default: false
required: [engine, region]
required: [parameters]
status:
type: object
properties:
endpoint:
type: string
port:
type: integer
6.3 Composition の定義
Composition は XRD で定義されたパラメータを実際の Managed Resource にマッピングする。
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabases.aws.platform.example.com
labels:
provider: aws
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XDatabase
mode: Resources
patchSets:
- name: common-parameters
patches:
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
resources:
- name: rds-instance
base:
apiVersion: rds.aws.upbound.io/v1beta2
kind: Instance
spec:
forProvider:
autoGeneratePassword: true
storageType: gp3
storageEncrypted: true
patches:
- type: PatchSet
patchSetName: common-parameters
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.engine
toFieldPath: spec.forProvider.engine
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.size
toFieldPath: spec.forProvider.instanceClass
transforms:
- type: map
map:
small: "db.t3.medium"
medium: "db.r6g.large"
large: "db.r6g.xlarge"
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.highAvailability
toFieldPath: spec.forProvider.multiAz
- type: ToCompositeFieldPath
fromFieldPath: status.atProvider.endpoint
toFieldPath: status.endpoint
6.4 Claim の作成
開発者は XRD で定義されたスキーマに従って Claim を作成する。
apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
name: my-app-db
namespace: team-alpha
spec:
parameters:
engine: postgres
size: small
storageGB: 50
region: ap-northeast-1
highAvailability: false
compositionSelector:
matchLabels:
provider: aws
writeConnectionSecretToRef:
name: my-app-db-connection
6.5 Patch の種類と Transform
| パッチタイプ | 方向 | 説明 |
|---|---|---|
| FromCompositeFieldPath | XR -> MR | XR のフィールドを MR にコピー |
| ToCompositeFieldPath | MR -> XR | MR のフィールドを XR にコピー |
| CombineFromComposite | XR -> MR | XR の複数フィールドを結合して MR に設定 |
| FromEnvironmentFieldPath | Env -> MR | Environment Config から MR にコピー |
Transform の種類
# Map Transform
transforms:
- type: map
map:
small: "db.t3.medium"
medium: "db.r6g.large"
# Math Transform
transforms:
- type: math
math:
type: Multiply
multiply: 1024
# String Transform
transforms:
- type: string
string:
type: Format
fmt: "%s-db-subnet-group"
6.6 Environment Config
Environment Config は Composition 内で共有されるコンテキスト情報を提供する。
apiVersion: apiextensions.crossplane.io/v1alpha1
kind: EnvironmentConfig
metadata:
name: production-ap-northeast-1
labels:
environment: production
region: ap-northeast-1
data:
vpcId: "vpc-0123456789abcdef0"
kmsKeyArn: "arn:aws:kms:ap-northeast-1:123456789012:key/xxxx"
accountId: "123456789012"
7. Composition Functions による高度なロジック
7.1 Composition Functions の概要
Composition Functions は Crossplane v1.14 で GA となった機能であり、Composition のリソース生成ロジックをプログラマブルに記述できる仕組みを提供する。条件分岐、ループ、外部データの参照などの複雑なロジックを実現できる。
7.2 Pipeline モードの Composition
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabases.aws-pipeline.platform.example.com
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XDatabase
mode: Pipeline
pipeline:
- step: render-resources
functionRef:
name: function-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
kind: Resources
resources:
- name: rds-instance
base:
apiVersion: rds.aws.upbound.io/v1beta2
kind: Instance
spec:
forProvider:
engine: postgres
storageEncrypted: true
- step: auto-ready
functionRef:
name: function-auto-ready
7.3 主要な Composition Functions
| Function | 説明 |
|---|---|
| function-patch-and-transform | 基本的なリソース生成とパッチ適用 |
| function-go-templating | Go テンプレートによる動的リソース生成 |
| function-kcl | KCL 言語による型安全な設定記述 |
| function-auto-ready | 全子リソース Ready 時に XR を Ready に設定 |
| function-extra-resources | Composition 外のリソースを参照 |
Go テンプレートを使用した Composition の例
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xnetworks.aws-templated.platform.example.com
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XNetwork
mode: Pipeline
pipeline:
- step: render-network
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
{{ $xr := .observed.composite.resource }}
{{ $region := $xr.spec.parameters.region }}
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: vpc
spec:
forProvider:
region: {{ $region }}
cidrBlock: {{ $xr.spec.parameters.vpcCidr }}
{{ $azs := list "a" "c" "d" }}
{{ range $i, $az := $azs }}
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: subnet-{{ $az }}
spec:
forProvider:
region: {{ $region }}
availabilityZone: {{ $region }}{{ $az }}
cidrBlock: "10.0.{{ add $i 1 }}.0/24"
{{ end }}
- step: auto-ready
functionRef:
name: function-auto-ready
7.4 カスタム Composition Function の開発
Go 言語での Function 実装例:
package main
import (
fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"
"github.com/crossplane/function-sdk-go"
"github.com/crossplane/function-sdk-go/request"
"github.com/crossplane/function-sdk-go/response"
)
type Function struct {
fnv1beta1.UnimplementedFunctionRunnerServiceServer
}
func (f *Function) RunFunction(
req *fnv1beta1.RunFunctionRequest,
) (*fnv1beta1.RunFunctionResponse, error) {
rsp := response.To(req, response.DefaultTTL)
xr, err := request.GetObservedCompositeResource(req)
if err != nil {
response.Fatal(rsp, err)
return rsp, nil
}
// カスタムロジックをここに実装
return rsp, nil
}
8. パッケージ管理
8.1 Configuration パッケージの作成
# crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: platform-database
spec:
crossplane:
version: ">=v1.14.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-aws-rds
version: ">=v1.0.0"
- function: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform
version: ">=v0.5.0"
パッケージのビルドとプッシュ:
$ crossplane xpkg build --package-root=. --output=platform-database.xpkg
$ crossplane xpkg push --package-files=platform-database.xpkg \
registry.example.com/platform/platform-database:v1.0.0
8.2 パッケージのインストール
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: platform-database
spec:
package: registry.example.com/platform/platform-database:v1.0.0
revisionActivationPolicy: Automatic
revisionHistoryLimit: 3
9. RBAC とセキュリティ
9.1 プラットフォームチームと開発チームの権限分離
# プラットフォームチーム用
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: platform-admin
rules:
- apiGroups: ["apiextensions.crossplane.io"]
resources: ["compositeresourcedefinitions", "compositions"]
verbs: ["*"]
- apiGroups: ["pkg.crossplane.io"]
resources: ["providers", "configurations", "functions"]
verbs: ["*"]
---
# 開発チーム用
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: team-alpha
rules:
- apiGroups: ["platform.example.com"]
resources: ["databases"]
verbs: ["*"]
9.2 認証情報の安全な管理
External Secrets Operator との統合により、クラウドのシークレットマネージャーから認証情報を自動取得できる。
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: aws-crossplane-credentials
namespace: crossplane-system
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: aws-credentials
data:
- secretKey: access_key
remoteRef:
key: crossplane/aws-credentials
property: access_key_id
10. GitOps との統合
10.1 ArgoCD との統合
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: crossplane-infrastructure
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/infrastructure.git
targetRevision: main
path: crossplane/claims
destination:
server: https://kubernetes.default.svc
namespace: infrastructure
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- ServerSideApply=true
10.2 Git リポジトリの構成例
infrastructure/
├── crossplane/
│ ├── providers/
│ ├── functions/
│ ├── platform-apis/
│ │ ├── database/
│ │ │ ├── xrd.yaml
│ │ │ └── composition-aws.yaml
│ │ └── network/
│ ├── environment-configs/
│ └── claims/
│ ├── production/
│ ├── staging/
│ └── development/
└── apps/
10.3 プルリクエストベースのワークフロー
- 開発者が Claim を作成/変更する PR を作成
- CI パイプラインで
crossplane beta validateによるスキーマ検証、crossplane beta renderによるローカルレンダリング - プラットフォームチームがレビュー
- マージ後、ArgoCD が自動 sync
- Crossplane が Composition に基づきリソースを作成
11. 実践的なユースケースと設定例
11.1 Web アプリケーション基盤の構築
3層アーキテクチャの Web アプリケーション基盤を Crossplane で構築する例。XRD でコンピュート、データベース、キャッシュの設定パラメータを定義し、Go テンプレートを使用した Composition でセキュリティグループ、RDS インスタンス、ElastiCache クラスターを条件付きで生成する。
11.2 EKS クラスターのプロビジョニング
IAM Role、EKS Cluster、NodeGroup、Addon を一括でプロビジョニングする Composition を定義し、開発チームは Claim でクラスター名、ノードプールの構成、アドオンの選択を指定するだけで EKS クラスターを構築できる。
11.3 マルチクラウドのオブジェクトストレージ
同一の XRD に対して AWS (S3) 向けと GCP (GCS) 向けの Composition を用意し、Claim の compositionSelector で provider ラベルを切り替えるだけでクラウドプロバイダーを選択できる。
12. 運用とトラブルシューティング
12.1 日常的な運用コマンド
kubectl get managed # 全 Managed Resource の状態確認
kubectl get databases.platform.example.com -A # 全 Claim の状態確認
kubectl get providers # Provider の状態確認
kubectl get compositions # Composition の一覧
kubectl describe instance.rds.aws.upbound.io/my-db # 詳細表示
12.2 よくある問題と対処法
| 症状 | 原因 | 対処法 |
|---|---|---|
| Synced: False | IAM 権限不足、パラメータ不正 | Provider ログの確認、ProviderConfig の検証 |
| MR が作成されない | Composition 選択の失敗 | XR の compositionRef を確認、Crossplane ログの確認 |
| パッケージインストール失敗 | イメージプル失敗 | ネットワーク接続、レジストリ認証の確認 |
| クラスター負荷増大 | CRD の肥大化 | Family Provider の活用、不要な Provider の削除 |
12.3 モニタリングとアラート
重要なメトリクス:
| メトリクス | 説明 | アラート閾値の目安 |
|---|---|---|
controller_runtime_reconcile_errors_total | リコンシリエーションエラー数 | 増加傾向 |
controller_runtime_reconcile_time_seconds | リコンシリエーション所要時間 | p99 > 30秒 |
workqueue_depth | コントローラーのワークキュー深度 | > 100 |
12.4 アップグレード戦略
# Crossplane のアップグレード
$ helm upgrade crossplane crossplane-stable/crossplane \
--namespace crossplane-system --version 1.17.0
# Provider のアップグレード(段階的に)
$ kubectl patch provider provider-aws-s3 --type merge \
-p '{"spec":{"package":"xpkg.upbound.io/upbound/provider-aws-s3:v1.15.0"}}'
13. パフォーマンスとスケーラビリティ
13.1 スケーラビリティの考慮事項
| 項目 | 推奨値 | 制約要因 |
|---|---|---|
| Managed Resource 数 | ~2,000/Provider | Provider のメモリ・CPU |
| CRD 数 | ~500 | API Server のメモリ、etcd |
| Composition の深さ | ~50 リソース | Composition Engine のパフォーマンス |
| Provider 数 | ~20 | クラスターのリソース |
13.2 パフォーマンスチューニング
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: high-performance-config
spec:
deploymentTemplate:
spec:
template:
spec:
containers:
- name: package-runtime
resources:
limits:
memory: 2Gi
cpu: "2"
args:
- --poll=5m
- --max-reconcile-rate=50
13.3 大規模環境でのベストプラクティス
- Family Provider の活用で CRD 数を最小限に抑える
- 専用ノードに Crossplane と Provider の Pod を配置
- 頻繁に変更されないリソースにはリコンシリエーション間隔を延長
- 大量のリソースは複数の ProviderConfig に分割
14. エコシステムと今後の展望
14.1 Crossplane エコシステム
| ツール | 用途 |
|---|---|
| crossplane CLI | コマンドラインツール |
| Upbound Cloud | マネージド Crossplane コントロールプレーン |
| Upjet | Terraform Provider から Crossplane Provider を自動生成 |
| provider-terraform | 既存の Terraform モジュールを Crossplane から利用 |
| provider-kubernetes | Kubernetes リソースを Crossplane で管理 |
| provider-helm | Helm チャートを Crossplane で管理 |
14.2 今後の展望
- Composition Functions の進化(より多くの言語サポート)
- Observability の強化(ネイティブなメトリクス、トレーシング)
- マルチクラスターサポート
- WebAssembly (Wasm) Functions
- ステートフルリソースの管理改善
15. まとめ
15.1 Crossplane の強み
- Kubernetes ネイティブ: 既存のエコシステム(RBAC、GitOps、モニタリング等)をそのまま活用
- 継続的リコンシリエーション: ドリフトを自動修復
- 抽象化レイヤー: Composition によるセルフサービスインフラを実現
- マルチクラウド対応: 同一 API で複数クラウドのリソースを管理
- エコシステム: Upjet による豊富な Provider カバレッジ
15.2 Crossplane の課題
- 学習曲線: Kubernetes + Crossplane 固有概念の理解が必要
- デバッグの困難さ: 複数レイヤーにまたがる問題の特定が困難
- CRD の肥大化: 多数の Provider で API Server への負荷が増大
- 成熟度: Terraform と比較するとコミュニティ規模で劣る
15.3 導入の判断基準
Crossplane が適している場合
- Kubernetes を中心としたプラットフォーム基盤を構築している
- マルチクラウド/マルチアカウント環境を統一的に管理したい
- 開発チームにセルフサービスのインフラストラクチャを提供したい
- GitOps ワークフローでインフラとアプリケーションを統合管理したい
Crossplane が適していない場合
- Kubernetes を使用していない環境
- 小規模なインフラストラクチャで Terraform で十分に管理できる
- チームに Kubernetes の運用知識が不足している
15.4 推奨される導入アプローチ
- フェーズ 1: 評価: 開発環境で小規模なリソースを管理し動作を理解
- フェーズ 2: プラットフォーム API の設計: XRD と Composition を設計
- フェーズ 3: パイロット: ステージング環境で実際のアプリケーション基盤を管理
- フェーズ 4: 本番導入: GitOps と統合し本番環境のインフラを段階的に移行
- フェーズ 5: 拡張: Composition Functions、カスタム Provider の開発
本記事では、Crossplane のアーキテクチャ、コアコンポーネント、Provider の設定、Composition による抽象化、Composition Functions、パッケージ管理、セキュリティ、GitOps との統合、実践的なユースケース、運用・トラブルシューティング、パフォーマンスとスケーラビリティ、そしてエコシステムと今後の展望について包括的に解説した。
Crossplane は Kubernetes エコシステムの一部として急速に成熟しつつあり、クラウドネイティブなインフラストラクチャ管理の新たな標準となる可能性を秘めている。特に、プラットフォームエンジニアリングの文脈において、開発者体験の向上とインフラストラクチャのガバナンスを両立させるための強力なツールとして、今後ますますその重要性が増していくものと考えられる。