36
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

様々なリソースをKubernetesの管理に統一するCrossplaneについて

Posted at

はじめに

今年もこの季節がやってまいりました。本年もOpenStandiaでAdvent Calendarを書いていきます。今年は特にテーマは決めずOpenStandiaのメンバが興味のある技術について25日間書いていきますのでよろしくお付き合いください!

crossplaneについて

1日目はさっそく今年Could Native Computing Foundation(CNCF)の Incubating project になったcrossplaneを評価してみました。
image.png

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にインストールすると、さまざまなリソースが作られます。その中で重要なものを紹介します。軽く概要を示す図を貼っておきます。

image.png
軽く説明すると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で実現しようとすると下記の構成になります。
image2022-10-17_11-37-28.png
また同じような考え方を用いることで、コンテナ基盤(例: ECS, Cloud Run, GKEなど)の抽象化も可能かなと考えています。image.png
上記の例だと、例えばコンテナイメージ自体やバージョンをclaimに指定させて、状況によってCompositionを変えることで、同じ構成のアプリケーションがたくさん増やすことができるのかなと感じました。

ただし、このComposite Resource、composite resource definitionを各クラウドリソースの特徴を理解して、作成するスーパーマンみたいな人が必要かなと感じています。さらに作成した後、この方式を運用しなければならず、いろいろ検討するところはありそうです。Crossplane自体は、OpenApplicationModelのKubernetes実装としていて、運用面としては基盤チーム、アプリチームから、新しく第3のチームとしてのアプリ運用チームといった組織が面倒をみていく想定になっているようです。

参考リンク

36
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?