Chuyển đến nội dung chính

第 34 課:運營商和自訂資源

Operator 模式:CRD、自訂控制器、Operator SDK、Kubebuilder。常用算子:Prometheus Operator、CloudNativePG (PostgreSQL)、Strimzi (Kafka)。使用 Kubebuilder 編寫簡單的運算子。

🔒 DevSecOps — 第 34 課 第 34 課:運營商和自訂資源

Kubernetes:從基礎到高級

Module 8: Helm, Operators & GitOps

xdev.asia

🎯 課程目標

了解 Operator 模式、如何使用 CRD 擴充 Kubernetes API 以及流行的 Operator(Prometheus、CloudNativePG、Strimzi)如何協助管理有狀態應用程式。

1. 算子模式

運算符編碼 操作知識 將應用程式載入到 Kubernetes 控制器中。操作員無需管理員執行手動步驟(備份、故障轉移、擴充),而是將這些步驟自動化。

例如:無需知道如何手動對 PostgreSQL 主資料庫進行故障轉移 — CloudNativePG Operator 會自動偵測主資料庫的故障並在幾秒鐘內升級副本。

Operator = CRD(自訂資源類型)+自訂控制器(監視和操作)

2. 自訂資源定義 (CRD)

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databases.mycompany.io
spec:
  group: mycompany.io
  names:
    kind: Database
    plural: databases
    singular: database
    shortNames: ["db"]
  scope: Namespaced
  versions:
  - name: v1
    served: true    # API server phục vụ version này
    storage: true   # etcd lưu ở version này
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            required: ["engine", "size"]
            properties:
              engine:
                type: string
                enum: ["postgres", "mysql"]
              size:
                type: string
              replicas:
                type: integer
                minimum: 1
                maximum: 5
          status:
            type: object
            properties:
              phase:
                type: string
              connectionString:
                type: string
    subresources:
      status: {}   # enable status subresource
    additionalPrinterColumns:
    - name: Engine
      type: string
      jsonPath: .spec.engine
    - name: Size
      type: string
      jsonPath: .spec.size
    - name: Phase
      type: string
      jsonPath: .status.phase
# Sau khi apply CRD, có thể tạo custom resources
cat <<EOF | kubectl apply -f -
apiVersion: mycompany.io/v1
kind: Database
metadata:
  name: my-postgres
  namespace: production
spec:
  engine: postgres
  size: medium
  replicas: 3
EOF

kubectl get databases -n production kubectl get db -n production # dùng shortName

3. 控制器循環

自訂控制器持續監視資源並協調到所需狀態:

for {
  // Lấy desired state từ K8s API
  desired = getDatabase("my-postgres")

// Lấy actual state từ cluster actual = getActualDatabaseState()

// Tính sự khác biệt diff = compare(desired, actual)

// Act để reconcile if diff { applyChanges(diff) }

// Cập nhật status updateStatus(desired, actual.phase)

sleep(reconcileInterval) }

4.Kubebuilder——建構操作符

# Cài Kubebuilder
curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

Tạo project mới

mkdir database-operator && cd database-operator kubebuilder init --domain mycompany.io --repo github.com/mycompany/database-operator

Tạo API (CRD + Controller)

kubebuilder create api --group mycompany --version v1 --kind Database

Project structure:

api/v1/database_types.go ← CRD schema

controllers/database_controller.go ← Reconcile loop

config/ ← K8s manifests

// controllers/database_controller.go
func (r *DatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    log := log.FromContext(ctx)

    // Lấy Database resource
    var database mycompanyv1.Database
    if err := r.Get(ctx, req.NamespacedName, &database); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // Tạo StatefulSet nếu chưa tồn tại
    statefulSet := &appsv1.StatefulSet{}
    err := r.Get(ctx, types.NamespacedName{
        Name:      database.Name,
        Namespace: database.Namespace,
    }, statefulSet)

    if errors.IsNotFound(err) {
        // Tạo StatefulSet
        newSS := r.constructStatefulSet(&database)
        r.Create(ctx, newSS)
        log.Info("Created StatefulSet", "name", newSS.Name)
    }

    // Cập nhật status
    database.Status.Phase = "Running"
    r.Status().Update(ctx, &database)

    return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

5. 通用運營商——2026

5.1 普羅米修斯算子

# Quản lý Prometheus cluster bằng CRDs
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: main
  namespace: monitoring
spec:
  replicas: 2
  retention: 7d
  serviceMonitorSelector: {}   # watch tất cả ServiceMonitors
  resources:
    requests:
      memory: 512Mi

5.2 CloudNativePG — PostgreSQL(CNCF 畢業)

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: my-postgres
  namespace: production
spec:
  instances: 3    # 1 primary + 2 replicas
  primaryUpdateStrategy: unsupervised  # auto failover
  storage:
    size: 10Gi
    storageClass: fast-ssd
  postgresql:
    parameters:
      max_connections: "200"
      shared_buffers: "256MB"
  backup:
    retentionPolicy: "30d"
    barmanObjectStore:
      destinationPath: s3://my-bucket/postgres/
      s3Credentials:
        accessKeyId:
          name: aws-creds
          key: ACCESS_KEY_ID
# CloudNativePG: automatic primary/replica management
kubectl get clusters -n production
kubectl get pods -n production -l cnpg.io/cluster=my-postgres
# my-postgres-1 → primary
# my-postgres-2 → replica
# my-postgres-3 → replica

Failover: xóa primary → operator tự promote replica

kubectl delete pod my-postgres-1 -n production

→ my-postgres-2 được promote thành primary trong ~5s

5.3 Strimzi——阿帕契卡夫卡

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-kafka
  namespace: messaging
spec:
  kafka:
    replicas: 3
    version: 3.9.0
    config:
      auto.create.topics.enable: "false"
    storage:
      type: persistent-claim
      size: 50Gi
  zookeeper:
    replicas: 3
    storage:
      type: persistent-claim
      size: 10Gi
  entityOperator:
    topicOperator: {}    # quản lý KafkaTopic CRDs
    userOperator: {}     # quản lý KafkaUser CRDs

5.4 證書管理器

# Tự động cấp và renew TLS certificates
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: api-tls
  namespace: production
spec:
  secretName: api-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - api.example.com
  - *.api.example.com

6. Operator Hub和OLM

# Operator Lifecycle Manager (OLM) quản lý lifecycle của operators
# Tìm operators tại: https://operatorhub.io/

Cài OLM

curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/latest/download/install.sh | bash -s latest

Cài operator từ OperatorHub

kubectl create -f https://operatorhub.io/install/postgresql.yaml

總結

  • 操作員 = CRD + 自訂控制器以自動化第 2 天操作
  • CRD 使用自訂資源類型擴充 Kubernetes API
  • Kubebuilder:使用 Go 搭建鷹架和建造操作員
  • CloudNativePG:最佳 PostgreSQL 操作員(CNCF 畢業,自動故障轉移)
  • Strimzi:Kubernetes 上的 Kafka 生命週期管理
  • cert-manager:TLS 憑證自動化