Kubernetes
Containers
Docker
Observability & Monitoring

Kubectl Cheat Sheet | Kubernetes Commands & Objects

Our topic today, `kubectl`, is a command line tool for Kubernetes that allows you to communicate with a cluster by using its API server.
February 2, 2024

Introduction 

Kubernetes, or K8s, is a comprehensive container orchestration platform with extensive networking, configuration management, and automation support. It rapidly became popular across the DevOps industry because of its flexibility and scalability.

Our topic today, `kubectl`, is a command line tool for Kubernetes that allows you to communicate with a cluster by using its API server. By using this tool, you can create, update, and delete Kubernetes resources or any behaviors supported. This cheat sheet will show you how to utilize commands in cluster, object, and data levels.

Key Features Provided by kubectl

  • Cluster management includes context control, node management, monitoring, and retrieving cluster information.
  • Quick creation of objects.
  • Objects management by patching a specific field or applying configurations by manifest files.
  • Retrieving data from logging, port-forwarding, and command execution inside a container.

Cluster Level

Cluster management is one of the key features provided by `kubectl`. Diving into cluster

management, we can get cluster information, monitor cluster resources, manage node

availabilities and more.

Cluster Control

kubectl config current-context 
Figure 1 - Kubectl Cheat Sheet | kubectl config current-context Command
Figure 1 - Kubectl Cheat Sheet | kubectl config current-context Command

This command shows you the cluster name that your `kubectl` is now controlling. All the commands being executed will target this cluster. It is also referring to the value of `currentcontext` in `~/.kube/config` in your machine.

Figure 2 - Kubectl Cheat Sheet | kubectl config current-context Command
Figure 2 - Kubectl Cheat Sheet | kubectl config current-context Command

Being a cluster operator, it is common to handle multiple Kubernetes clusters at the same time as they refer to different environments. It could be a critical issue if you execute `kubectl` command in the wrong cluster. Therefore, we should run this command daily from the start of the day, to make sure we are working on the cluster we need.

Here is some common context usage:

  1. One context per environment, like DEV, QA, Production
  2. One context per power user in the same environment, like system-administrator, developer
kubectl config get-contexts 
Figure 3 - Kubectl Cheat Sheet | kubectl config get-contexts Command
Figure 3 - Kubectl Cheat Sheet | kubectl config get-contexts Command

This command shows you all the contexts available in your machine. It is also referring the `contexts` section in `~/kube/config` in your machine.

Figure 4 - Kubectl Cheat Sheet | kubectl config get-contexts Command
Figure 4 - Kubectl Cheat Sheet | kubectl config get-contexts Command

Sometimes we have to know which cluster is control-able based on your config file, simply executing this command to get all the available clusters with which user and namespace you are going to use under each context.

kubectl config use-context "context-name"
Figure 5 - Kubectl Cheat Sheet | kubectl config use-context "context-name" Command
Figure 5 - Kubectl Cheat Sheet | kubectl config use-context "context-name" Command

This command allows you to switch to any context under your config file. It updates the `current-context` field in `~/.kube/config`.

Figure 6 - Kubectl Cheat Sheet | kubectl config use-context "context-name" Command
Figure 6 - Kubectl Cheat Sheet | kubectl config use-context "context-name" Command

A context contains three inputs. They are `cluster`, `namespace`, and `user`. For example, you can create multiple contexts pointing to different users in the same cluster. You can add any context to assist you in switching between clusters, users, and namespaces.

Node Management

Nodes are one of the important components in Kubernetes architecture as pods are running on nodes. `kubectl` provides the power of retrieving information, status intervention, maintenance control, and tainting of nodes.

kubectl get nodes
Figure 7 - Kubectl Cheat Sheet | kubectl get nodesCommand
Figure 7 - Kubectl Cheat Sheet | kubectl get nodes Command

This command provides the information of nodes, including the name, status, roles, age and version. It is an important command as a quick print of available nodes and their basic information, to make sure the cluster have enough healthy nodes to start pods.

