CRDについてのメモ
Kubernetesのカスタムリソースについてのメモ。基本的には公式ドキュメントの Custom Resources にいろいろと説明が書かれているのでここを読めばよい。カスタムリソース自体は構造化されたデータをKubernetes上に保存・取得できる機能といえる。これにカスタムコントローラを組み合わせることで、Deploymentのようなビルトインリソースと同じような宣言的APIを用いた状態管理を実現できるようになる。データ保存だけなら必ずしもカスタムコントローラーは必要ではないというのが最初分かっていなかった。
軽く試す。使用バージョンは以下の通り:
- Kubernetes v1.12.3
- minikube v0.32.0
検証用環境はminikubeで起動:
$ minikube start --memory=8192 --cpus=4 \
--kubernetes-version=v1.12.3 \
--vm-driver=hyperkit \
--bootstrapper=kubeadm
kubernetes/sample-controller を参考にしつつ、CRD用のマニフェストを作成する。グループやバージョンがリソースへアクセスする際のAPIとなる(/apis/<group>/<version>)。リソースのkindや単数形、複数形なども定義できる。
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha
scope: Namespaced
names:
plural: foos
singular: foo
kind: Foo
shortNames:
- foo
このマニフェストを適用すると、以下のようにcrdリソースとして見えるようになる:
$ kubectl get crd
NAME AGE
foos.samplecontroller.k8s.io 34m
Fooリソースを作ってみる。以下のようなマニフェストを用意し、 kubectl applyする:
---
apiVersion: samplecontroller.k8s.io/v1alpha
kind: Foo
metadata:
name: foo-001
spec:
deploymentName: deploy-foo-001
replicas: 1
---
apiVersion: samplecontroller.k8s.io/v1alpha
kind: Foo
metadata:
name: foo-002
spec:
deploymentName: deploy-foo-002
replicas: 1
hoge: huga
Fooリソースが作成されていることがわかる:
$ kubectl get foos
NAME AGE
foo-001 50s
foo-002 50s
リソースの詳細を見ると、マニフェストで指定したspecが確認できる:
$ kubectl describe foo foo-001
Name: foo-001
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"samplecontroller.k8s.io/v1alpha","kind":"Foo","metadata":{"annotations":{},"name":"foo-001","namespace":"default"},"spec":{"deploymentNa...
API Version: samplecontroller.k8s.io/v1alpha
Kind: Foo
Metadata:
Creation Timestamp: 2019-01-02T03:42:45Z
Generation: 1
Resource Version: 3649
Self Link: /apis/samplecontroller.k8s.io/v1alpha/namespaces/default/foos/foo-001
UID: 77506f4f-0e40-11e9-95ac-263ada282756
Spec:
Deployment Name: deploy-foo-001
Replicas: 1
Events: <none>
リソース毎にspecが異なることも確認できる:
$ kubectl describe foo foo-002
Name: foo-002
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"samplecontroller.k8s.io/v1alpha","kind":"Foo","metadata":{"annotations":{},"name":"foo-002","namespace":"default"},"spec":{"deploymentNa...
API Version: samplecontroller.k8s.io/v1alpha
Kind: Foo
Metadata:
Creation Timestamp: 2019-01-02T03:42:45Z
Generation: 1
Resource Version: 93582
Self Link: /apis/samplecontroller.k8s.io/v1alpha/namespaces/default/foos/foo-002
UID: 775194f8-0e40-11e9-95ac-263ada282756
Spec:
Deployment Name: deploy-foo-002
Hoge: huga
Replicas: 1
Events: <none>
CRDでバリデーションを行うこともできる(OpenAPIv3.0を使うようだ)。kubernetes/sample-controller を見つつ、replicasのバリデーションを設定してみる:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha
scope: Namespaced
names:
plural: foos
singular: foo
kind: Foo
shortNames:
- foo
validation:
openAPIV3Schema:
properties:
spec:
properties:
replicas:
type: integer
minimum: 1
maximum: 10
これで、replicasの最小値と最大値が設定される。replicasが10より大きいマニフェストを用意して適用してみる:
---
apiVersion: samplecontroller.k8s.io/v1alpha
kind: Foo
metadata:
name: foo-003
spec:
deploymentName: deploy-foo-003
replicas: 20
バリデーションに引っかかり、作成に失敗することが確認できた。
$ kubectl apply -f ./foo-invalid.yaml
The Foo "foo-003" is invalid: []: Invalid value: map[string]interface {}{"apiVersion":"samplecontroller.k8s.io/v1alpha", "kind":"Foo", "metadata":map[string]interface {}{"name":"foo-003", "namespace":"default", "creationTimestamp":"2019-01-03T01:05:13Z", "annotations":map[string]interface {}{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"samplecontroller.k8s.io/v1alpha\",\"kind\":\"Foo\",\"metadata\":{\"annotations\":{},\"name\":\"foo-003\",\"namespace\":\"default\"},\"spec\":{\"deploymentName\":\"deploy-foo-003\",\"replicas\":20}}\n"}, "generation":1, "uid":"a02a984d-0ef3-11e9-95ac-263ada282756"}, "spec":map[string]interface {}{"replicas":20, "deploymentName":"deploy-foo-003"}}: validation failure list:
spec.replicas in body should be less than or equal to 10
API Aggregationというものもあるようだが、そちらはまた今度。
参考: