Slide 1

Slide 1 text

1 沈め!Kubernetes Operator沼!! 2023/9/12

Slide 2

Slide 2 text

2023/9/12 2 谷合 純也(たにあい じゅんや) 江戸川区在住 来年福岡移住します!(戸建購入済) ・所属:株式会社エーピーコミュニケーションズ ACS事業部 Cloud Infrastructureチーム ・業務: Microsoft Azureのコンテナ製品をメインにインフラ支援 ・趣味: Kubernetes Operator実装やコードリーディング, 筋トレ jnytnai0530 junya0530 jnytnai0613

Slide 3

Slide 3 text

3 Kubernetes Operatorの実装って、難しいし、ハードル高いイメージないですか? 絶賛沼にハマっている私が「ちょっと実装してみようかな?」を手助けします! 2023/9/12

Slide 4

Slide 4 text

4 Kubernetes Operatorの実装ができるようなると • Kubernetesさんとコードでお話しできるようになる • 普段使っているOperatorのコードリーディングもサクサクできるようになる 2023/9/12

Slide 5

Slide 5 text

5 アジェンダ 1. Kubernetes Operatorって? 2. 実装の準備をしよう 3. 成果物紹介 4. 教材 2023/9/12

Slide 6

Slide 6 text

6 通常運用を行う場合、システムがどのように振る舞うべきか、Deploy方法はどうす るべきかといった知識の上で、担当者が手で運用を行う必要がある。 Kubernetes Operator(以降Operator)とは管理対象のシステムの振る舞いの強制と Deployを自動化する拡張方法を指す。 Kubernetes Operatorには以下のComponentが含まれる • Custom Resource Definitions(以降CRD) • Custom Resource(以降CR) • Custom Controller(以降Controller) • Admission Webhook Kubernetes Operatorって? 2023/9/12

Slide 7

Slide 7 text

通常、なんらかの要因で本来あるべき振る舞いに乱れが生じた際、リトライ処理が必要となる。 ControllerはReconcile Loopという機能で、リトライ処理を自動化し、処理の冪等性を保証している。 つまり、あるべき姿が常に保持可能である。 7 あるべき姿 Controller 管理対象Target (K8s 標準Resource, 外部Resource等) 比較 Kubernetes Operatorって? 1. CRで管理対象Targetのあるべき姿を定義し、Deployする 2. Controllerが管理対象Targetあるべき姿を監視する 3. Controllerがあるべき姿と現在の姿を比較 4. 差異があれば、あるべき姿に戻す 2023/9/12

Slide 8

Slide 8 text

8 // K8sNoviceOperatorSpec defines the desired state of K8sNoviceOperator type K8sNoviceOperatorSpec struct { DeploymentName string `json:"deploymentName"` DeploymentSpec *DeploymentSpecApplyConfiguration `json:"deploymentSpec"` } // K8sNoviceOperator is the Schema for the k8snoviceoperators API type K8sNoviceOperator struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec K8sNoviceOperatorSpec `json:"spec,omitempty"` Status K8sNoviceOperatorStatus `json:"status,omitempty"` } Kubernetes Operatorって? • CR API 定義 API定義はGo言語の構造体として定義され、metav1.TypeMetaでAPIVersionとKind、 metav1.ObjectMetaでName, Namespace, UID, OwnerReferences、SpecとStatusでリソースが表現 される。API定義はCRDで管理される。

Slide 9

Slide 9 text

9 apiVersion: k8snoviceoperator.jnytnai0613.github.io/v1 kind: K8sNoviceOperator metadata: name: k8snoviceoperator-sample spec: deploymentName: nginx deploymentSpec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 30% maxUnavailable: 30% template: spec: containers: - name: nginx image: nginx:latest 管理対象リソース定義 (Kubernetes 標準リソースの場合) Kubernetes Operatorって? • CR定義 CRはAPIで表現したリソース構造に則り、定義する。

Slide 10

Slide 10 text

