Kubernetesは、コンテナオーケストレーションを実現するための主要ツールの一つです。API面では、REST APIやYAMLファイルを用いて、APIの状態や目的を明確に示すインタラクティブな仕組みを提供します。
k8sリソースは、API使用時に必要なオブジェクトを確実に保持します。しかし、標準リソースだけで十分でしょうか。そこで登場するのがk8sカスタムリソースです。詳しくは以下をご覧ください。
K8s v1.7は、貴社の要件に合わせたリソース作成が可能です。この機能により、どのAPIオブジェクトも簡単に利用でき、モジュール式のKubernetes API拡張として捉えることができます。
開発者は必要な機能を追加し、標準リソースと同様に新たに設計されたカスタムリソースを利用できます。以下に、カスタムリソースに関するいくつかの事実を示します:
カスタムリソースを明確に記述するため、K8sカスタムリソース定義は必習です。これにより、カスタムで作成されたリソースを利用できるようになります。
CRDの意味は、エンドユーザーがKubernetesを自由にカスタマイズするための補助機能とも言えます。そのため、APIは拡張され、カスタマイズ可能な状態になる必要があります。これによって初めてリソースのカスタム構築が可能となります。
CRD単体ではほとんど役に立たず、単なるデータを示すだけです。宣言的な運用を実現するため、カスタムコントローラーを利用して現状と期待状態を一致させる必要があります。この仕組みにより、Kubernetesのカスタマイズに必要な動作が拡張されます。
CRDをより深く理解するため、以下の内容にご注目ください。
さらに、CRDに関連する処理はkube-apiserver内で行われ、k8sのコントロールプレーンの一部であるapiextensions-apiserverモジュールが担当します。
CRDは、k8sシステムとの卓越した互換性で知られています。ほとんどのk8sコンポーネント、例えばAPIクライアント、UIツール、CLIと最適に連携します。
これらのコンポーネントを活用した開発を目指す場合、CRDの利用を強くお勧めします。
一方、シンプルな開発手法を求める際にはCRDは最適とは言えません。扱いやすいとはいえ、手間がかかるため、十分な労力をかけられる場合にのみ使用してください。
CRDを効果的に扱うには熟練した技術が必要です。Kubernetesに不慣れな開発者は、CRDの利用を控えた方が良いでしょう。
CRDはカスタマイズに有用ですが、すべての状況に最適というわけではありません。効果的に利用すれば最良の成果が得られます。例えば、開発目標がCI/CDプラットフォームの構築や、ライフサイクル管理を担うアプリのホスティングであると仮定します。
この場合、開発者はアプリの開発、テスト、公開を支援するパイプラインを構築する必要があり、アプリのデプロイにはKubernetesクラスターが利用されます。
しかし、既定のKubernetesクラスターだけでは全てのデプロイ要求に応えられないため、カスタムリソースを用いてk8s APIの機能拡張を図ることが可能です。これにより、ITチームがアプリ開発中にセルフサービスで作業を進められるようになります。
次に、CRDの使用例を見ていきます。前述の例では、k8sカスタムリソースはユーザーの入力を必要とします。入力がなければ、Kubernetesの構築は難しくなります。
この目標達成のための最低限のセットアップ要件は次の通りです:
これらの前提条件を元に、例示した顧客向けリソースのCRD構築を始めてください。
k8s APIは、CRDの各バージョンについて、クラスター単位または名前空間単位の新たなRESTfulリソースパスを自動的に生成する点を忘れないでください。これはCustomResourceDefinition APIの構築開始と同時に実行されます。
また、組み込みk8sオブジェクトの名前空間を除去しようとすると、関連するカスタムオブジェクトもすべて消去される点に留意してください。CRDについては、CRD自体が名前空間に縛られないため、影響を受けません。
ここでは、TestPlatformという種のオブジェクトのCRD構築プロセスを見ていきます。このオブジェクトは、構築中のアプリに関する全情報を保持する設計と仮定します。
このKubernetesカスタムリソース定義の例では、APIグループとして example.com を使用していますが、必ずしも自社のドメインである必要はありません。
本リソースの名前空間上の配置は「versions」となります。まずは、製品リリース前に変更される可能性のある「v1alpha1」から始めます。ユーザー入力の検証ルールに従い、JSONスキーマを「v1alpha1」版として定義する必要があります。
以下の例をご覧ください:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# 名前は形式の一部であり、以下に示すspecフィールド(.)と一致する必要があります
name: platforms_example.example.com
spec:
# REST APIで使用されるグループ名 (/apis//)
group: example.com
names:
# pluralはURLに含まれる名称 (/apis///)
plural: platforms_example
# singularはCLI上で表示される別名
singular: testplatform
# kindはリソースマニフェストで用いられ、通常はキャメルケースの単数形です
kind: TestPlatform
# shortNamesはCLIでの短縮名を提供します
shortNames:
- myp
# スコープはClusterまたはNamespacedのいずれかです
scope: Namespaced
versions:
- name: v1alpha1
# servedフラグは各バージョンの有効/無効を切り替えます
served: true
# storageとして扱われるバージョンは1つだけです
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
appId:
type: string
language:
type: string
enum:
- csharp
- python
- go
os:
type: string
enum:
- windows
- linux
instanceSize:
type: string
enum:
- small
- medium
- large
environmentType:
type: string
enum:
- dev
- test
- prod
replicas:
type: integer
minimum: 1
required: ["appId", "language", "environmentType"]
required: ["spec"]
次に、このCRDを登録します。以下のkubectl applyコマンドを使用してください。
kubectl apply -f ./crd.yaml
これで完了です。CRDは正常に登録されました。次は検証作業です。kubectl get crdsコマンド、またはkubectl api-resources | grep testplatformコマンドで確認できます。どちらの方法でも、標準通りであれば迅速に検証されます。
登録済みのクラスターCRDを利用すれば、後にカスタムリソースの一部となるカスタムオブジェクトを作成するのが容易です。
apiVersion: example.com/v1alpha1
kind: TestPlatform
metadata:
name: test-example-app
spec:
appId: testexampleapp
language: csharp
os: linux
instanceSize: small
environmentType: development
replicas: 3
このようにしてカスタムオブジェクトが作成されます。例えば、kubectl apply -f ./cr.yaml を実行した際、以下の画像のようなメッセージが表示されたとします。
これは、無効な入力オブジェクトを示すエラーです。JSONスキーマでspec.environmentTypeフィールドが既に定義され、test、prod、devのenum値のみ受け付けると決められているため、同じ値を再定義するとエラーが発生します。
重要なのは、あらかじめ定義されたスキーマによる検証を追加することでエラーを防げる点です。これによりエラーが解消され、再度kubectl apply -f ./cr.yamlコマンドを実行すると、カスタムリソースのインスタンスが作成されるのが確認できます。
apiVersion: example.com/v1alpha1
kind: TestPlatform
metadata:
name: test-example-app
spec:
appId: testexampleapp
language: csharp
os: linux
instanceSize: small
environmentType: dev
replicas: 3
続いて、kubectlコマンドでCRDのカスタムオブジェクトを取得するのが賢明です。CRDの完全な名称ではなく、短縮名でも取得が可能です。
kubectl get myp #
このコマンドで確認できます。
既に作成したCRDが不要になりましたか?ご安心ください。
kubectl deleteコマンドを使用して、KubernetesのCRDを簡単に削除できます。また、CRDの削除時には対象サーバーが自動的にRESTful APIのエンドポイントおよびそれに紐づく全てのカスタムオブジェクトを除去する点にご注意ください。
以下のように実行します:
kubectl delete -f resourcedefinition.yaml
kubectl get crontabs
Error from server (NotFound): Unable to list {"stable.example.com" "v1" "crontabs"}: the server could not find the requested resource (get crontabs.stable.example.com)
一度削除すると、同じCRDを再取得または再作成することはできません。再試行しても何も返ってきません。
Kubernetes APIはコンテナ管理をこれまで以上に容易にします。しかし、柔軟性に欠ける場合、一部の要求を満たせず、手間が増えることもあります。カスタムリソースは、Kubernetes APIにさらなる柔軟性をもたらします。
CRDがなければ、これらは実現できません。本記事ではKubernetes CRDについて詳しく解説しました。以下、要点を振り返ります:
既定の機能を超えた活用を目指す場合、CRDの導入は検討に値します。ただし、最適な状況で使用することが重要です。まずはK8sカスタムリソース定義を十分に理解した上で、導入を進めてください。
Custom Resources - Kubernetes
Extend the Kubernetes API with CustomResourceDefinitions - Kubernetes
最新情報を購読