Adding `-o wide` is a little trick to show more node level information.

Figure 8 - Kubectl Cheat Sheet | kubectl get nodes -o wide Command
Figure 8 - Kubectl Cheat Sheet | kubectl get nodes -o wide Command
kubectl describe nodes "node-name"
Figure 9 - Kubectl Cheat Sheet | kubectl describe nodes "node-name" Command
Figure 9 - Kubectl Cheat Sheet | kubectl describe nodes "node-name" Command

This command provides detailed information of a specific node, including labels, annotations, conditions, storage data, pod information, etc.

It has a similar purpose as `kubectl get nodes` but it gives you a much-detailed output for a better understanding of nodes. As a cluster operator, sometimes it can give ideas on debugging node-level issues.

kubectl cordon "node-name"
Figure 10 - Kubectl Cheat Sheet | kubectl cordon "node-name" Command
Figure 10 - Kubectl Cheat Sheet | kubectl cordon "node-name" Command

This command is used to mark a specific node as unschedulable.

The meaning of unschedulable is to stop new pods from starting on that node. It is a common action to cordon off a node for many purposes, such as debugging at the node level. If you want to prevent unexpected situations, you probably need this command.

On the other hand, we need to pay attention before executing this command in the production environment, as it could affect pod availability or auto-scaling ability without a well-cordon plan.

kubectl uncordon "node-name"
Figure 11 - Kubectl Cheat Sheet | kubectl uncordon "node-name" Command
Figure 11 - Kubectl Cheat Sheet | kubectl uncordon "node-name" Command

This command is to mark a specific node as schedulable.

Like the cordon command, it performs exactly the opposite task to mark a node back to schedulable. When a node-level issue has been fixed, you would like to bring the node back available.

Object Level

Through Kubernetes API, we can perform actions such as get, create, update, and delete to different kinds of objects. Objects include but are not limited to pods, deployments, services, secrets, and config maps. We can utilize `kubectl` for quick creation of objects, service expose, configuration with field patching, and applying changes with manifest files.

Object Management 

kubectl get "object-type"

Get list of pods: 

Figure 12 - Kubectl Cheat Sheet | kubectl get pods Command
Figure 12 - Kubectl Cheat Sheet | kubectl get pods Command

Get list of services: 

Figure 13 - Kubectl Cheat Sheet | kubectl get service Command
Figure 13 - Kubectl Cheat Sheet | kubectl get service Command

Get list of config maps: 

Figure 14 - Kubectl Cheat Sheet | kubectl get configmaps Command
Figure 14 - Kubectl Cheat Sheet | kubectl get configmaps Command

Get list of secrets: 

Figure 15 - Kubectl Cheat Sheet | kubectl get secrets Command
Figure 15 - Kubectl Cheat Sheet | kubectl get secrets Command

This command generates the information in a list according to the requested object type and provided arguments.

Retrieving information from the Kubernetes cluster is the most repeated and important task in daily operation. In all environments, it proves everything is working fine. That’s why this simple command is indispensable for us.

Other common types of objects: 

  • Namespace
  • Deployment
  • Ingress

Trick: You can use `kubectl api-resources` to list all the available types in your cluster. 

Quick Creation

kubectl run "pod-name" --image="image-name"
Figure 16 - Kubectl Cheat Sheet | kubectl run "pod-name" --image="image-name" Command
Figure 16 - Kubectl Cheat Sheet | kubectl run "pod-name" --image="image-name" Command
Figure 17 - Kubectl Cheat Sheet | kubectl run "pod-name" --image="image-name" Command
Figure 17 - Kubectl Cheat Sheet | kubectl run "pod-name" --image="image-name" Command

This command is to start a pod with the provided name and image. In most cases, we create Kubernetes objects by applying well-defined manifest files to better organize object definition and feature extension. Then, why do we need to know this command? 

As a DevOps Engineer, imagine when you need a pod for development purposes, it would be time-consuming to prepare a manifest file just for a pod you will delete soon. In that case, it provides an efficient way to start a pod in a few seconds.

