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

Kubernetesオペレータのアンチパターン&ベストプラクティス

 Kubernetesオペレータのアンチパターン&ベストプラクティス

CloudNative Days Tokyo 2021の発表資料です。
https://event.cloudnativedays.jp/cndt2021/talks/1207

補足資料
https://git.io/operator-bestpractice

Akihiro Ikezoe

November 04, 2021
Tweet

More Decks by Akihiro Ikezoe

Other Decks in Programming

Transcript

  1. type Reconciler interface { // コントローラのReconcile処理の実装 // 受け取ったRequestの内容に応じてリソースの作成や削除などの処理をおこなう // 処理の結果に応じてResultとerrorを返す

    Reconcile(context.Context, Request) (Result, error) } type Request struct { // コントローラが対象とするKubernetesオブジェクトのNamespaceとName types.NamespacedName } type Result struct { // コントローラにReconcileを再実行するように指示する Requeue bool // コントローラに指定した時間が経過した後にReconcileを再実行するように指示する RequeueAfter time.Duration }
  2. func (r *reconciler) reconcileXxxx(ctx context.Context) error { result, err :=

    ctrl.CreateOrUpdate(ctx, r.Client, res, func() error { // リソースの更新処理を実行 }) if err != nil { return err } if result != controllerutil.OperationResultNone { err = r.updateStatus() if err != nil { return err } } return nil }
  3. ss, err := p.GatherStatus(ctx) if err != nil { return

    false, err } if err := p.updateStatus(ctx, ss); err != nil { return false, err } switch ss.State { case StateCloning: // 省略 return redo, nil case StateRestoring: return false, nil case StateHealthy, StateDegraded: // 省略 return false, nil case StateFailed: // 省略 return true, nil
  4. _, err := ctrl.CreateOrUpdate(ctx, r.Client, certificate, func() error { //

    省略 } if err != nil { return ctrl.Result{}, err } secret := &corev1.Secret{} err = r.Get(ctx, key, secret) if err != nil { if apierrors.IsNotFound(err) { return ctrl.Result{ RequeueAfter: 10 * time.Second, }, nil } return ctrl.Result{}, err } // 次の処理を実行
  5. apiVersion: v1 kind: Pod metadata: managedFields: - apiVersion: v1 fieldsType:

    FieldsV1 fieldsV1: f:metadata: f:labels: f:v1.controller: {} manager: my-controller operation: Update
  6. svc := corev1apply.Service(svcName, mdView.Namespace). WithSpec(corev1apply.ServiceSpec(). // 省略 ) obj, err

    := runtime.DefaultUnstructuredConverter.ToUnstructured(svc) if err != nil { return err } patch := &unstructured.Unstructured{ Object: obj, } var current corev1.Service err = r.Get(ctx, client.ObjectKey{Namespace: mdView.Namespace, Name: svcName}, &current) if err != nil && !errors.IsNotFound(err) { return err } currentSvc, err := corev1apply.ExtractService(&current, constants.ControllerName) if err != nil { return err } if equality.Semantic.DeepEqual(svc, currentSvc) { return nil } err = r.Patch(ctx, patch, client.Apply, &client.PatchOptions{ FieldManager: constants.ControllerName, Force: pointer.Bool(true), })