TT Lab
はじめる
学ぶ 学習パス コース

CKA — Kubernetes管理者

CRDでAPIを広げる

TT Labで続きを見る

目標

CustomResourceDefinitionを自分で書いてKubernetesのAPIを拡張し、スキーマ検証が実際にリクエストを拒否することを確認し、新しいリソースに対する権限をAggregated ClusterRoleで付与します。

なぜ重要なのか

CKAの出題範囲にCRDが入っているのは、Operatorを作れという意味ではありません。Operatorが導入されたクラスターを運用できるかを問うているのです。現場のクラスターには、すでに数十個のCRDが導入されています。

ここで理解すべき構造があります。CRDを作るとapiserverに新しいエンドポイントができ、そのエンドポイントは、保存・検証・watchを提供します。しかし、それだけです。実際に何かを行うのは、そのCRをwatchするコントローラーであり、それは別のソフトウェアです。CRを作ったのに何も起きないなら、たいていはコントローラーがないか、死んでいるのです。

スキーマも同じ文脈です。apiextensions.k8s.io/v1では、schemaは任意ではなく必須です。スキーマがそのAPIの契約であり、不正な値を、コントローラーではなくapiserverが先に防いでくれます。

ステップ

  1. CRDwidgets.labhub.ioを作成してください。grouplabhub.io、scopeNamespaced、kindWidget、pluralwidgets、singularwidget、shortNamesにwg、バージョンはv1alpha11つで、servedとstorageはどちらもtrueです。
  2. ネームスペースcka-crdを作成し、その中にWidgetdemoを作成してください。spec.replicasは3、spec.tierはsmallです。
  3. CRDのv1alpha1のスキーマを修正して、検証ルールを入れてください。spec.replicasはtypeintegerで、minimum 1、maximum 10です。spec.tierはtypestringで、enum[small, large]です。specオブジェクトのrequiredは[replicas, tier]です。
  4. spec.replicasが99のWidgettoo-bigを作成してみて、拒否されたエラー出力を/root/cka-crd/reject.txtに保存してください。too-bigは作成されていてはいけません。
  5. v1alpha1にadditionalPrinterColumnsを2つ追加してください。名前REPLICAS(typeinteger、jsonPath.spec.replicas)、名前TIER(typestring、jsonPath.spec.tier)です。
  6. CRDclusterwidgets.labhub.ioを作成してください。scopeCluster、kindClusterWidget、pluralclusterwidgets、grouplabhub.io、バージョンv1alpha1です。そしてClusterWidgetglobalを作成してください。
  7. ClusterRolecka-widget-viewerを作成してください。ラベルはrbac.labhub.io/aggregate-to-widget=true、ルールはapiGroupslabhub.ioのwidgetsに対するget、list、watchです。そしてClusterRolecka-widget-aggregateを作成し、aggregationRuleがそのラベルをセレクターとして選ぶようにしてください。

参考

CustomResourceDefinitionを作成する

CRDwidgets.labhub.ioを作成してください。grouplabhub.io、scopeNamespaced、kindWidget、pluralwidgets、singularwidget、shortNamesにwg、バージョンはv1alpha11つで、servedとstorageはどちらもtrueです。

CRDのmetadata.nameは、必ず「複数形.グループ」の形式である必要があります。apiextensions.k8s.io/v1では、versions配列の各項目にschemaが必須です。

カスタムリソースを作成する

ネームスペースcka-crdを作成し、その中にWidgetdemoを作成してください。spec.replicasは3、spec.tierはsmallです。

CRのapiVersionは「グループ/バージョン」です。スキーマが緩いと任意のフィールドが入ってしまうので、まずspecの下に未知のフィールドを許可しておくと楽です。

スキーマに検証ルールを入れる

CRDのv1alpha1のスキーマを修正して、検証ルールを入れてください。spec.replicasはtypeintegerで、minimum 1、maximum 10です。spec.tierはtypestringで、enum[small, large]です。specオブジェクトのrequiredは[replicas, tier]です。

openAPIV3Schemaの中のproperties.spec.propertiesの下に、フィールドごとのtypeとminimum/maximum/enumを付けます。requiredは値ではなく、そのオブジェクトレベルの配列です。

検証が拒否する瞬間を確認する

spec.replicasが99のWidgettoo-bigを作成してみて、拒否されたエラー出力を/root/cka-crd/reject.txtに保存してください。too-bigは作成されていてはいけません。

エラーは標準出力ではなく、標準エラー出力に出ます。リダイレクトするときは、2>&1を忘れないでください。拒否されたリソースは、作成されていないのが正常です。

kubectl getの出力にカラムを追加する

v1alpha1にadditionalPrinterColumnsを2つ追加してください。名前REPLICAS(typeinteger、jsonPath.spec.replicas)、名前TIER(typestring、jsonPath.spec.tier)です。

additionalPrinterColumnsは、versions配列の各バージョンの中に入ります。name、type、jsonPathの3つのフィールドが必要で、jsonPathはドットで始まります。

クラスタースコープのCRDを作成する

CRDclusterwidgets.labhub.ioを作成してください。scopeCluster、kindClusterWidget、pluralclusterwidgets、grouplabhub.io、バージョンv1alpha1です。そしてClusterWidgetglobalを作成してください。

scopeは、CRDを作成したあとでは変更できません。クラスタースコープのリソースは、-nオプションを受け付けません。

Aggregated ClusterRoleで権限を広げる

ClusterRolecka-widget-viewerを作成してください。ラベルはrbac.labhub.io/aggregate-to-widget=true、ルールはapiGroupslabhub.ioのwidgetsに対するget、list、watchです。そしてClusterRolecka-widget-aggregateを作成し、aggregationRuleがそのラベルをセレクターとして選ぶようにしてください。

aggregationRuleのあるClusterRoleのrulesは、直接書きません。ラベルの付いたほかのClusterRoleを、コントローラーが見つけて統合してくれます。