kubectl expose pod "pod-name" --port="port-number" --type="service-type" -- name="service-name"
Figure 18 - Kubectl Cheat Sheet | kubectl expose pod "pod-name" --port="port-number" --type="service-type" -- name="service-name" Command
Figure 18 - Kubectl Cheat Sheet | kubectl expose pod "pod-name" --port="port-number" --type="service-type" -- name="service-name" Command

This command is to create a service that exposes the pod according to the options provided.

The above example shows a service exposing port 80 of the pod with a NodePort type. 

You can expose a pod in different types as follows:

  • ClusterIP: Expose the pod internally for cluster-wise availability. 
  • NodePort: Expose with a port allocated from the node machine.
  • LoadBalancer: Expose with a load balancer from your cloud provider.

Choosing the appropriate type is an important task as you need to prevent incorrect service expose. For example, it could be a security concern if you expose a database pod to the public by NodePort or LoadBalancer type. With a NodePort type, we can directly access the pod locally which is a common practice during the local development stage.

Figure 19 - Kubectl Cheat Sheet | kubectl expose pod "pod-name" --port="port-number" --type="service-type" -- name="service-name" Command
Figure 19 - Kubectl Cheat Sheet | kubectl expose pod "pod-name" --port="port-number" --type="service-type" -- name="service-name" Command

Therefore, in production, we should prevent using NodePort to expose services. Using Ingress would be a better option for exposing external services. 

kubectl create secrets generic "secret-name" --from-literal="key-name"="value"
Figure 20 - Kubectl Cheat Sheet | kubectl create secrets generic "secret-name" --from-literal="key-name"="value" Command
Figure 20 - Kubectl Cheat Sheet | kubectl create secrets generic "secret-name" --from-literal="key-name"="value" Command

This command creates a generic secret that stores sensitive information in key-value pair, such as a password, token, or key. 

During application deployment, different kinds of sensitive information will be used for authentication, authorization or anything that needs to be secretly handled. By using Kubernetes secrets, we can exclude sensitive information from application code which is not a recommended way in the production environment. 

Security is one of the biggest concerns of a DevOps Engineer. Making good use of Kubernetes secret could lower the possibility of secret leakage.

Remark: You can change `--from-literal` to `--from-file` to define secrets by file.

kubectl create configmap "configmap-name" --from-literal="key-name"="value"
Figure 21 - Kubectl Cheat Sheet | kubectl create configmap "configmap-name" --from-literal="key-name"="value" Command
Figure 21 - Kubectl Cheat Sheet | kubectl create configmap "configmap-name" --from-literal="key-name"="value" Command

This command creates a config map that stores non-sensitive information in a key-value pair.

Its nature is like Secrets in an opposite way. Pod can also consume config map as environment variables, command line arguments, or configuration files stored in volumes.

As it allows you to decouple environment-specific variables, it is an important concept for portable application setup. For example, we don’t need to hardcode the value of variables in the container image, which means using the same image to apply on multiple environments. 

Configuring

kubectl patch "object-type" "object-name" -p "patch-content"
Figure 22 - Kubectl Cheat Sheet | kubectl patch "object-type" "object-name" -p "patch-content" Command
Figure 22 - Kubectl Cheat Sheet | kubectl patch "object-type" "object-name" -p "patch-content" Command

This command patches specific or multiple fields of objects. The above screenshot shows updating the field `spec.type` of service from `NodePort` to `ClusterIP`.

While managing Kubernetes objects, there could be legacy items that you cannot configure due to missing manifest files. It is a useful command to apply changes to those items. However, it is only suggested to use in non-production environments and temporary changes as they are untraceable.

In all circumstances, it is always preferred to configure objects in a traceable way. For a better way of object configuring, please use the next command.

kubectl apply -f "file-name"
Figure 23 - Kubectl Cheat Sheet | kubectl apply -f "file-name" Command
Figure 23 - Kubectl Cheat Sheet | kubectl apply -f "file-name" Command

