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 谷合 純也(たにあい じゅんや) 江戸川区在住 来年福岡移住します!(戸建購入済) ・所属:株式会社エーピーコミュニケーションズ ACS事業部 Cloud

    Infrastructureチーム ・業務: 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/