Upgrade to Pro — share decks privately, control downloads, hide ads and more …

沈め!KubernetesOperator沼!!

Junya Taniai
September 12, 2023

 沈め!KubernetesOperator沼!!

Kubernetes Novice Tokyo #27 ( https://k8s-novice-jp.connpass.com/event/293144/ ) のセッション資料です。
Kubernetes Operator実装方法や実装ができるようになった場合のメリットについて紹介しています。

セッション動画はこちらです。
https://www.youtube.com/watch?v=kYNJ54lFUVQ

Junya Taniai

September 12, 2023
Tweet

More Decks by Junya Taniai

Other Decks in Technology

Transcript

  1. 2023/9/12 2 ⾕合 純也(たにあい じゅんや) 江⼾川区在住 来年福岡移住します︕(⼾建購⼊済) ・所属︓株式会社エーピーコミュニケーションズ Azure Container

    Solution事業部 Cloud Integrationチーム ・業務︓ Microsoft Azureのコンテナ製品をメインにインフラ⽀援 ・趣味︓ Kubernetes Operator実装やコードリーディング, 筋トレ jnytnai0530 junya0530 jnytnai0613
  2. 通常、なんらかの要因で本来あるべき振る舞いに乱れが⽣じた際、リトライ処理が必要となる。 ControllerはReconcile Loopという機能で、リトライ処理を⾃動化し、処理の冪等性を保証している。 つまり、あるべき姿が常に保持可能である。 7 あるべき姿 Controller 管理対象Target (K8s 標準Resource,

    外部Resource等) ⽐較 Kubernetes Operatorって? 1. CRで管理対象Targetのあるべき姿を定義し、Deployする 2. Controllerが管理対象Targetあるべき姿を監視する 3. Controllerがあるべき姿と現在の姿を⽐較 4. 差異があれば、あるべき姿に戻す 2023/9/12
  3. 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で管理される。
  4. 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で表現したリソース構造に則り、定義する。
  5. 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定義に沿って監理対象ターゲットの冪等性を保つように 実装する
  6. 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
  7. 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が順番に処理する
  8. 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が順番に処理する
  9. 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とお話しを⾏う。
  10. 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
  11. 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
  12. 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
  13. 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/
  14. 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を扱う際に便利な関数がまとまっている 当⽇スキップ
  15. 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のトリガー などがまとまっている 当⽇スキップ
  16. 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
  17. 29 成果物紹介 • 実践⼊⾨ Kubernetesカスタムコントローラーへの道 Operatorの実装⽅法についてまとめらた唯⼀の⽇本語書籍かつ神本。 ⼀通りの実装⽅法を学ぶことができる。 https://amzn.asia/d/5lxOTN0 • つくって学ぶKubebuilder

    kubebuilderを使⽤して、実装するための全ての初級的な知識が詰まっている。 実践的な実装⽅法に加え、本LTでは触れなかったWebhookやManager、finalizerなどの使い⽅も 学ぶことができる https://zoetrope.github.io/kubebuilder-training/