This command is to apply Kubernetes manifest file(s) to create or update the resources defined in the file.

Figure 24 - Kubectl Cheat Sheet | kubectl apply -f "file-name" Command
Figure 24 - Kubectl Cheat Sheet | kubectl apply -f "file-name" Command

Above is a manifest file example of creating a pod. Official Kubernetes documentation provides all the information of different kinds of resource manifest files.

As mentioned in the previous `kubectl patch` section, it is always preferred to configure objects in a traceable way. Executing this command, `kubectl` will search existing objects and see if any are matched. If there’s no matched object, it will create the object. Otherwise, it will configure the object by checking the differences between the values in the manifest file and the actual object attributes.

Using manifest files with `kubectl apply` can centralize creation and configuration. At the same time, those files can be managed by a version control system such as GitHub and GitLab, which leads to traceable object management.

Automation is a key factor in modern DevOps solutions. All histories need to be recorded since everything is going to be executed by itself without human intervention. Therefore, this command is strongly recommended from a DevOps or SRE Engineer perspective.

Data Level 

In the previous two levels, you have seen the usage of `kubectl` on cluster and object levels. At the data level, it also provides strong support for error tracing and troubleshooting.

kubectl logs -f "pod-name"
Figure 25 - Kubectl Cheat Sheet | kubectl logs -f "pod-name" Command
Figure 25 - Kubectl Cheat Sheet | kubectl logs -f "pod-name" Command

This command prints the container log in a streaming mode enabled by `-f.` 

Log tracing is the daily routine of DevOps or SRE Engineers. This command gives the ability to retrieve live-time container-level access logs. Its streaming mode allows us to get instant responses on all the actions against the container.

For SRE Engineers, their main duty is a rapid response to all incidents in the production environment by tagging their severity and assigning them to the correct teams. `kubectl logs` would be a great assistance in error tracing and evidence finding.

Remark: This command is container-specific. We don’t need to provide a container name because there is only one container in this pod. It will get the log of the default container.

Troubleshooting

kubectl exec "pod-name" – "command"
Figure 26 - Kubectl Cheat Sheet | kubectl exec "pod-name" – "command" Command
Figure 26 - Kubectl Cheat Sheet | kubectl exec "pod-name" – "command" Command

This command is used to execute a command in a container. From the above screenshot, it executed `date` in the default container of pod `nginx-pod`.

Except for log checking, executing a command in the problematic container is more straightforward. You can use this command in two ways: single command or interactive.

For a single command, it looks just like the example that executes one command in the container. You can also execute any other command that is available on the container image.

For the interactive way, you can switch the current process into raw terminal mode and send standard inputs(stdin) directly into the container. In this way, you can execute multiple commands by a single `kubectl exec` session. It is useful for troubleshooting as you can directly modify anything in the container, such as adding debugging code to print an error log.

Figure 27 - Kubectl Cheat Sheet | kubectl exec "pod-name" – "command" Command
Figure 27 - Kubectl Cheat Sheet | kubectl exec "pod-name" – "command" Command

Remark: This command is container-specific. We don’t need to provide container name because there is only one container in this pod. It will execute the command in the default container.

kubectl port-forward "object-type" / "object-name" "local-port":"remote-port"
Figure 28 - Kubectl Cheat Sheet | kubectl port-forward "object-type" / "object-name" "local-port":"remote-port" Command
Figure 28 - Kubectl Cheat Sheet | kubectl port-forward "object-type" / "object-name" "local-port":"remote-port" Command

This command performs port forwarding on your machine. It allows you to connect a specific remote port of the pod to a local port.

Port forwarding is a common practice in troubleshooting, especially while the pod is in a private network. As mentioned in the `kubectl expose` section, exposing service internally or externally is a serious topic. Production clusters are always configured in a restricted condition. As a result, port forwarding brings a huge benefit in that you can directly access the service without requesting extra network resources. 

Conclusion

That’s all this cheat sheet. You have got the skills to utilize `kubectl` on clusters, objects, and data levels. Try on your Kubernetes cluster now!