Kubernetes Nativeなプログラムを作る際に知っておくべきこと
kubectl pluginという形でKubernetes Nativeなプログラムを作りました。
その際に前提知識としてKubernetes APIの理解が必要だと感じました。
本投稿では、Kubernetes Nativeなプログラムを作る際に知っておくべき知識を紹介します。
なお、Goおよびclient-goを利用する前提での内容になります。
Kubernetes APIについて
Kubernetes APIには、KindなどAPIに関連するいくつかの要素があります。
プログラムを書く際には、これらを理解する必要があると思います。
Kind
Pod,DeploymentといったKubernetes Resourceの種類を表します。
GoにおけるKubernetesのクライアントライブラリであるclient-goでは、このKind毎に型が用意されています。
例えば、Podの型は以下のように定義されています。
type Pod struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Specification of the desired behavior of the pod. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec PodSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Most recently observed status of the pod. // This data may not be up to date. // Populated by the system. // Read-only. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` }
これはKubernetesマニフェストの構造と一致します。
apiVersion: v1 kind: Pod metadata: namespace: default name: example spec: containers: - name: nginx image: nginx:latest status: phase: Running
Group
Kubernetes Resourceをグループ分けする要素になります。
apps,batchといったGroup名があります。
Version
APIのバージョンを表します。
開発が進む毎にv1alpha,v1beta,v1という段階があります。
Resource
Kubernetes API Serverのエンドポイントを構成する1要素になります。
例えば、以下のようにDeploymentリソースのエンドポイントがあります。
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
deployments
に当たる部分がResourceになります。
GroupVersionKind(GVK)
Group,Version,Kindを用いて、Kubernetes Resourceを特定します。
GroupVersionResource(GVR)
Group,Version,Resourceを用いて、Kubernetes Resourceを特定します。
Kubernetes API ServerのREST形式エンドポイントと対応しています。
REST Mapping
GVKからGVRに変換する仕組みです。
利用方法は以下のとおりです。
ここでは、GVK形式のDeploymentリソースをGVRに変換しています。
... config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) dc, err := discovery.NewDiscoveryClientForConfig(config) mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc)) mapping, err := mapper.RESTMapping(schema.GroupKind{ Group: "apps", Kind: "Deployment", }, "v1") ...
mapping.Resource
がGVRの値になります。
discoveryを使い、どのようなResourceが定義されているかをKubernetes API Serverに問い合わせた上でREST形式にマッピングするようです。
そのため、このような手順を踏みます。
Scheme
Go上でGroup,Version,Kind,Resourceといった値を扱うためのPackageです。
k8s.io/apimachinery/pkg/runtime/schema
で定義されています。
Typed Client
Kindの項で説明したとおり、Kubernetes Resource用の型が定義されています。
その型に従ってResourceを扱うclientです。
例えば、Deploymentリソースを扱う場合、以下のような記述になります。
...
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
clientset, err := kubernetes.NewForConfig(config)
deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
deploymentsClient.List(context.TODO(), metav1.ListOptions{})
...
Get,Listといったデータを取得するメソッドを使うと、Deployment型のデータを取得可能です。
Deployment型のデータを用意して、Create,Update,Deleteといったデータを変更するメソッドを利用します。
Dynamic Client
特定の型によらずに動的にKubernetes Resourceを扱うclientです。
このclientでは、unstructured.Unstructured型を扱います。この型の実態はmap[string]interface{}
型でどのような値でも受け入れる形になっています。
例えば、Deploymentリソースを扱う場合、以下のような記述になります。
... config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) client, err := dynamic.NewForConfig(config) deploymentRes := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"} client.Resource(deploymentRes).Namespace(namespace).List(context.TODO(), metav1.ListOptions{}) ...
Dynamic Clientで取得した値はunstructured.Unstructured型になるので汎用的に扱うことができます。
まとめ
Kubernetes APIを扱う上での前提知識といった内容を紹介しました。
Kubernetesを単純に利用しているだけだと、KubernetesにはAPIがあるというくらいの理解しかできていなかったです。
Kubernetes Nativeなプログラムを作ることでより深くKubernetesを理解できました。
これらの知識はCustom Resourceを作る際に役立つ内容だと思います。