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
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.
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:
- One context per environment, like DEV, QA, Production
- One context per power user in the same environment, like system-administrator, developer
This command shows you all the contexts available in your machine. It is also referring the `contexts` section in `~/kube/config` in your machine.
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.
This command allows you to switch to any context under your config file. It updates the `current-context` field in `~/.kube/config`.
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.
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.
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.
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.
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
Get list of pods:
Get list of services:
Get list of config maps:
Get list of secrets:
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
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.
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.
Therefore, in production, we should prevent using NodePort to expose services. Using Ingress would be a better option for exposing external services.
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.
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
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.
This command is to apply Kubernetes manifest file(s) to create or update the resources defined in the file.
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.
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
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.
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.
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!