コンテンツにスキップ

カスタムリソース@Kubernetes

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. カスタムリソース

カスタムリソースとは

Kubernetesに標準で備わっていないKubernetesリソースを提供する。


管理方針

CRDは、作成も変更もHelmの管理外 (kubectlコマンド) で作成/変更したほうがよい。

理由としては以下の通りである。

  • CRDの作成が衝突する可能性があり、CRDにmeta.helm.shキーを付与したくない
  • HelmはCRDを作成できるが更新できないため、作成もHelmの管理外にしたい

カスタムリソースのマニフェストで定義できるオプションやデータ型は、CRDのスキーマ定義に応じて決まる。

そのため、CRDのスキーマを変更すると、同じCluster内にある該当のカスタムリソースに影響が出る。

具体的には、以下のような問題が起こる可能性がある。

  • CRDをアップグレードした場合に、スキーマに機能廃止があると、カスタムリソースで廃止されたその機能を使用できなくなる。
  • CRD自体を誤って削除すると、これに対応するカスタムリソースも自動的に削除される。


カスタムリソース固有の問題

▼ 共通エラー

以下のようなエラーになってしまう場合、CRDが存在していないか、CRDが古くて新しいカスタムリソースが対応していない可能性がある。

Failed to render chart: exit status 1: Error: unable to build kubernetes objects from release manifest: error validating ""

▼ 個別

メモ程度に、カスタムリソースで起こった固有の問題を記載しておく。

問題 解決策 該当のカスタムリソース
.spec.affinityキーの変更を適用するために、Podを再スケジューリングさせた。.spec.affinityキーの設定が機能せず、変更前と同じNodeにPodが再スケジューリングされてしまう。 PersistentVolumeが再作成されておらず、既存のPersistentVolumeに紐付けるために、同じNodeにPodを再スケジューリングさせている可能性がある。Podを再スケジューリングさせた後に、すぐにPersistentVolumeも再作成する。 Prometheus系


02.セットアップ

ユーザーによる管理

▼ 非チャートとして

CRDのマニフェストを送信し、その後にカスタムリソースのマニフェストを送信する。

もしCRDを送信する前にカスタムリソースを送信してしまうと、kube-apiserverはCRDを見つけられずに、以下のエラーレスポンスを返信する。

the server could not find the requested resource

▼ チャートとして

CRDとカスタムリソースを含むチャートをインストールする。


custom-controllerによる管理

▼ 非チャートとして

custom-controllerのマニフェストを送信し、後はcustom-controllerにカスタムリソースを作成させる。

▼ チャートとして

custom-controllerのチャートをインストールし、後はcustom-controllerにカスタムリソースを作成させる。


03. CRD

CRDとは

カスタムリソースを宣言的に定義する。

ただし、kube-controllerはetcd内のカスタムリソースを検知できず、これを検知するためにはcustom-controllerを作成する必要がある。


カスタムリソースの宣言値の決まり方

マニフェストの.apiVersionキーで、『<.spec.groupキー名>/<.spec.versionキー名>』と宣言し、カスタムリソースを使用する。

例えば『example.com』というグループと『v1』というバージョンを定義したとすると、カスタムリソースからはexample.com/v1というAPIからコールできるようになる。


.apiVersion

CRD自体のAPIグループの名前を設定する。

apiVersion: apiextensions.k8s.io/v1


.metadata

▼ name

カスタムリソースのAPIグループの名前を設定する。

名前は、『<.spec.names.pluralキー名>.<spec.groupキー名>』とする必要がある。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  # pluralキー名は、foos
  # groupキー名は、example.com
  name: foos.example.com


.spec.group

▼ groupとは

カスタムリソースが所属するAPIグループの名前を設定する。

カスタムリソースを管理する組織の完全修飾ドメイン名にすると良い。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  group: example.com


.spec.scope

▼ scopeとは

カスタムリソースを『Namespacedスコープ』あるいは『Clusterスコープ』なKubernetesリソースとするかを設定する。

注意点として、CRD自体はClusterスコープなKubernetesリソースである。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  scope: Namespaced

▼ Clusterの場合

同じカスタムリソースがCluster内に1個のみ存在できるようにする。

Namespaceごとにカスタムリソースを作成できなくなる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  scope: Cluster

▼ Namespacedの場合

同じカスタムリソースがNamespace内に1個のみ存在できるようにする。

Namespaceごとにカスタムリソースを作成できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  scope: Namespaced


.spec.names

▼ namesとは

カスタムリソースの名前を設定する。

▼ kind

カスタムリソースの.kindキー名を設定する。

例えば『Foo』という宣言名にすると、マニフェストの.kindキーで、Fooというカスタムリソース名で使用できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  names:
    kind: Foo
# カスタムリソースの宣言
apiVersion: foo.example.com
kind: Foo
spec: ...

▼ plural

kubectlコマンドで使用するカスタムリソースの複数形名を設定する。

例えば『foos』という宣言名にすると、kubectlコマンドでfoosというカスタムリソース名で使用できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  names:
    plural: foos
$ kubectl get foos

▼ singular

kubectlコマンドで使用するカスタムリソースの単数形名を設定する。

例えば『foo』という宣言名にすると、kubectlコマンドでfooというカスタムリソース名で使用できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  names:
    singular: foo
$ kubectl get foo

▼ shortNames

kubectlコマンドで使用するカスタムリソースの省略名を設定する。

例えば『fo』という宣言名にすると、kubectlコマンドでfoというカスタムリソース名で使用できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  names:
    shortNames:
      - fo
$ kubectl get fo


.spec.versions

▼ versionsとは

CRDに対応するカスタムリソースに関して、APIグループのバージョンを設定する。

複数のバージョンのCRDをCluster内で同時に管理する場合、.spec.versions[*].nameキー配下に複数のスキーマを定義する。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  versions:
    - name: v1

  ...

    - name: v2

  ...

▼ name

APIグループのバージョン名を設定する。

例えば『v1』というstring型のキーを設定すると、マニフェストの.apiVersionで、/v1を最後につけてコールすることになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  versions:
    - name: v1

▼ served

APIグループのバージョンを有効化するかを設定する。

もしカスタムリソースに複数のバージョンが存在する場合、旧バージョンを無効化し、マニフェストで使用できないようにできる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  versions:
    - served: "true"

▼ schema

カスタムリソースの.specキー以下に設定できるキーと、これのデータ型を設定する。

例えば『message』というstring型のキーを設定すると、カスタムリソースの.spec.messageキーに任意のstring型を設定できるようになる。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  versions:
    - schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                # カスタムリソースの.spec.messageキーに文字列を設定できるようになる。
                message:
                  # 説明文
                  description: Echo message
                  # string型
                  type: string

▼ storage

APIグループのバージョンをetcdのストレージに保管しても良いどうかを設定する。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foo.example.com
spec:
  versions:
    - storage: "true"