次世代のIaC OSS「Crossplane」のQuickStartを試してみた #Crossplane #Kubernetes #GCP
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
Infrastructure as Code (IaC) と聞くと、Terraformや、たびたび当方でも紹介するPulumiなどが思い浮かびますが、インフラストラクチャの状態監視が可能と言われる、次世代のIaC OSS「Crossplane」について調査して、実際にGoogleCloudのリソースのプロビジョニングを試してみましたので、簡単にご紹介します。Crossplane初学者である当方ですが、Crossplane自体を詳しく知ったきっかけは 2023年7月20日 ~ 21日に開催された弊社イベント「Engineering All Hands」のLT大会でした(菅野さん、ご紹介いただきありがとうございました)。GoogleCloudでも似たような仕組みに「Anthos Config Management」があり、当方が携わる案件でよく触っているので、Crossplaneはどんなものかと、興味を持った次第です。
Crossplane について
概要
米国シアトルに会社を持つ Upboud が2018年に公開したオープンソースソフトウェアです。コンセプトは以下のように紹介されています(カッコ内はGoogle翻訳したものです)
https://www.crossplane.io/why-control-planes
- Declarative configuration
(宣言的な構成)- Unify application and infrastructure configuration and deployment
(アプリケーションとインフラストラクチャの構成と展開を統合)- One source of truth for infrastructure configuration and setup
(インフラストラクチャの構成とセットアップのための 1 つの信頼できる情報源)- Automate operational tasks with reconciling controllers
(調整コントローラーによる運用タスクの自動化)- Built with high levels of extensibility
(高度な拡張性を備えた構築)- A strong separation of concerns
(懸念事項の強力な分離)
他のIaCツールでも似たようなコンセプトはよく見かけますが、特にCrossplaneで特徴的な点として「Automate operational tasks with reconciling controllers (調整コントローラーによる運用タスクの自動化)」が挙げられます。要はインフラストラクチャの状態を監視して、Crossplaneで宣言された状態と差分があれば、都度インフラストラクチャを修正する機能を有するとのことです。その実装として、Kubernetes Resource Model (KRM)を利用して拡張したものが「Crossplane」となり、KRMの宣言型かつ常時調整型の特性をGoogle CloudやAWSなど、複数のクラウドプロバイダにCrossplaneが活用できます。Terraformなどで一度デプロイしたインフラが、何かの拍子に実体のリソース設定が変更されちゃって、Terraformのコードが正しいのか、実体のリソース設定が正しいのか分からないケースが度々あるので、Crossplaneで「調整」してくれるのはとても便利ですね。
Crossplaneの構成要素
Crossplaneのコンセプトとして、以下のように紹介されています。
Packages
Crossplaneの機能を拡張されるものです。CrossplaneはKubernetesを利用するので、Kubernetes CRDs と controller のセットを追加するイメージですね。
Providers
Google Cloud / AWS / Azure などの外部サービスにリソースをプロビジョニングするための、前述のPackageとして提供されるのが Provider になります。サービス × リソース種別 毎に Provider が Crossplane で用意されているので、利用したい Provider があれば以下のようにClusterにインストールします(以下ではGoogle CloudのGCSのProviderをインストール)
$ cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-gcp-storage
spec:
package: xpkg.upbound.io/upbound/provider-gcp-storage:v0.35.0
EOF
Managed Resources
例えば Google Cloud だと こちらのAPIリファレンスのように、各 Provider (Google Cloudなど) のリソース(Compute Engine Instance / Google Cloud Storage など)と1対1で対応するのがこの Managed Resource で、Kubernetes の Custom Resource になります。例えば Storage Bucket の Managed Resource だと、以下のようなmanifestがCrossplaneにデプロイされることで、Providerを通じて Google Cloud にリソースがプロビジョニングされ、実際にGoogle Cloudにリソースが作成されるイメージです。
apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
metadata:
annotations:
meta.upbound.io/example-id: storage/v1beta1/notification
labels:
testing.upbound.io/example-name: bucket
name: bucket-${Rand.RFC1123Subdomain}
spec:
forProvider:
location: US
Composite Resources
1つ以上のManaged Resourceから構成されるもので、例えばネットワークに関連する「VPC/Subnet/Routing」などのリソースを1つのComposite Resourceにまとめることができます。他のComposite Resourceを別のComposite Resourceに含めることも可能です。例えば以下では VPC/InternetGateway/Subnet の Managed Resource と、あらかじめ別に作成している Composite Resource を、1つのComposite Resource にまとめています。
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
spec:
resources:
- name: vpc-resource
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
# Removed for Brevity
- name: gateway-resource
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: InternetGateway
# Removed for Brevity
- name: subnet-resource
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
# Removed for Brevity
compositeTypeRef:
apiVersion: aws.platformref.upbound.io/v1alpha1
kind: XNetwork
Anthos Config Managementとの比較
Google Cloud にも似たようなサービスに「Anthos Config Management (ACM)」があります。弊社のBlogでも紹介していますが、ACMは「Policy Controller -> ポリシーチェック機能」「Config Sync -> GitOps機能」「Config Controller -> Google Cloud リソースのプロビジョニング」の3つのコンポーネントで構成されますが、Crossplaneはこのうち(筆者の理解としては)、「Config Controller」の機能に該当すると思います。ただし、ACMはGoogle Cloudのリソースに特化したサービスで、対してCrossplaneはGoogle Cloudの他、AWS/Azure/更にはTerraformなどのProviderが用意されていますので、「Google Cloud以外のサービスについても、1つの control plane を用意したい」場合などは、Crossplaneを試してみても良いかもしれません。ただし、ACMに似たことをCrossplaneで実施する場合、Policy ControllerやConfig Syncなどの機能は、他のThird-partyを利用して自身で組み上げる必要がありますので、Google Cloudのみでの利用を想定している場合は、公式ドキュメントの充実度などを考慮すると、素直にACMを利用した方が良いかもしれません。
Crossplane 試してみた
今回はGoogle Cloudのリソースについて、Crossplaneを利用してプロビジョニングしてみました。基本的な流れは公式のQuickstartをもとに実施しています。
前提
- Google Cloud リソースを作成可能な一通りの権限を有する (Google Kubernetes Engine Clusterの接続/pods,secreetの作成/Google Compute Engine Instanceの作成)
- Google Cloud で Project/GKE Clusterを作成済み
- Kubernetes関連の基本的な知識 (kubectl/Helmの利用など)
構成
- Google Cloud の 1つのProjectにGKE(Google Kubernetes Engine)/GCE(Google Compute Engine)などの必要なリソースをデプロイします
- GKEにCrossplaneをデプロイします
- GCEのManageed ResourceをCrossplaneでデプロイして、実際にGCEのリソースをGoogle Cloudにプロビジョニングします
手順
Crossplane インストール
- CloudShell を起動して、対象のGKE Clusterに接続します。筆者の環境では project: CloudSolution-Blog の GKE Cluster: cs-cluster-1 に接続しています。
- Crossplane Helm Chart レポジトリを追加します
$ helm repo add \
crossplane-stable https://charts.crossplane.io/stable
"crossplane-stable" has been added to your repositories
- Crossplane Helm Chart をインストールします(インストール前に一度dry-run実施)
$ helm install crossplane crossplane-stable/crossplane --dry-run --debug --namespace crossplane-system --create-namespace
---
$ helm install crossplane \
crossplane-stable/crossplane \
--namespace crossplane-system \
--create-namespace
NAME: crossplane
LAST DEPLOYED: Fri Aug 18 08:48:40 2023
NAMESPACE: crossplane-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Release: crossplane
Chart Name: crossplane
Chart Description: Crossplane is an open source Kubernetes add-on that enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume.
Chart Version: 1.13.2
Chart Application Version: 1.13.2
Kube Version: v1.27.3-gke.100
- Crossplane関連のリソースが起動しているか確認します
$ kubectl get pods -n crossplane-system
NAME READY STATUS RESTARTS AGE
crossplane-8697f8cff4-qgbk5 1/1 Running 0 36s
crossplane-rbac-manager-6f8dbd9ffd-g8wjh 1/1 Running 0 36s
- Crossplaneに関連するKubernetes APIが新しく追加されているか確認します
$ kubectl api-resources | grep crossplane
compositeresourcedefinitions xrd,xrds apiextensions.crossplane.io/v1 false CompositeResourceDefinition
compositionrevisions comprev apiextensions.crossplane.io/v1 false CompositionRevision
compositions comp apiextensions.crossplane.io/v1 false Composition
environmentconfigs envcfg apiextensions.crossplane.io/v1alpha1 false EnvironmentConfig
configurationrevisions pkg.crossplane.io/v1 false ConfigurationRevision
configurations pkg.crossplane.io/v1 false Configuration
controllerconfigs pkg.crossplane.io/v1alpha1 false ControllerConfig
locks pkg.crossplane.io/v1beta1 false Lock
providerrevisions pkg.crossplane.io/v1 false ProviderRevision
providers pkg.crossplane.io/v1 false Provider
storeconfigs secrets.crossplane.io/v1alpha1 false StoreConfig
GCP Provider インストール
- 以下のmanifestでGCP Providerをインストールします
$ cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-gcp-compute
spec:
package: xpkg.upbound.io/upbound/provider-gcp-compute:v0.35.1
EOF
provider.pkg.crossplane.io/provider-gcp-compute created
- 該当のProviderがインストールされていることを確認します。ちなみに
upbound-provider-family-gcp
はFamily Providerと呼ばれていて、Google Cloudの認証を管理するProviderで、GCE以外の全ての(Google Cloud関連の)Providerをインストールしても、このFamily Providerが用意されます。
$ kubectl get provider
NAME INSTALLED HEALTHY PACKAGE AGE
provider-gcp-compute True True xpkg.upbound.io/upbound/provider-gcp-compute:v0.35.1 9m39s
upbound-provider-family-gcp True True xpkg.upbound.io/upbound/provider-family-gcp:v0.35.1 23m
- Compute リソースに関連したKubernetes CRDsがインストールされているのを確認します
$ kubectl get crds | grep compute
addresses.compute.gcp.upbound.io 2023-08-18T09:22:32Z
attacheddisks.compute.gcp.upbound.io 2023-08-18T09:22:32Z
autoscalers.compute.gcp.upbound.io 2023-08-18T09:22:32Z
backendbuckets.compute.gcp.upbound.io 2023-08-18T09:22:32Z
backendbucketsignedurlkeys.compute.gcp.upbound.io 2023-08-18T09:22:32Z
backendservices.compute.gcp.upbound.io 2023-08-18T09:22:32Z
backendservicesignedurlkeys.compute.gcp.upbound.io 2023-08-18T09:22:32Z
diskiammembers.compute.gcp.upbound.io 2023-08-18T09:22:32Z
diskresourcepolicyattachments.compute.gcp.upbound.io 2023-08-18T09:22:32Z
disks.compute.gcp.upbound.io 2023-08-18T09:22:32Z
~~~
instancegroupmanagers.compute.gcp.upbound.io 2023-08-18T09:22:33Z
instancegroupnamedports.compute.gcp.upbound.io 2023-08-18T09:22:33Z
instancegroups.compute.gcp.upbound.io 2023-08-18T09:22:33Z
instanceiammembers.compute.gcp.upbound.io 2023-08-18T09:22:33Z
instances.compute.gcp.upbound.io 2023-08-18T09:22:34Z
instancetemplates.compute.gcp.upbound.io 2023-08-18T09:22:34Z
interconnectattachments.compute.gcp.upbound.io 2023-08-18T09:22:33Z
managedsslcertificates.compute.gcp.upbound.io 2023-08-18T09:22:33Z
Kubernetes Secret 作成
ProviderでGoogle Cloudリソースを作成するために必要となるクレデンシャルをKubernetes Secretとして用意します
- Google Cloud コンソールでService Account を作成します。筆者は「crossplane-sa」という名前でService Accountを作成しました
- Google Cloud コンソールのIAM画面で、作成したService Accountに「Compute 管理者」ロールを付与します
- Service Accountの画面に戻って、該当SAの認証鍵(json)を作成します
- Cloud Shellに戻って、作成した認証鍵(json)をCloud Shellにアップロードします。筆者は分かりやすいように、認証鍵のファイル名を「crossplane-sa.json」に変更してからアップロードしました
- アップロードした認証鍵(json)をもとに、以下コマンドでKubernetes Secretを作成します。
--from-file
には、アップロードした認証鍵のPathを指定します
$ kubectl create secret \
generic gcp-secret \
-n crossplane-system \
--from-file=creds=./crossplane-sa.json
secret/gcp-secret created
- 作成したsecretを確認します
$ kubectl describe secret gcp-secret -n crossplane-system
Name: gcp-secret
Namespace: crossplane-system
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
creds: 2374 bytes
ProviderConfig 作成
Google Cloud Providerをカスタマイズするためのリソース「ProviderConfig」を作成します
- 以下コマンドで ProviderConfig を作成します。
spec.projectID
には、ご自身が用意した Google Cloud Project の ID を指定します(筆者の場合はcloudsolution-blog
になります)
$ cat <<EOF | kubectl apply -f -
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
projectID: cloudsolution-blog
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: gcp-secret
key: creds
EOF
Managed Resource 作成
一通りの準備が整ったので、いよいよ Managed Resource を作成して、実際にリソースをGoogle Cloudにプロビジョニングします。
- Compute Engine InstanceのAPIリファレンスを参考に、以下manifestを作成してデプロイします。
cat <<EOF | kubectl create -f -
apiVersion: compute.gcp.upbound.io/v1beta1
kind: Instance
metadata:
annotations:
meta.upbound.io/example-id: compute/v1beta1/testinstance
labels:
testing.upbound.io/example-name: test-instance
name: test-instance
spec:
forProvider:
bootDisk:
- initializeParams:
- image: debian-cloud/debian-11
machineType: e2-medium
networkInterface:
- network: default
zone: asia-northeast1-a
EOF
- Kubernetes側でリソースが作成されていることを確認します
$ kubectl get Instance
NAME READY SYNCED EXTERNAL-NAME AGE
test-instance True True test-instance 33s
- Google Cloud のコンソール画面で、該当のリソースが無事プロビジョニングされているのが確認できます
Crossplaneによるリソース自動調整確認
「要はインフラストラクチャの状態を監視して、Crossplaneで宣言された状態と差分があれば、都度インフラストラクチャを修正する機能を有する」とのことで、試しにGoogle Cloud側でCrossplaneで作成したリソースの設定を変えてみて、Crossplaneで自動修正されるか確認してみます。
- Google Cloud コンソールで該当インスタンスを「停止」してから、「編集」をクリックします
- マシンタイプを「E2」から「N2」に上げて、保存します
- 保存後、数分(筆者の環境だと 5分くらい)待つと、「N2」から自動的に「E2」に戻るのが確認できました。
↓
自動調整も無事行われていそうですね(ちなみに、一部フィールドは自動調整されないケースがあるようです)
Managed Resource 削除
- Cloud Shellに戻り、以下コマンドでリソースを削除します。
--selector
にリソースのラベルを指定して削除します。
$ kubectl get Instance
NAME READY SYNCED EXTERNAL-NAME AGE
test-instance True True test-instance 27m
---
$ kubectl delete Instance test-instance
instance.compute.gcp.upbound.io "test-instance" deleted
- Google Cloud コンソール画面に戻ると、該当インスタンスが削除されているのが確認できます
感想
今回はGoogle CloudリソースのCrossplaneによるプロビジョニングを試してみたのですが、Crossplaneのインストールから実際のリソースプロビジョニングまであまり手間が掛からず、リソースの宣言もyamlで記載することができるので、ヤムラー?(yaml使い)の方にとっても嬉しいポイントではないでしょうか?IaCについてはTerraformが浸透している昨今ですが、ライセンス変更の件もあり、この機会に、色々なIaCツールを試してみたいと思いました。