10 func (r *K8sNoviceOperatorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { logger := log.FromContext(ctx) // CRの定義を取得 var k8snovice k8snoviceoperatorv1.K8sNoviceOperator if err := r.Client.Get(ctx, req.NamespacedName, &k8snovice); err != nil { logger.Error(err, "unable to fetch K8sNoviceOperator") return ctrl.Result{}, err } // DeploymentのApply // CRに変更がある、または既存管理対象ターゲットと定義が異なる場合は、 // 再度CR定義を基にApplyする if err := r.applyDeployment(k8snovice, logger); err != nil { logger.Error(err, "unable to apply Deployment") return ctrl.Result{}, err } return ctrl.Result{}, nil } Kubernetes Operatorって? • Reconcile定義 基本としては、CR定義を取得し、CR定義に沿って監理対象ターゲットの冪等性を保つように 実装する

Slide 11

Slide 11 text

11 func (r * K8sNoviceOperatorReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). // 自分自身 For(&k8snoviceoperatorv1.K8sNoviceOperator{}). Complete(r) } Kubernetes Operatorって? • Reconcile Loopが呼び出されるタイミング • 10時間毎(デフォルト) • Manager.SyncPeriodで指定した時間毎 • 自分自身 or 子リソース or それ以外の監視対象のイベント発生時 自分自身以外の監視方法 Custom Controller外のリソースのイベントを監視する https://zenn.dev/ap_com/articles/5b64ab1ccd60a2

Slide 12

Slide 12 text

12 ね?簡単でしょ? 2023/9/12

Slide 13

Slide 13 text

13 アジェンダ 1. Kubernetes Operatorって? 2. 実装の準備をしよう 3. 成果物紹介 4. 教材 2023/9/12

Slide 14

Slide 14 text

14 実装の準備をしよう OperatorはControllerの集合体として実装されるが、実装方法やKubernetesから情報を取得するには ライブラリの深い理解が必要となり、若干ハードルが高い。 これさえ最低限マスターすれば、簡単なOperatorが実装可能となる関数やフレームワークをご紹介しま す。

Slide 15

Slide 15 text

15 実装の準備をしよう OperatorはControllerの集合体として実装されるが、実装方法やKubernetesから情報を取得する方法は ライブラリの読み込みが必要となり、若干ハードルが高い。 これさえ最低限マスターすれば、簡単なOperatorが実装可能となる関数やフレームワーク、覚えておく べきライブラリをご紹介します。 まず、以下のComponentは知っていますか? Component 役割 Informer • K8s上のリソースを監視して、Object一覧を取得し、In-Memory-Cacheに格納する • イベント毎に、WorkqueueにObjectを格納する Lister • Get/List要求のたびにIn-Memory-CacheからObjectを取得する Workqueue • Reconcile Loop対象のObjectを貯めておくキュー。このキュー内のObjectを Controllerが順番に処理する

Slide 16

Slide 16 text

16 実装の準備をしよう OperatorはControllerの集合体として実装されるが、実装方法やKubernetesから情報を取得する方法は ライブラリの読み込みが必要とな理、若干ハードルが高い。 これさえ最低限マスターすれば、簡単なOperatorが実装可能となる関数やフレームワークをご紹介しま す。 まず、以下のComponentは知っていますか? Component 役割 Informer • K8s上のリソースを監視して、Object一覧を取得し、In-Memory-Cacheに格納する • イベント毎に、WorkqueueにObjectを格納する Lister • Get/List要求のたびにIn-Memory-CacheからObjectを取得する Workqueue • Reconcile Loop対象のObjectを貯めておくキュー。このキュー内のObjectを Controllerが順番に処理する

Slide 17

Slide 17 text

17 実装の準備をしよう ~ Clientの生成 ~ func generateClient(log logr.Logger, scheme runtime.Scheme) (client.Client, error) { clientConfig := ctrl.GetConfigOrDie() kubeClient, err := client.New(clientConfig, client.Options{Scheme: &scheme}) if err != nil { return nil, fmt.Errorf("failed to generate client: %w", err) } return kubeClient, nil } GetConfigOrDie関数で、 Kubernetes APIを通信を行うrest.Configを生成する。 rest.Configをclient.Newに渡すことで、Clientの生成が可能。 このClientを使用し、Kubernetesとお話しを行う。

Slide 18

Slide 18 text

18 実装の準備をしよう ~ 関数の紹介 ~ func (c *client) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { • Get関数 In-Memory-CacheからObjectを取得する https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/client/client.go#L343 func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { • List関数 In-Memory-CacheからObjectを一覧取得する https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/client/client.go#L365

Slide 19

Slide 19 text

19 実装の準備をしよう ~ 関数の紹介 ~ func (c *client) Create(ctx context.Context, obj Object, opts ...CreateOption) error { • Create関数 引数に渡されたObject定義を元に、リソースの作成を行う https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/client/client.go#L281 func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) { • CreateOrUpdate関数 引数に渡されたMutateFn定義を元に、リソースが存在かつ差分があればUpdate、存在しない場合は 作成を行う https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/controller/controllerutil/controllerutil.go#L196

Slide 20

Slide 20 text

20 実装の準備をしよう ~ 関数の紹介 ~ func (c *client) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { • Update関数 引数に渡されたObject定義を元に、リソースの更新を行う https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/client/client.go#L293 func (c *client) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { • Delete関数 引数に渡されたObject定義を元に、リソースの削除を行う https://github.com/kubernetes-sigs/controller-runtime/blob/f30e11d97fd19564e71b4f672efcdc0ecad3a8d1/pkg/client/client.go#L306

Slide 21

Slide 21 text

21 実装の準備をしよう ~ 関数の紹介 ~ ここで紹介した関数はClientを使用して呼び出せるものになります。 他にもClientsetというAPIごとに関数がまとまったものもあります。 後述するsample-controllerはClientsetが使われています。 https://github.com/kubernetes/client-go/tree/master/kubernetes/typed

Slide 22

Slide 22 text

22 実装の準備をしよう ~ フレームワーク紹介 ~ • Kubebuilder InformerやWorkqueue、Listerなどの小難しいComponentを隠蔽し、実装者がロジックに集中 できるようにAPI, Controllerテンプレート, Dockerfile, Manifestなどを自動作成してくれます。 https://book.kubebuilder.io/ • Operator SDK Kubebuilderと同じく、実装者がロジックに集中できるように手助けをする。 Helm chartやAnsibleをベースとしたOperatorの実装もサポートしている。 https://sdk.operatorframework.io/

Slide 23

Slide 23 text

23 実装の準備をしよう ~ ライブラリ紹介~ • kubernetes/apimachinery scheme, typing, encoding, decoding, conversionなどのパッケージがまとまっているライブラリ https://github.com/kubernetes/apimachinery 推しディレクトリ: • pkg/api/ equality, errorsなどの便利関数がまとまっている • pkg/apis/meta/v1/ TypeMeta, ObjectMetaがまとまっている • kubernetes/client-go Kubernetesとお話しするためのClientライブラリ。 https://github.com/kubernetes/client-go 推しディレクトリ: • kubernetes/ Clientsetがまとまっている • applyconfigurations/ Server-Side Apply用のAPI定義の型と関数がまとまっている。 • tools/clientcmd/ kubeconfigを扱う際に便利な関数がまとまっている 当日スキップ

Slide 24

Slide 24 text

24 実装の準備をしよう ~ ライブラリ紹介~ • kubernetes-sigs/controller-runtime kubebuilderとOperator SDKでOperatorを実装する際に使用するライブラリ https://github.com/kubernetes-sigs/controller-runtime 推しディレクトリ: • pkg/client/ Clientに関する関数がまとまっている • pkg/envtest/ envtestを使用することで、kube-apiserverとetcdを立ち上げ、 Controllerのtestを 行うことができる • pkg/builder/controller.go ディレクトリではないが、管理対象ターゲットの設定や、Reconcile Loopのトリガー などがまとまっている 当日スキップ

Slide 25

Slide 25 text

25 アジェンダ 1. Kubernetes Operatorって? 2. 実装の準備をしよう 3. 成果物紹介 4. 教材 2023/9/12

Slide 26

Slide 26 text

26 成果物紹介 • kubernetes/sample-controller フレームワークを使用せずにフルスクラッチで書かれたController。 InformerやWorkqueueなどのComponentもふんだんに使用されているので、内部動作を把握する にはうってうつけ。 https://github.com/kubernetes/sample-controller 若干コードリーディングは難しいので、以下に解説記事書いてます。 [Kubernetes] sample-controllerを細かく解説する https://zenn.dev/ap_com/articles/45f7a646f62f52

Slide 27

Slide 27 text

27 成果物紹介 • jnytnai0613/k8snovice-operator 本LTで引用したコードの元である、Operator。 若干発展的な実装をしている。 CRをDeployすることで、 CR定義に則って、Deploymentが作成される。 https://github.com/jnytnai0613/k8snovice-operator • jnytnai0613/plumber Multi-Cluster間でリソースのReplicationを行うOperator。 2つのControllerと、 Replication対象のClusterの追加/削除を行うCLIが含まれる。 https://github.com/jnytnai0613/plumber 詳細は以下記事にまとめています。 Multi Kubernetes ClusterなOperator(改)とCLIを作ったよ https://zenn.dev/ap_com/articles/70dc79a8e01305

Slide 28

Slide 28 text

28 アジェンダ 1. Kubernetes Operatorって? 2. 実装の準備をしよう 3. 成果物紹介 4. 教材 2023/9/12

Slide 29

Slide 29 text

29 成果物紹介 • 実践入門 Kubernetesカスタムコントローラーへの道 Operatorの実装方法についてまとめらた唯一の日本語書籍かつ神本。 一通りの実装方法を学ぶことができる。 https://amzn.asia/d/5lxOTN0 • つくって学ぶKubebuilder kubebuilderを使用して、実装するための全ての初級的な知識が詰まっている。 実践的な実装方法に加え、本LTでは触れなかったWebhookやManager、finalizerなどの使い方も 学ぶことができる https://zoetrope.github.io/kubebuilder-training/

Slide 30

Slide 30 text

30 これで君もOperator Masterだ! 2023/9/12

Slide 31

Slide 31 text

31 WE ARE HIRING! CultureDeckも作成してます 2023/9/12