Blog: https://blog.zespre.com • Roles • Senior Software Engineer at SUSE • Consultant at FreeBSD Foundation • Projects I’m currently working on • Harvester HCI • OpenStack on FreeBSD • KubeVirtBMC 2
• What pushes you to do this (the WHY) • To enable something that never works/exists in the current K8s cluster? • To create a better wheel than the existing one? • To be the coolest kid in the town • What do you want for it to achieve (the WHAT) • To be the operator for some other applications (configuration/life-cycle management)? • To be a cloud-native application? • What libraries/tools/framework do you want to leverage (the HOW) • client-go/controller-runtime • kubebuilder • Operator SDK • Lasso/Wrangler 3
The Matrix Trilogy? • You are the operator • Ensure the installation/removal workflow works for the target app • Reflect config changes to the target app • Cloud-native application • Build from the ground up • Might need to revamp the architecture (keep in mind that this will run on a cluster) 4
and kind (GVK) • Main blocks (applies to almost all the K8s resources) • `.spec` defines the desired state • `.status` represents the observed state (~= actual state) • Objects instantiated from the CRD template called custom resource (denoted as CR thereafter) • Store all the important bits for controllers to reconcile 7
control loop (reconciler) • Reads the state of resources from etcd via the API server • Changes the state of resources and takes necessary actions to the external world • Updates the status of resources in etcd via the API server • A controller implements a control loop • An operator embeds operational knowledge and consists of several controllers 8
the time in the distributed world • Locking mechanism introduces performance issues • Why is it called optimistic? • API server is optimistic • “It’s all their (clients’) fault” • Part of the controller logic is optimistic • YOU are the one who is pessimistic framework to the rescue! • Implementation detail • Every Kubernetes object has `resourceVersion` • Write operation rejected if `resourceVersion` conflict • Clients, i.e., controllers, are obliged to do the retry • Intermediate business logic must be retriable (optimistic) 9
objects before persisted • Mutator • Invoked first • Patch the requested objects • Typical use cases: add “default values” and relevant “labels” • Validator • Think of it as a particular case of mutator: do no alternation to the objects • Reject the request if it does not fulfill the criteria • Typical use case: check if “the requirements have been met” or “is safe to delete” • A good way to hijack objects before other entities process them • Handy, but beware • Better to be lightweight with no side effects • Responsibility: do not overtake controllers 10
desired state • Always get the same results no matter how many times being run • Orthogonal • Each set of conditions represents a different aspect of the object • State machine 11
need to fiddle with CRD schema, no conversions 😉 • Flexible, you can store whatever you want, data, states, signals, etc. 😉 • Chaotic, hard to maintain if the number grows 😵💫 • Burdensome, don’t know how to use at first glance 😵💫 • Use at your own risk 😈 12
be used to generating controller templates, clientsets, etc. 15 // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/ runtime.Object type Order struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec OrderSpec `json:"spec,omitempty"` Status OrderStatus `json:"status,omitempty"` } type OrderSpec struct { MealConfig `json:"mealConfig"` Sets int `json:"sets"` Chef string `json:"chef,omitempty"` } type OrderStatus struct { Condition string `json:"condition"` }
• Start the test cluster with envtest (only API server and etcd) • Add the types to the default client-go K8s scheme • Create a client for test CRUD operations • Hook up your custom controller/event handler • Start the controller manager • After suite • Stop the controller manager • Stop the test cluster 19
container image • Write manifests to run the application/controller on Kubernetes • Deployment/DaemonSet/StatefulSet • Ingress/Service/Endpoint • RBAC • … etc. • Derive Helm charts for distributing the application and easy installation 20
• Formerly called KubeBMC, but found it confusing • Built with kubebuilder • Target to provide a subset of IPMI & Redfish functionalities for KubeVirt VMs • Power management • Boot device management • Image mount • How-tos: https://github.com/starbops/kubevirtbmc/wiki#the-slow-start-guide • Proposed to join the KubeVirt organization • Contributions are welcome 🤗 22
• A tiny computer that (almost) always watches the server’s back • Up and running as long as the power cord is plugged • Provide a specific set of services, including power and boot device management over the network (so-called out-of-band management) • “Redfish is the new IPMI” 23
OpenStack VirtualBMC but in a cloud/Kubernetes-native fashion • Distributed and horizontal-scalable • Leverage K8s APIs • Business logic • `virtbmc-controller` (manager) • Reconcile VirtualMachineBMC, VirtualMachine, and Service objects • Deploy virtbmc Pod and Service for each VM • `virtbmc` (agent) • Run an IPMI simulator • Decode IPMI commands and translate them to K8s API calls 24
state machine in mind • Introduce a new CRD - Upgrade (`upgrades.harvesterhci.io/v1beta1`) • Workflow control point • Upgrade relevant metadata • A bunch of control loops reconcile different kinds of (custom) resources • Upgrade • Pod/Job/Secret/Node • CRDs from other projects include Plan, ManagedChart, etc. 27
perspective) • An upgrade involves almost all kinds of objects • Logs are scattered in different pods • Hard to troubleshoot if something goes wrong • A slight move in one part can affect the whole system • It never rains but it pours 29
• Designed with control and data planes • Topology-aware • Currently only work with Harvester • Try to be provider-agnostic, but apparently it’s not possible • Built with Wrangler framework 31
traditional DHCP servers but in a cloud/Kubernetes-native fashion • Business logic • VM DHCP controller (manager) • Reconcile IPPool, VirtualMachineNetworkConfig, and VirtuamMachine objects • Watch Pod events, then trigger IPPool resync • Deploy agents according to IPPool objects and decide where to deploy depending on the following criteria • Target network to serve (net-attach-def) • Nodes that comprise the target network (node affinity) • Handle IP address allocation/deallocation (IPAM) • VM DHCP agent • Sync with API server for IPPool to ensure in-memory DHCP leases • Run a native DHCP serving process 32
run an existing solution like ISC Kea or Dnsmasq and then maintain its configuration? • It could be done that way… • At the cost of customizability, scalability, and the possibility of not- playing-well-with-containers • It becomes a totally different set of problems to solve • It’s boring 36
a command line interface • Generate near-ready-to-ship projects • You are (only) responsible for implementing control loops • Recommended for beginners • Wrangler • Feel like actually writing “controllers” • Handy and feature-rich 37
• The Mechanics of Kubernetes • Events, the DNA of Kubernetes • What the heck are Conditions in Kubernetes controllers? • Groups and Versions and Kinds, oh my! • Introduction to the Informer Pattern 38