🎯 Lesson Objective
Understand the Operator pattern, how to use CRDs to extend the Kubernetes API, and how popular operators (Prometheus, CloudNativePG, Strimzi) help manage stateful applications.
1. Operator Pattern
Operators encode operational knowledge of an application into the Kubernetes controller. Instead of admins performing manual steps (backup, failover, scaling), Operators automate them.
Example: No need to know how to manually failover PostgreSQL primary — CloudNativePG Operator automatically detects primary down and promotes replica within seconds.
Operator = CRD (custom resource type) + Custom Controller (watches and acts)
2. Custom Resource Definitions (CRDs)
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. Controller Loop
Custom Controller continuously watches resources and reconciles them to the desired state:
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 — Build Operators
# 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. Common Operators — 2026
5.1 Prometheus Operator
# 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 Graduated)
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 → replicaFailover: 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 — Apache Kafka
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 cert-manager
# 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 and 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
Summary
- Operator = CRD + Custom Controller to automate Day-2 operations__HTMLTAG_105___
- CRD extends the Kubernetes API with custom resource types
- Kubebuilder: scaffold and build operators with Go
- CloudNativePG: best PostgreSQL operator (CNCF graduated, auto failover)
- Strimzi: Kafka lifecycle management on Kubernetes__HTMLTAG_113___
- cert-manager: TLS certificate automation