KEMBAR78
Brief intro to K8s controller and operator | PDF
K8s controller
A platform for automating:
•deployment,
•scaling, and
•management
of containerized applications
k8s
CLI
API
users master nodes
etcd
schedul
er
controll
ers
apiserv
er
kubelet
kube-
proxy
add-ons
cri
System components
workloads
workloads
✤ While the controllers are
level-based (as
described here and here)
to maximize fault
tolerance, they
typically watch for changes
to relevant resources in
order to minimize
reaction latency and
redundant work.
controller
✤ observe
✤ diff
✤ act
https://github.com/kubernetes/community/blob/
8cafef897a22026d42f5e5bb3f104febe7e29830/
contributors/devel/controllers.md
observe
diff
act
controller - observe
// Set up an event handler for when Foo resources change
// https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L117
fooInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: controller.enqueueFoo,
UpdateFunc: func(old, new interface{}) {
controller.enqueueFoo(new)
},
})
// enqueueFoo takes a Foo resource and converts it into a namespace/name
// string which is then put onto the work queue. This method should *not* be
// passed resources of any type other than Foo.
// https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L338:22
func (c *Controller) enqueueFoo(obj interface{}) {
var key string
var err error
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { // namespace/fooname
utilruntime.HandleError(err)
return
}
c.workqueue.Add(key)
}
controller - diff
// syncHandler compares the actual state with the desired, and attempts to
// converge the two. It then updates the Status block of the Foo resource
// with the current status of the resource.
func (c *Controller) syncHandler(key string) error {
*****
foo, err := c.foosLister.Foos(namespace).Get(name)
deploymentName := foo.Spec.DeploymentName
if deploymentName == "" {
// We choose to absorb the error here as the worker would requeue the
// resource otherwise. Instead, the next time the resource is updated
// the resource will be queued again.
utilruntime.HandleError(fmt.Errorf("%s: deployment name must be specified", key))
return nil
}
// Get the deployment with the name specified in Foo.spec
deployment, err := c.deploymentsLister.Deployments(foo.Namespace).Get(deploymentName)
****
https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L243
controller - act
// If the resource doesn't exist, we'll create it
if errors.IsNotFound(err) {
deployment, err = c.kubeclientset.AppsV1().Deployments(foo.Namespace).Create(newDeployment(foo))
}
err = c.updateFooStatus(foo, deployment)
if err != nil {
return err
}
c.recorder.Event(foo, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced)
https://github.com/kubernetes/sample-controller/blob/
0e5b089d858f35daf461613074207039f23cac77/controller.go#L321
CustomResourceDefinition
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
name: modules.application.mskj.cmbc.com.cn
spec:
group: application.mskj.cmbc.com.cn
names:
kind: Module
plural: modules
scope: Namespaced
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-
conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-
conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
type: object
status:
type: object
version: v1beta1
operator-sdk by CoreOS
✤ Operators implement and automate common Day-1 (installation,
configuration, etc) and Day-2 (re-configuration, update, backup,
failover, restore, etc.) activities in a piece of software running inside
your Kubernetes cluster, by integrating natively with Kubernetes
concepts and APIs. We call this a Kubernetes-native application.
With Operators you can stop treating an application as a collection
of primitives like Pods, Deployments, Services or ConfigMaps, but
instead as a single object that only exposes the knobs that make
sense for the application.
✤ https://operatorhub.io/
kubebuilder
✤ https://kubebuilder.io/
Q&A

Brief intro to K8s controller and operator

  • 1.
  • 2.
    A platform forautomating: •deployment, •scaling, and •management of containerized applications k8s
  • 3.
  • 4.
  • 5.
    workloads ✤ While thecontrollers are level-based (as described here and here) to maximize fault tolerance, they typically watch for changes to relevant resources in order to minimize reaction latency and redundant work.
  • 6.
    controller ✤ observe ✤ diff ✤act https://github.com/kubernetes/community/blob/ 8cafef897a22026d42f5e5bb3f104febe7e29830/ contributors/devel/controllers.md observe diff act
  • 7.
    controller - observe //Set up an event handler for when Foo resources change // https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L117 fooInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: controller.enqueueFoo, UpdateFunc: func(old, new interface{}) { controller.enqueueFoo(new) }, }) // enqueueFoo takes a Foo resource and converts it into a namespace/name // string which is then put onto the work queue. This method should *not* be // passed resources of any type other than Foo. // https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L338:22 func (c *Controller) enqueueFoo(obj interface{}) { var key string var err error if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { // namespace/fooname utilruntime.HandleError(err) return } c.workqueue.Add(key) }
  • 8.
    controller - diff //syncHandler compares the actual state with the desired, and attempts to // converge the two. It then updates the Status block of the Foo resource // with the current status of the resource. func (c *Controller) syncHandler(key string) error { ***** foo, err := c.foosLister.Foos(namespace).Get(name) deploymentName := foo.Spec.DeploymentName if deploymentName == "" { // We choose to absorb the error here as the worker would requeue the // resource otherwise. Instead, the next time the resource is updated // the resource will be queued again. utilruntime.HandleError(fmt.Errorf("%s: deployment name must be specified", key)) return nil } // Get the deployment with the name specified in Foo.spec deployment, err := c.deploymentsLister.Deployments(foo.Namespace).Get(deploymentName) **** https://github.com/kubernetes/sample-controller/blob/0e5b089d858f35daf461613074207039f23cac77/controller.go#L243
  • 9.
    controller - act //If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { deployment, err = c.kubeclientset.AppsV1().Deployments(foo.Namespace).Create(newDeployment(foo)) } err = c.updateFooStatus(foo, deployment) if err != nil { return err } c.recorder.Event(foo, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced) https://github.com/kubernetes/sample-controller/blob/ 0e5b089d858f35daf461613074207039f23cac77/controller.go#L321
  • 10.
    CustomResourceDefinition apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: creationTimestamp:null labels: controller-tools.k8s.io: "1.0" name: modules.application.mskj.cmbc.com.cn spec: group: application.mskj.cmbc.com.cn names: kind: Module plural: modules scope: Namespaced validation: openAPIV3Schema: properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api- conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api- conventions.md#types-kinds' type: string metadata: type: object spec: type: object status: type: object version: v1beta1
  • 11.
    operator-sdk by CoreOS ✤Operators implement and automate common Day-1 (installation, configuration, etc) and Day-2 (re-configuration, update, backup, failover, restore, etc.) activities in a piece of software running inside your Kubernetes cluster, by integrating natively with Kubernetes concepts and APIs. We call this a Kubernetes-native application. With Operators you can stop treating an application as a collection of primitives like Pods, Deployments, Services or ConfigMaps, but instead as a single object that only exposes the knobs that make sense for the application. ✤ https://operatorhub.io/
  • 12.
  • 13.