In this part of the Kubernetes deep dive, I am going to discuss one of the very useful K8s features called Generators.
K8s provides two ways of defining/managing configuration.
a] Imperative — Manage K8s object using CLI ( imperative commands)
b] Declarative — By defining K8s objects in yaml file.
For creating multiple complex object, declarative approach is preferred as it follows Infrastructure as a Code approach. However, imperative approach is also useful when we want to do quick POC and save yourself from writing yaml files. Let’s take a look at some imperative commands.
One of the most popular and useful imperative command is kubectl run which is used to create different K8s objects. E.g Create an nginx deployment with 3 replicas and expose it on port 8080. Label each pod as app=frontend.
As you can see it helps you quickly try out nginx pod with multiple configuration options. By default kubectl run creates K8s Deployment object. However, we can also use it to create other objects such as Pod, Job and CronJob. The ‘kind’ of object to create can be defined using generators.
As the name suggests, Generators are used to define what object to generate. You can use — generator option in kubectl run to create different types of objects. Following table gives list of objects and corresponding generator to be used.
As seen in above table, deployment/v1beta1 is the default generator used in kubectl run command.
Let’s take a few examples example.
kubectl run nginx --image=nginx:latest --generator=run-pod/v1 --limts="cpu=200m,memory=512Mi" kubectl run busybox --image=busybox --dry-run --generator=cronjob/v1beta1 --schedule="*/1 * * * *" -- /bin/sh -c "date; echo hello from kubernetes cluster"
You might feel that remembering the generator names could be a bit difficult. Don’t worry we have a shorthands for them.
Shorthand for generators
You don’t need to specify generators every time in kubectl run. Instead you can just specify restart policy. K8s will make an intelligent call to determine which object to create.
# E.g --restart=Never creates a Podkubectl run buysbox --image=busybox:latest --rm -it --restart=Never pod "buysbox" created
List of shorthands:
a] Deployment: Don’t specify the flag
b] Pod : — restart=Never
c] Job: — restart=OnFailure
c] CronJob: — restart=OnFailure — schedule=<some cron expression>
As you can see this a very powerful way of quickly defining and experimenting with objects.
Moving from Imperative to Declarative
Thought imperative way is cool and quick, eventually we need to folllow Infrastructure as Code approach for long term benefits. But that involves editing YAML files which many feel is tedious job. You can avoid that pain too if you know a simple trick. K8s provides a way to convert kubectl run command configuration into yaml file. You can review/edit the yaml and then use declarative way ( kubectl create -f ). It can be done using two simple flags. — dry-run -o yaml.
kubectl run buysbox --image=busybox:latest --rm -it --restart=Never --dry-run -o yaml > busybox.yaml
Here busybox.yaml will contain Pod definition of busybox pod. Cool ! isn’t it ?
Kubernetes object configuration may look daunting sometimes. However, with practice and a few useful tricks it can become really enjoyable.