Acing the CKAD

CKAD Tips: Kubernetes Object Management Techniques

Why You Should Know Them for the CKAD Exam

Edidiong Asikpo
Ambassador Labs
Published in
9 min readFeb 3, 2022

--

Welcome to the 4th article in my CKAD Tips series, where I share the learnings gained from preparing for my upcoming CKAD exam and tips geared towards helping you excel when you eventually take your CKAD exam.

In today’s article, I’ll be talking about Kubernetes objects — what they are, how to create them imperatively or declaratively, and why understanding these two approaches can increase your chances of passing the CKAD exam.

What are Kubernetes Objects?

According to the official documentation, Kubernetes objects are persistent entities used to represent the state of a cluster — they describe what containerized applications are running (and on which nodes), the resources available to those applications, and the policies around how those applications behave (such as restart policies, upgrades, and fault-tolerance).

Fundamentally, when you create an object, you are defining the components that make up the state of your cluster, and the Kubernetes system will keep working to ensure that your cluster maintains that specified state no matter what.

There are many Kubernetes objects, some used very often, and others rarely used. To see the complete list of all the objects available on Kubernetes, run this command kubectl api-resources on your terminal.

How to create Kubernetes objects

Kubernetes exposes an API via the kube-apiserver that allows developers to query and manipulate the state of objects. One of the ways of communicating with this API is by using REST calls, a custom client, or a local client like kubectl.

This article will only focus on how to use the kubectl command-line tool to interact with the Kubernetes API, query, and manage Kubernetes objects.

At the time of this writing, there are two approaches you can follow to manage (create, update, delete, etc) Kubernetes objects using kubectl — the imperative and declarative management approach. Let’s demystify these approaches 👇

Managing Kubernetes objects using the Imperative approach

The imperative approach of creating and managing Kubernetes objects requires you to pass operations that will give you the desired state of your cluster directly in your terminal.

The imperative approach is divided into two sub approaches — the imperative commands and imperative object configuration.

Using the imperative command:

Here, you operate directly on the live objects existing in your Kubernetes cluster or in a remote registry like Docker Hub and you’d also have to describe the proposed state of the Kubernetes object as arguments or flags using the kubectl command-line tool.

For instance, if you wanted to create a pod using the imperative command approach, you’d run this command on your terminal:

kubectl run mypod — image=nginx

The Nginx image you used to create this pod imperatively could have either been available on your Kubernetes cluster or on a Docker registry. And just within a matter of seconds, you’ve been able to create a Pod without writing any YAML configuration file.

Using the imperative object configuration:

Here, you are still required to specify the operations (create, delete, and update) on the go, but the only difference is that your command must contain a YAML configuration file that contains the full definition of the proposed object you want to manage.

This configuration file can either:

  • Be created directly on your terminal using the Linux touch command: touch pod-definition.yml
  • Be created using your preferred IDE on your computer (But doesn’t include all the operations you need to get your desired state and that’s why you’d have to add these operations later directly in the command line).

Let’s use the YAML configuration file below to create a pod using the imperative object configuration approach:

apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
type: frontend
spec:
containers:
- name: nginx-container
image: nginx

Save this file as pod-definition.yml. Now, go to your command line and run this command: kubectl create -f pod-definition.yml

Here, you didn't have to specify the details of the object you wanted to create as that has already been included in the YAML file.

The Imperative Object Configuration approach is often confused with the declarative approach, but there’s a difference between them.

Managing Kubernetes objects using the Declarative approach

When utilizing the declarative object configuration approach, a user operates on object configuration files stored locally like the imperative configuration method.

However, the user doesn’t define the operations to be taken on the files (create, update, and delete) as they are included in the configuration file and are detected by kubectl. Here’s how it works in action:

kubectl apply -f pod-definition.yml

As you can see we didn’t add the create operation here, but this pod was still created successfully in the Kubernetes cluster.

Utilizing both approaches for the CKAD exam

As mentioned in the Kubernetes Architecture Explained article, the CKAD is a practical hands-on exam that lasts for 2 hours. Due to this time constraint, the faster you implement tasks, the better– every second counts!

The ability to easily and quickly identify which Kubernetes object management approach to use for each task will increase your chances of passing the CKAD exam. That’s what I’ll be explaining in this section of the article.

Scenario 1: Manage a single Kubernetes object

