Modular Kubernetes Programming— Part II
This is a follow up post to the one published yesterday titled “Modular Kubernetes Programming”. If you aren’t familiar with modular Kubernetes resources, please read the previous article in this series before continuing.
The previous article talks about the advantages of dividing Kubernetes resources into modules, and showed the use of animport
statement to import a module into another module.
This article dives into using theparams
keyword in Koki Short.
Parametric Modules
Modules in Koki Short have been designed to be not just evolvable, but also configurable. This provides the maximum flexbility for users using this system.
Consider this Pod definition:
pod:
containers:
- env:
- from: metadata.namespace
key: POD_NAMESPACE
expose:
- admin-port: 8080
- driver-port: 28015
- cluster-port: 29015
image: gcr.io/google_containers/rethinkdb:1.16.0_1
name: rethinkdb
volume:
- mount: /data/rethinkdb_data
store: rethinkdb-storage
labels:
db: rethinkdb
role: admin
name: rethinkdb-admin
version: v1
volumes:
rethinkdb-storage: empty_dir
In Kubernetes, labels
and annotations
are used to decorate resources with custom metadata. Generally, labels
are shared between different resources and are used to select resources of specific kinds.
For instance, if you wanted to front the pod defined above with a Service
resource, then the service would “select” this pod by looking for all pods with a certain label.
Since labels are shared between various resources, their definitions should be created, updated and managed together. We already saw how a module system could be beneficial here. Let’s modularize the pod above to use labels from a module instead of repeating them in each file.
pod:
containers:
- env:
- from: metadata.namespace
key: POD_NAMESPACE
expose:
- admin-port: 8080
- driver-port: 28015
- cluster-port: 29015
image: gcr.io/google_containers/rethinkdb:1.16.0_1
name: rethinkdb
volume:
- mount: /data/rethinkdb_data
store: rethinkdb-storage
labels:
db: rethinkdb
role: admin
name: rethinkdb-admin
version: v1
volumes:
rethinkdb-storage: empty_dir
The text in bold is the module boundary. Let’s put everything within the boundary into a different module. Let’s name the module definition file rethink-labels-module.yaml
, containing the data below:
labels:
db: rethinkdb
role: admin
Now, let’s update the original pod definition to use this module
imports:
- labels: ./rethink-labels-module.yaml
pod:
containers:
- env:
- from: metadata.namespace
key: POD_NAMESPACE
expose:
- admin-port: 8080
- driver-port: 28015
- cluster-port: 29015
image: gcr.io/google_containers/rethinkdb:1.16.0_1
name: rethinkdb
volume:
- mount: /data/rethinkdb_data
store: rethinkdb-storage
labels:
${labels}
name: rethinkdb-admin
version: v1
volumes:
rethinkdb-storage: empty_dir
The above module system works perfectly when the labels are used exactly as defined in the module file.
Let’s consider the scenario where the role
defined in the labels module is not always admin
. If you wish to specify the role as user
in another resource, the params
feature in Koki Short is the answer!
Theparams
keyword is used to parameterize the imported module. This save significant amount of time, which would otherwise be required to rewrite the same configuration multiple times with minor changes. Let’s use params
to change the role
to user
params:
- role: "role of the rethinkdb service (admin|user)"
default: admin
labels:
db: rethinkdb
role: ${role}
When importing this module, the role
can be parameterized
imports:
- labels: ./rethink-labels-module.yaml
params:
role: user
pod:
containers:
- env:
- from: metadata.namespace
key: POD_NAMESPACE
expose:
- admin-port: 8080
- driver-port: 28015
- cluster-port: 29015
image: gcr.io/google_containers/rethinkdb:1.16.0_1
name: rethinkdb
volume:
- mount: /data/rethinkdb_data
store: rethinkdb-storage
labels:
${labels}
name: rethinkdb-admin
version: v1
volumes:
rethinkdb-storage: empty_dir
Let’s expand the whole parameterized, modularized resource and see the final result.
$ short -k -f rethinkdb.yaml
The output looks like this
apiVersion: v1
kind: Pod
metadata:
labels:
db: rethinkdb
role: user
name: rethinkdb-admin
spec:
containers:
- env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: gcr.io/google_containers/rethinkdb:1.16.0_1
name: rethinkdb
ports:
- containerPort: 8080
name: admin-port
protocol: TCP
- containerPort: 28015
name: driver-port
protocol: TCP
- containerPort: 29015
name: cluster-port
protocol: TCP
resources: {}
volumeMounts:
- mountPath: /data/rethinkdb_data
mountPropagation: ""
name: rethinkdb-storage
volumes:
- emptyDir: {}
name: rethinkdb-storage
The role has been parameterized to be user
.
Conclusion
This blog post sheds more light onto the param
keyword in the module system. This powerful feature provide users with the flexibility needed for creating, reading, writing and managing Kubernetes manifests easily.
You can learn more about Short or download examples to play with. You can also try out the Chrome extension to translate live on your browser!
Stay tuned for more deep dives into Modular Kubernetes programming using Koki Short!