Kubernetes Operators & Custom Resource Definitions (CRDs)
In this tutorial, you'll learn about Kubernetes Operators & Custom Resource Definitions (CRDs). We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Kubernetes Operators extend the Kubernetes API with Custom Resource Definitions and controllers that automate application management tasks like backups upgrades and scaling.
What You'll Learn
This tutorial covers creating CRDs, building operators with the Operator SDK, implementing reconciliation loops, managing operator lifecycle with OLM, and real operator examples.
Why It Matters
Manual application management does not scale. Operators encode human operational knowledge into software, automating complex tasks like database backups, certificate renewal, and cluster upgrades.
Real-World Use
The Prometheus Operator manages thousands of monitoring stacks across Kubernetes clusters. Zalando built the Postgres Operator to automate database provisioning and failover for 2000 PostgreSQL instances.
Custom Resource Definitions
CRDs extend the Kubernetes API with custom resource types.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: databases.example.com
spec:
group: example.com
names:
kind: Database
plural: databases
singular: database
shortNames:
- db
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- engine
- version
properties:
engine:
type: string
enum: [postgres, mysql]
version:
type: string
replicas:
type: integer
minimum: 1
maximum: 10
# Create CRD
kubectl apply -f database-crd.yaml
# List CRDs
kubectl get crds
# Create a custom resource
kubectl apply -f - <<EOF
apiVersion: example.com/v1
kind: Database
metadata:
name: my-db
spec:
engine: postgres
version: "15"
replicas: 3
EOF
Building an Operator with Operator SDK
Initialize the Project
# Install Operator SDK
curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.34.0/operator-sdk_linux_amd64
chmod +x operator-sdk_linux_amd64
sudo mv operator-sdk_linux_amd64 /usr/local/bin/operator-sdk
# Create operator project
operator-sdk init --domain example.com --repo github.com/example/database-operator
# Create API and controller
operator-sdk create api --group example --version v1 --kind Database --resource --controller
Implement the Controller
The controller watches Database custom resources and reconciles the desired state.
func (r *DatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := log.FromContext(ctx)
var db examplev1.Database
if err := r.Get(ctx, req.NamespacedName, &db); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// Ensure StatefulSet exists
sts := &appsv1.StatefulSet{}
sts.Name = db.Name
sts.Namespace = db.Namespace
_, err := ctrl.CreateOrUpdate(ctx, r.Client, sts, func() error {
sts.Spec.Replicas = &db.Spec.Replicas
sts.Spec.Template.Spec.Containers = []corev1.Container{{
Name: "database",
Image: fmt.Sprintf("postgres:%s", db.Spec.Version),
}}
return ctrl.SetControllerReference(&db, sts, r.Scheme)
})
return ctrl.Result{}, err
}
Deploy the Operator
# Build and push image
make docker-build docker-push IMG=registry.example.com/database-operator:v1
# Deploy to cluster
make deploy IMG=registry.example.com/database-operator:v1
Testing the Operator
# Deploy a sample custom resource
kubectl apply -f config/samples/example_v1_database.yaml
# Check that the StatefulSet was created
kubectl get statefulsets
# View operator logs
kubectl -n database-operator-system logs deployment/database-operator-controller-manager
Practice Questions
What is the relationship between a CRD and a Controller? The CRD defines the API schema. The Controller watches CRD instances and creates or manages the underlying Kubernetes resources.
What does the reconciliation loop do? It continuously compares the desired state from the custom resource with the actual cluster state and makes changes to converge them.
How does ctrl.CreateOrUpdate work? It creates a resource if it does not exist, or updates it to match the desired specification if it already exists.
Why use the Operator Lifecycle Manager? OLM manages operator installation, upgrades, and dependencies across cluster namespaces.
What is the purpose of the OpenAPI schema in a CRD? It validates custom resource fields and provides documentation through kubectl describe.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro