Do you remember the placement days in your colleges? What a roller-coaster day they used to be. A mix of
anxiety, joy, and yes anguish too. When you deploy your amazing microservice or app on a Kubernetes
cluster, your workload also experiences a cocktail of emotions. Your app would be thinking – which node
will I get? Will there be enough CPU for me to work? Will I have enough storage to store my work? Will my
storage be fast enough like an SSD?
It is only fair for a developer to personify the app they build with personalities and emotions. After all, they
are the ones who spend so much time with the amazing app, raising it as its child tending it when it caught
a bug, carefully building the logic wall for it to only flourish in the time to come.
Turning our heads back at the scheduler in Kubernetes infrastructure. It is like those important students in
the placement committee who help you find the right company that fulfils your ambitions. Financially as well
as professionally. In Kubernetes they are responsible for assigning the workload pods to nodes.
Wish you could have expressed your ambitions like this during those placement days –
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig
If you ask, why should you bother about a configuration as a developer? To that question, we will respond –
If you have spent some time wrangling complex code in your app code’s logic, you would not have asked
that question. Configuration is the low mental bandwidth thing for the developer. Yet it is one of the most
notorious root causes for many issues a developer faces in the production environment. Thus, we urge
developers not to underestimate them. If possible, befriend them.
Similar to the flow of stages in a placement exercise, there are stages relevant to scheduling. These
lifecycle stages help you steer your workload to find the most appropriate node where they could flourish.
The life cycle stages in the scheduling activity of Kubernetes are – queueSort, preFilter, filter, postFilter,
preScore, score, reserve, permit, preBind, bind, postBind, multiPoint. As a student, we are sure you would
enjoy a high score stage leading to preBind stage to enter into an employment contract and eventually be
good enough to handle the multiPoint stage where you could grow to become a consultant with multiple
engagements.
Each stage has a few behaviours called plugins made available to developers by the vanilla
implementation of Kubernetes. You too have an option to expand it by creating your custom plugin. There
are many for each lifecycle stage. But the ones that probably resonate with a student's life would be
ImageLocality. It deals with placing workload to a specific node and is perhaps co-located to another
service. Like you prefer to work in the same city where your friend is working or going to work. Relating to
employment in your own hometown or Taints that repel you from some cities. Tolerations similarly might be
liked by employers as they do look for students who tolerate some versatility in the location of work.
A developer could also use multiple scheduler configurations to have the best of the worlds by doing
something like this –
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
– schedulerName: default-scheduler
– schedulerName: no-scoring-scheduler
We are sure as a student one would have loved the scheduler configuration that reads no-scoring
scheduler.
As a developer, you might say – “This is great for infrastructure but what should I do for the app?”. Let us
take an amazing plugin called Pod Topology Spread. This plugin ensures your app is distributed across
fault domains and uses optimally the available resources. This plugin requires a spec that specifies what is
acceptable. That is a configuration which you will make in your pod’s configuration file like this –
apiVersion: v1
kind: Pod
metadata:
name: srv1-pod
spec:
topologySpreadConstraints:
– maxSkew: 1
minDomains: 1
topologyKey: “linux-deb-netcore”
whenUnsatisfiable: “DoNotSchedule”
nodeAffinityPolicy: Honor
nodeTaintsPolicy: Ignore
This configuration is read by the scheduler which tries to honour it as much as possible. If you notice in this
specification there are values which tell the scheduler what it must do to honour it. The configuration
maxSkew tells how the pod can be unevenly distributed in the node topology. It has a bearing from another
specification in the file. When the whenUnSatisifable is configured to DoNotSchedule then it updates the
global minimum to the maximum difference between the number of matching pods. If the value for
whenUnsatisfiable is set to ScheduleAnyway the scheduler finds you topology that helps reduce the skew
in the cluster of nodes.
Drawing parallel to student life this plugin is similar to the head of the placement committee who is
determined to get maximum placement in keeping both fellow students happy as well as the visiting
employers. By reducing the friction between the expectations of employers and the abilities of students.
Amongst the stages listed earlier, the pivotal ones that a developer needs to keep in mind are filtering and
scoring. The scheduler would first filter and then for the filtered records will score the candidates/nodes in
the topology. The one we discussed a while ago can be used in either of the stages. Practically it is often
used in the filtering stage.
Advanced topics of dynamic scheduling and descheduler which offboards the resources allocation are
interesting topics for advanced use cases of scheduler. These are some advancements which even the
placement practices in our universities have not yet seen. We reserve discussion on them for a future
dispatch. Till then happy coding.