Skip to content

Kubernetes Operator Study Journey

1. Try using existing operators

  1. prometheus-operator
  2. postgres-operator
  3. strimzi
  4. argocd: appcontroller.go
  5. grafana-operator
  6. mysql-operator
  7. terraform-k8s

And more

2. Understand what is Kubernetes operator.

  1. Kubernetes Controller components.
  2. How Kubernetes Controller works.
  3. Custom Resource.

Kubernetes Operator

A Kubernetes operator is an application-specific controller that extends the functionality of the Kubernetes API to create, configure, and manage instances of complex applications on behalf of a Kubernetes user.

From What is a Kubernetes operator?

Operators are software extensions to Kubernetes that make use of custom resources to manage applications and their components. Operators follow Kubernetes principles, notably the control loop.

From https://kubernetes.io/docs/concepts/extend-kubernetes/operator/

An Operator is like an automated Site Reliability Engineer for its application.

From Kubernetes Operators ~ Automating the Container Orchestration Platform ~

Operator vs. Controller

  • Controller (custom controller): a component that manages custom resources by running a control loop (reconciliation loop).
  • Operator: a CRD and custom controller that automate management of specific software, such as an etcd or MySQL operator.

Translated from A Practical Introduction to Kubernetes Custom Controllers

  • Controllers can act on core resources such as deployments or services, which are typically part of the Kubernetes controller manager in the control plane, or can watch and manipulate user-defined custom resources.
  • Operators are controllers that encode some operational knowledge, such as application lifecycle management, along with the custom resources defined in Chapter 4.

From Programming Kubernetes

  • A controller is a loop that reads desired state ("spec), observed cluster state (others' "status"), and external state, and the reconciles cluster state and external state with the desired state, writing any observations down (to our own "status").
  • All of Kubernetes functions on this model.
  • An operator is a controller that encodes human operational knowledge: how do I run and manage a specific piece of complex software.
  • All operators are controllers, but not all controllers are operators.

From Tutorial: Zero to Operator in 90 Minutes! - Solly Ross, Google (YouTube)

For more detail: - CNCF Operator White Paper - Final Version - CNCF White Paper

3. Create a sample operator following a tutorial

There are several ways to create an operator. You can try any of them:

  1. operator-sdk
    1. go-based: https://github.com/nakamasato/memcached-operator
    2. helm-based: https://github.com/nakamasato/nginx-operator
    3. ansible-based: https://github.com/nakamasato/memcached-operator-with-ansible
  2. kubebuilder
    1. Tutorial: Building CronJob
  3. metacontroller
  4. KUDO (Kubernetes Universal Declarative Operator)
  5. Learn Kubebuilder by Building

You can also reference example controllers:

  1. Sample Controller
  2. Istio Example Controller
  3. Foo Controller with Kubebuilder
  4. Memcached Operator with Operator SDK

4. Understand more detail about each component

The walkthroughs and diagrams target client-go v0.37.1 and controller-runtime v0.25.1 from go.mod. They include implementation structure, construction paths, and runnable examples.

Simplified:

Detailed:

More Detailed:

from https://github.com/kubernetes/sample-controller/blob/master/docs/images/client-go-controller-interaction.jpeg

  1. client-go:
    1. clientset is a client for the built-in API resources.
    2. informer: watch the changes of objects and reflect the changes to the in-memory-cache.
      1. factory: informers.NewSharedInformerFactory
      2. watcher
      3. lister
      4. indexer
      5. event handler
      6. reflector
    3. lister: Get data from in-memory cache.
    4. indexer: in-memory cache
    5. workqueue: A queue to store items that the controller will process.
  2. code-generator:
    1. Generate codes for clientset for a custom resource.
  3. apimachinery:
    1. Scheme: connects Kubernetes API and Go Types, API version conversion
  4. controller-runtime
    1. builder
    2. cache
    3. client
    4. cluster
    5. controller
    6. handler
    7. inject
    8. log
    9. manager
    10. reconciler
    11. source
    12. webhook

Reference:

5. Create your own operator

After creating a sample operator, you should have deeper understanding of Kubernetes operator. Now you can think about what kind of problem that you want to resolve by utilizing operator pattern.

To clarify a problem to resolve with a new operator, you can reference existing operators:

operator role language
prometheus-operator Manage Prometheus, Alertmanager and their configuration Golang
mysql-operator Manage MySQL cluster Python
postgres-operator Manage PostgreSQL cluster (version upgrade, live volume resize, ...) Golang
strimzi-kafka-operator Manage Kafka cluster, user, and topic Java
... ... ...

Considerations:

6. Tools

7. Study Golang for better code quality

  1. golang-standanrds/project-layout
  2. Learn Go with tests
  3. The Current State of Go and Dependency Injection
  4. Go Blog
  5. Gopher Reading List
  6. Type Embedding

8. Other Topics

  1. Write Kubernetes Operator in other languages
  2. Optimistic Concurrency Control

9. Keep learning

10. Example test inventory

The runnable examples are intentionally split between unit tests and Kubernetes-backed tests:

Example Live API server Coverage
client-go/clientset Yes E2E target (API access)
client-go/deltafifo No Unit/fake objects
client-go/indexer No Unit/in-memory indexer
client-go/informer Yes E2E target; cache sync and Pod add/update/delete
client-go/lister No Unit/fake indexer
client-go/listerwatcher Yes E2E target; list/watch delivery
client-go/reflector No runnable binary Covered through informer/list-watch concepts
client-go/workqueue No runnable binary Unit-level concept
controller-runtime/cache Yes E2E target; cache sync and read
controller-runtime/example-controller Yes E2E target; ReplicaSet pod-count reconciliation
controller-runtime/manager Yes E2E target; manager startup and watches
controller-runtime/reconciler No Unit test/example
controller-runtime/source Yes, with its example CRD Documented live-cluster dependency; no remote CRD is applied by CI
controller-runtime/log No Process/unit example
controller-runtime/webhook Not by the standalone example Unit/process example; it does not register an API-server webhook

The live-cluster suites are selected independently as client-go and controller-runtime targets. CI creates a temporary kind cluster for each selected target. Developers can run either target against an existing cluster by setting KUBECONFIG; the runner removes only resources created by the test and never deletes a developer-provided cluster.

  1. 47 Things To Become a Kubernetes Expert
  2. Kubernetes API Basics - Resources, Kinds, and Objects
  3. Kubernetes API Conventions
  4. How To Call Kubernetes API using Simple HTTP Client
  5. How To Call Kubernetes API using Go - Types and Common Machinery
  6. How To Extend Kubernetes API - Kubernetes vs. Django
  7. Manage Custom Resources with client-go Without Generating a Client
  8. kubebuilder vs operator-sdk (2019-04-10)
  9. client-go Informer Source Analysis
  10. Operator Best Practices