はじめに
今年もこの季節がやってまいりました。本年もOpenStandiaでAdvent Calendarを書いていきます。今年は特にテーマは決めずOpenStandiaのメンバが興味のある技術について25日間書いていきますのでよろしくお付き合いください!
crossplaneについて
1日目はさっそく今年Could Native Computing Foundation(CNCF)の Incubating project になったcrossplaneを評価してみました。
crossplaneってなんぞやということで公式サイトをまずは見てみました。どうやら下記のように書かれています。
https://crossplane.io/
#上の方にあるDocumentationからたどれます。
Crossplane is an open source Kubernetes add-on that transforms your cluster into a universal control plane. Crossplane enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume, without having to write any code.
CrossplaneはKubernetesクラスタを普遍的なコントロールプレーンへ変換するためのKubernetesのアドオンです。これによってプラットフォームチームが新しくコードを書くことになしに、様々なインフラを組み合わせたり、アプリチームが利用するためにKubernetesのAPIを公開することが可能になる。と書いています。いきなりこういわれてもわからんと思いますので、簡潔にまとめると主に下記の2つができるようになります。
- AWSやGCPなどのクラウドベンダーが提供するインフラや、Kubernetes/Helmなどのソフトウェアが提供するリソースを統合的にKubenetesで管理できるようになる。
- 上記のリソースを組み合わせたリソースを作成し、それに対応する新しいKubernetesのAPIを公開することができる。
つまり、いろいろなものがYAML化していきますね。YAMLおじさんの皆さん、おめでとうございます(白目)
リソースをKubernetesで管理する
KuberentesにCrossplaneのProviderを入れることで、そのカスタムリソース定義(CRD)などが作成され、アクセストークンなどの認証情報を用いて、そのカスタムリソースが作成されると、対応するリソースが作成されます。
2022年12月現在で対応しているProviderは下記になります。
- aws
- azure
- gcp
- alubaba
- kubernetes
- helm
- newrelic
- gitlab
などなど他にもあります。詳細はこちらを確認ください。https://marketplace.upbound.io/providers
上記のベンダのリソース(たとえば、RDS)は下記のようなマニフェストで表現されています。このようなベンダ毎に作成されるリソースのことをcrossplaneではmanaged resource
と呼んでいます。
apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
metadata:
name: rdspostgresql
spec:
forProvider:
region: us-east-1
dbInstanceClass: db.t2.small
masterUsername: masteruser
allocatedStorage: 20
engine: postgres
engineVersion: "12"
skipFinalSnapshotBeforeDeletion: true
writeConnectionSecretToRef:
namespace: crossplane-system
name: aws-rdspostgresql-conn
新しいリソースを作成し、KubernetesのAPIで公開する
crossplaneをKubernetesにインストールすると、さまざまなリソースが作られます。その中で重要なものを紹介します。軽く概要を示す図を貼っておきます。
軽く説明するとManaged Resource(MR)の集合体をComposite Resource(XR)といい、その利用までのインターフェースのことをCompositionResourceDefinition(xRD)と言います。xRDを基にclaimを使って実際のXRを作成します
Composite Resource(複合リソース,XR)
Composite Resourceとは1つ以上のManaged Resourceからなるリソースです。。例えばAWSではネットワークが使えるようになるためには、VPCだったり、Subnetだったり、InternetGWなどなどを組み合わせることが前提となっており、その組み合わせたものを一つのKubernetesリソースとして扱うことができます
Composite Resourceのマニフェストの例としては下記になります。
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: example
labels:
crossplane.io/xrd: xpostgresqlinstances.database.example.org
provider: gcp
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef: # ★1
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: cloudsqlinstance
base:
apiVersion: database.gcp.crossplane.io/v1beta1
kind: CloudSQLInstance
spec:
forProvider:
databaseVersion: POSTGRES_12
region: us-central1
settings:
tier: db-custom-1-3840
dataDiskType: PD_SSD
ipConfiguration:
ipv4Enabled: true
authorizedNetworks:
- value: "0.0.0.0/0"
patches: #★2
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.storageGB
toFieldPath: spec.forProvider.settings.dataDiskSizeGb
★1部分については、resource以下で定義されているMRをまとめたリソースのAPIを公開するためのapiVersionとkindを設定している。また★2については、公開したAPIからどのようなValueが入り、それがresource配下のどのパラメータに対応するのかを定義している。
Composite Resource Definition(複合リソース定義, XRD)
Composite Resource Definitionとは、作成したいCompositionのスキーマを定義するためのリソースです。実際にアプリチームとしては、このXRDによって定義されたAPIに対してマニフェストを作成し、Compositionを作成します。Compositionはクラウドベンダの色が出るパラメータになっていますが、うまくクラウドベンダ専用のものがなくなるようにXRDを定義することによって、同じマニフェストでAWSやAzure、GCPの同じようなリソースを作成できます。
xRDのマニフェストの例としては下記の通り。これは、DBのストレージサイズを求めるようなAPIを公開している。
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresqlinstances.database.example.org
spec:
group: database.example.org
names:
kind: XPostgreSQLInstance # ☆1
plural: xpostgresqlinstances
claimNames:
kind: PostgreSQLInstance
plural: postgresqlinstances
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
storageGB:
type: integer
required:
- storageGB
required:
- parameters
★1部分では定義したCompositionのKind名を指定する。ちょうどXRのマニフェストの例の★1部分が該当する。
Claim
上記xRDで公開したKubernetesのAPIを通して実際に利用するためのリソースをClaimと言います。Claimというと、PersistentVolumeClaimがあるのですが、考え方としては同じで、ユーザの要求に従ってCompositionResourceが払い出されます。マニフェストの例としては下記になります。
apiVersion: database.example.org/v1alpha1
kind: PostgreSQLInstance
metadata:
namespace: default
name: my-db
spec:
parameters:
storageGB: 20
compositionRef:
name: production
writeConnectionSecretToRef:
name: my-db-connection-details
触ってみる
それでは実際にCrossplaneを触ってみましょう。
実行環境
- MacOS Monterey
- minikube v1.26.0
- helm v3.9.2
- crossplane ver1.10.1
crossplaneのインストール
$ kubectl create ns crossplane-system
namespace/crossplane-system created
$ helm install crossplane --namespace crossplane-system crossplane-stable/crossplane
NAME: crossplane
LAST DEPLOYED: Sun Nov 27 18:23:32 2022
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.10.1
Chart Application Version: 1.10.1
Kube Version: v1.24.1
$ kube get po -n crossplane-system
NAME READY STATUS RESTARTS AGE
crossplane-7d4bbdd8dd-dpmdb 1/1 Running 0 2m11s
crossplane-rbac-manager-7f9b4f6d47-zp8mx 1/1 Running 0 2m11s
$ curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh
kubectl plugin downloaded successfully! Run the following commands to finish installing it:
sudo mv kubectl-crossplane /usr/local/bin
kubectl crossplane --help
Visit https://crossplane.io to get started. 🚀
Have a nice day! 👋
Providerのインストール
$ cat provider.yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws
namespace: crossplane-system
spec:
package: "xpkg.upbound.io/crossplane-contrib/provider-aws:v0.34.0"
$ kubectl apply -f provider.yaml
provider.pkg.crossplane.io/provider-aws created
$ kubectl get provider -n crossplane-system
NAME INSTALLED HEALTHY PACKAGE AGE
provider-aws True True xpkg.upbound.io/crossplane-contrib/provider-aws:v0.34.0 52s
$ AWS_PROFILE=default && echo -e "[default]\naws_access_key_id = $(aws configure get aws_access_key_id --profile
$AWS_PROFILE)\naws_secret_access_key = $(aws configure get aws_secret_access_key --profile $AWS_PROFILE)" >
creds.conf
$ cat creds.conf
[default]
aws_access_key_id = XXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
$ kubectl create secret generic aws-creds -n crossplane-system --from-file=./creds.conf
secret/aws-creds created
$ kubectl get secret -n crossplane-system
NAME TYPE DATA AGE
aws-creds Opaque 1 15s
composite resource definitionの作成
$ kubectl apply -f definition.yaml
compositeresourcedefinition.apiextensions.crossplane.io/xpostgresqlinstances.database.example.org created
$ kubectl get xrd
NAME ESTABLISHED OFFERED AGE
xpostgresqlinstances.database.example.org True True 12s
composite resourceの作成
$ kubectl apply -f composition.yaml
composition.apiextensions.crossplane.io/xpostgresqlinstances.aws.database.example.org created
$ kubectl get composition
NAME AGE
xpostgresqlinstances.aws.database.example.org 70s
claimを通して、compotisionの作成
$ kubectl apply -f claim.yaml
postgresqlinstance.database.example.org/my-db created
$ kubectl get rdsinstance
NAME READY SYNCED STATE ENGINE VERSION AGE
my-db-s66fm-f88f6 True True available postgres 12.11 7m58s
備考: crossplane で作成されたリソースは下記のように確認可能
$ kubectl get claim
NAME SYNCED READY CONNECTION-SECRET AGE
my-db True True db-conn 9m48s
$ kubectl get composite
NAME SYNCED READY COMPOSITION AGE
my-db-s66fm True True xpostgresqlinstances.aws.database.example.org 9m57s
$ kubectl get managed
NAME READY SYNCED STATE ENGINE VERSION AGE
rdsinstance.database.aws.crossplane.io/my-db-s66fm-f88f6 True True available postgres 12.11 10m
感想
ちょうど上の例をGCPのCloudSQLで実現しようとすると下記の構成になります。
また同じような考え方を用いることで、コンテナ基盤(例: ECS, Cloud Run, GKEなど)の抽象化も可能かなと考えています。
上記の例だと、例えばコンテナイメージ自体やバージョンをclaimに指定させて、状況によってCompositionを変えることで、同じ構成のアプリケーションがたくさん増やすことができるのかなと感じました。
ただし、このComposite Resource、composite resource definitionを各クラウドリソースの特徴を理解して、作成するスーパーマンみたいな人が必要かなと感じています。さらに作成した後、この方式を運用しなければならず、いろいろ検討するところはありそうです。Crossplane自体は、OpenApplicationModelのKubernetes実装としていて、運用面としては基盤チーム、アプリチームから、新しく第3のチームとしてのアプリ運用チームといった組織が面倒をみていく想定になっているようです。
参考リンク