Let’s imagine your first task was to create a pod using the Nginx image

  • If you use the imperative command in this approach, all you’d have to do is run this command kubectl run newpod — image=nginx.
  • To use the declarative object configuration approach, you’d have to confirm that this configuration file exists and has all the required information that will create the pod as directed. After confirming, run this command: kubectl apply -f {pod configuration file}. However, if this configuration file doesn’t exist, there’s nothing you can do as you can’t use the declarative approach to create a configuration file.

After reading through the steps required to complete the task for each approach, you’d agree with me that the better way to complete this task is by using the imperative command. It is fast, straight to the point, and can be completed in seconds.

Scenario 2: Create a Kubernetes object, then modify

Imagine you had a task to create a Kubernetes object, e.g. a pod, and the task required that you would modify that object afterwards.

This is one of those cases where using the imperative and declarative approaches together would help you achieve the desired result faster!

What you would need to do in this case is start with the imperative approach and move to the declarative approach. For example, to expose the port on a pod named one, you would do the following:

  • Use the imperative approach to create a service configuration file using this command: kubectl expose pod one — port=8080 — name one-service > service.yml
  • With this command, you’ve not just created a service, you’ve also generated a configuration YAML file; if you run cat service.yml you’ll see the contents of the YAML file.
  • Now to update the state of this object with new configuration details, you can modify the YAML file directly using the vi editor on your terminal using this command vim service.yml

Using both approaches together can also be very useful in Scenario 1. Instead of not being able to use the declarative approach because of the absence of a yaml file, you can use the imperative approach to create the file, modify it to meet your needs, and then apply it to the cluster using the kubectl apply command.

Scenario 3: Manage multiple Kubernetes objects at once

Now, imagine if your third task was to create five services for five different pods named (one, two, three, four & five).

  • Using the imperative command would mean running something similar to this command kubectl expose pod one — port=8080 — name one-service five times, and the only thing you’d need to change is the pod name and service name.
  • Using the declarative object configuration approach would mean creating a configuration file, say service-definition.yml, then adding the config details for each of those services while ensuring that they are formatted well, and then running the kubectl apply -f service-definition.yml

While using the imperative command is faster, it is less obvious like in scenario 1. This is because if you are fast at creating and editing YAML files using Vim, there’s a chance that you can implement the task faster using the declarative method.

But we all know that editing on Vim isn’t as seamless as editing on an IDE on our computer. So, going with the imperative approach is highly recommended in this case.

💡 Edidiong’s CKAD tip: You will be allowed to use the Kubernetes documentation during CKAD exam, so you can always copy sample configuration files (e.g pods, deployments, replica sets, etc) from the docs and edit them to meet your needs.

Scenario 4: Manage a Kubernetes object with an existing configuration file

Let’s say the next task you were expected to complete was to create a deployment using an existing deployment file named deployment-definition.yml. Here’s what the flow would look like:

  • The file already exists, so you don’t have to create a new one from scratch. All you need to do is create this using the imperative approach is to run this command: kubectl create -f deployment-definition.yml
  • Due to the existence of the file, you can also use the declarative apply command here: kubectl apply -f deployment-definition.yml

Using these two commands will get you what you need; however, it is advisable to use the kubectl apply -f deployment-definition.yml in this case because the task only wants you to create a deployment and not fix an issue — meaning that everything has been done correctly.

Scenario 5: Search operation

Imagine if your cluster had 5 namespaces, and your task was to find which namespace had a pod named kubo:

  • The imperative way to do this would be to run kubectl get pods — all-namespaces | grep kubo
  • In this case, there’s no way to use the declarative approach, so using the imperative is the advised choice here.

Conclusion

Just like everything in life, the Kubernetes object management techniques shared in this article have their pros and cons. The declarative way helps implement your desired state of the cluster without you adding operations to the commands or repeating yourself. On the other hand, the imperative way makes you manage objects swiftly, and that speed is exactly what you need for the CKAD.

I hope you found this article useful. If you have any questions or concerns, share them in the comment section.

Special thanks to my friend Idowu Emehinola, who shared his experience with using these different Kubernetes object management techniques during his CKAD exam.

Ace the CKAD with me

This article is part of the CKAD Tips weekly series, where I write articles that will enable anyone studying for the CKAD to excel during the examinations. Stay up to date on the latest additions to this series by following us on Medium or Twitter and kickstart your Kubernetes learning on our Kubernetes Developer Learning center.

The CKAD series, so far:

--

--