Kubernetes上のCrossplane:Terraformを超え、GitOpsコントロールプレーンへ

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Terraformからコントロールプレーンへのシフト

Terraformは10年近くInfrastructure as Code (IaC) の分野を支配してきました。信頼性の高いツールですが、これは「プッシュ型」のモデルで動作します。プランを実行し、変更を適用(apply)すれば、プロセスは終了します。問題は、チームメンバーが午前2時にAWSコンソールでセキュリティグループを手動で変更した場合、次の手動実行までTerraformがそれに気づかないことです。これこそが「設定ドリフト(configuration drift)」の本質です。

Crossplaneは、Kubernetesクラスターをユニバーサルなコントロールプレーンに変えることで、このモデルを根底から覆します。状態(state)ファイルを管理する代わりに、インフラをKubernetesのカスタムリソース(CRD)として定義します。その後、コントローラーが継続的にクラウドリソースの状態を同期(reconcile)します。現実のリソースに変更があれば、Crossplaneが自動で元に戻します。私はこれを500以上のリソースを管理する本番環境に導入し、インフラとアプリケーションのコードを単一の統合されたGitOpsパイプラインで管理することに成功しました。

クイックスタート:5分以内にS3バケットをデプロイする

開始するには、稼働中のKubernetesクラスターとHelmがあれば十分です。Crossplane and 特定のAWSプロバイダーをインストールして、バケットを作成してみましょう。

1. Crossplaneのインストール

kubectl create namespace crossplane-system

helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update

helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

2. AWSプロバイダーのインストール

最新のCrossplaneは、軽量さを保つために「ファミリープロバイダー」を使用します。すべてのAWSサービスをインストールするのではなく、S3コントローラーのみをインストールします。これにより、以前のモノリシックなバージョンでは2GB以上必要だったメモリ使用量を、150MB以下に抑えることができます。

cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v0.47.0
EOF

3. 認証情報の設定

CrossplaneがAWSと通信するための権限が必要です。AWSキーを含む creds.conf ファイルを作成し、KubernetesのSecretを生成します。

kubectl create secret generic aws-secret -n crossplane-system --from-file=creds=./creds.conf

cat <<EOF | kubectl apply -f -
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-secret
      key: creds
EOF

4. 最初のリソースをプロビジョニングする

標準的なYAMLを使用してバケットを定義します。これは DeploymentやServiceのマニフェストと全く同じように見えます。

cat <<EOF | kubectl apply -f -
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  name: my-crossplane-test-bucket
spec:
  forProvider:
    region: us-east-1
  providerConfigRef:
    name: default
EOF

kubectl get buckets で進捗を確認します。READY 列が True になれば、AWS上に実際のバケットが作成されています。

なぜKubernetesが最高のインフラエンジンなのか

秘訣はYAMLではなく、制御ループ(Control Loop)にあります。Crossplaneは監視を止めません。AWS CLI経由でS3バケットが削除された場合、Crossplaneは次回の同期時に不一致を検出し、自動的に再作成します。これは外部の自動化なしではTerraformが太刀打ちできない、自己修復型のインフラを提供します。

データとしてのインフラ(Infrastructure as Data)

インフラをKubernetesオブジェクトとして扱うことで、既存の使い慣れたツールを利用できます。デバッグには kubectl、可視化には k9s、デプロイには ArgoCD を使用できます。私の経験上、この橋渡しによって開発者が自分たちのクラウドリソースに責任を持つようになります。HCLを学んだり、DevOpsエンジニアがパイプラインを実行するのを待つ必要はもうありません。

コンポジション(Composition)パターン

コンポジションは、Crossplaneの最も強力な機能です。複雑なリソースをまとめて、独自のカスタムAPIを作成できます。例えば、StandardDatabase オブジェクトを作成すると、開発者がそのオブジェクトを1つ作るだけで、Crossplaneが裏側でRDSインスタンス、必要なセキュリティグループ、プライベートサブネットグループを自動的にプロビジョニングするように設定できます。

高度な活用法:GitOpsワークフロー

Crossplaneを最大限に活用するには、ArgoCDと組み合わせます。このセットアップにより、Gitが絶対的な信頼できる情報源(Source of Truth)となる、自動化された環境が構築されます。リポジトリ構造は以下のようになります。

  • /infra/providers/: インストールするクラウドプロバイダーを定義。
  • /infra/definitions/: カスタムコンポジション(設計図)。
  • /apps/production/resources/: 実際のインフラリクエスト(インスタンス)。

バケットのタグを更新するPRをマージすると、ArgoCDが変更をクラスターに同期します。その後、Crossplaneが即座にクラウドリソースを更新します。破損する可能性のあるローカルの状態ファイルも、手動で実行する terraform plan コマンドも不要です。

現場からの実践的なヒント

いくつかの大規模な環境をCrossplaneに移行した経験から、いくつかの重要なベストプラクティスを特定しました。

1. 細分化されたプロバイダーを使用する

オールインワンの provider-aws は避けてください。数千のCRDをロードしようとするため、クラスターのAPIサーバーが重くなる可能性があります。provider-aws-rdsprovider-aws-ec2 のようなファミリープロバイダーを使用して、管理クラスターの軽快さと効率を維持しましょう。

2. シークレットの保護

Crossplaneは、データベースのパスワードなどの機密データをKubernetes Secretに書き込みます。これらをリポジトリにプレーンテキストで放置しないでください。External Secrets Operator を使用して、これらの値をAWS Secrets ManagerやHashiCorp Vaultなどの安全なボルトと同期させてください。

3. Orphan削除ポリシーの使用

デフォルトでは、Kubernetes上のYAMLファイルを削除すると、AWS上のリソースも削除されます。移行中、これは危険です。リソースのスペックに deletionPolicy: Orphan を追加しましょう。これにより、YAMLが削除されても、実際のクラウド上のリソースを削除せずにCrossplaneの管理対象から外すよう指示できます。

4. 一度にすべてを移行しない

明日すぐにTerraformのコードを削除する必要はありません。Crossplaneは既存のツールと完璧に共存できます。まずはSQSキューやS3バケットのようなシンプルなリソースの移行から始めましょう。基礎となるネットワーキング(VPCやサブネット)はTerraformに任せ、変更頻度の高いアプリケーションリソースをCrossplaneで管理するようにします。

Kubernetesネイティブなコントロールプレーンへの移行は、真のプラットフォームエンジニアリングに向けた大きな一歩です。手動のトリガーを、インフラを常に理想の状態に保つために24時間365日動作する自己修復システムに置き換えることができます。

Share: