Introduction
Kubernetes was born out of the need to make our complex applications highly available, scalable, portable and deployable in small microservices independently. It also extends its capabilities to make adoption of DevOps processes and helps you set up modern Incident Response strategies to enhance the reliability of your applications.
Running applications in Kubernetes
Despite its complex internal architecture and API flows, Kubernetes makes it easy for users to do things with objects like deployments, services, ConfigMaps and secrets, since Kubernetes is designed to abstract away many of the complexities of managing these objects. As a result, users can focus on running their applications without having to worry about the internal details of Kubernetes.
Let's explore how users can interact with Kubernetes.
Kubectl
Kubectl is like a Swiss Army knife of container orchestration, deployments and management. It is a powerful command line tool that can be used to manage Kubernetes deployments and resources. With it, you can inspect Kubernetes objects, view logs and perform other operational tasks. Kubectl is so powerful that every action in Kubernetes can be controlled via kubectl commands.
Imperative and Declarative methods
There are two main ways to manage Kubernetes objects: imperative (with kubectl commands) and declarative (by writing manifests and then using kubectl apply). Each has its own advantages and disadvantages, so it's best to choose one method based on your use case.
Imperative commands are great for learning and interactive experiments, but they don't give you full access to the Kubernetes API. They're more commonly used to create YAML manifests and objects on the go. Declarative commands are useful for reproducible deployments and production. They're commonly used in CI/CD pipelines and Helm charts, where YAML manifests need to be present beforehand.
Pros and Cons
Each type of command has pros and cons, so it's important to decide which one will work best for your needs. Here's a brief overview of the pros and cons of each method.
Command | Pros | Cons |
Declarative | The chance for human error is low when the YAML manifest is already present. | If you don't have YAML manifests, you cannot use declarative commands. |
Imperative | Since you can create objects on the fly with these commands, productivity is increased. This is especially useful when you need to create an object quickly and don't have time to go through the process of creating it from scratch. | There's an increased chance of human error when every configuration has to be specified in one-liners. |
Deep Dive Into Imperative Commands
In this section, we will see how to use kubectl imperative commands to interact with Kubernetes clusters and do various operations on Kubernetes objects. This can be useful for managing Kubernetes clusters and developing applications.
Create
The kubectl CLI is commonly used to create objects. In order to create an object, kubectl’s imperative commands require the user to explicitly specify the type of object they wish to create, along with the properties they wish to associate with the object being created.
The syntax for kubectl's imperative command to create objects can be summarized as follows:
kubectl create <type-of-object> [<subtype-of-object>] <name-of-object> <properties>
Since some Kubernetes objects have several subtypes, a user is required to specify the subtype-of-object parameter as well. For example, a Kubernetes service has several subtypes like ClusterIP, NodePort or LoadBalancer. A user is required to specify the service type as a subtype-of-object parameter when creating a service.
The syntax for creating a 'nodeport' service is pretty simple and can be summarized as follows:
kubectl create service nodeport <name-of-service> <properties>
An example of the above syntax:
kubectl create service nodeport my-ns --tcp=5678:8080
Another example of where you would be required to specify a subtype-of-object parameter is when you're creating a secret. A secret inside Kubernetes can be of the generic, TLS or Docker-registry type.
The syntax for creating a generic secret is pretty straightforward:
kubectl create secret generic
An example of the above syntax:
kubectl create secret generic my-secret --from-literal=key1=supersecret
Examples
It can be helpful to become more familiar with the imperative commands related to the creation, so let's take a look at some additional syntaxes along with examples.
Example: Create a config map with a ‘name=squadcast’ key-value pair.
kubectl create configmap <name> --from-literal=<key>=<value>
kubectl create configmap cm123 --from-literal=name=squadcast
Example: Create a deployment with the name Squadcast running three replicas of Ubuntu.
kubectl create deployment <name> --image=<image> --replicas=<replicas>
kubectl create deployment squadcast --image=ubuntu --replicas=2
Example: Create a job with the name Squadcast executing the sleep command on Ubuntu.
kubectl create job <name> --image=<image> -- <command> <argument>
kubectl create job squadcast --image=ubuntu -- sleep 200
In addition to 'create', there are other functions that can help you work with Kubernetes, like 'expose' and 'run'. Let's take a look at them, too.
Expose
A service object is how a user interacts with an application in Kubernetes, and how different microservices communicate with each other. In other words, for any application to be usable on Kubernetes, it requires a service object.
The kubectl CLI is commonly used to expose applications by creating services. In order to expose an application — for example, deployments in most cases — kubectl's imperative commands require the user to explicitly specify the name of the deployment that they wish to expose, along with port numbers that they wish to expose on the deployment object.
To expose port 80 for your deployment, use the following syntax:
kubectl expose deployment --type= --port= --target-port= --name=
An example of the above syntax:
kubectl expose deployment nginx --type=ClusterIP --port=8080 --target-port=80 --name=nginx-clusterip-svc
Run
A pod is the smallest unit of a containerized application that can be managed by Kubernetes. You usually create pods using deployment objects, but there are many use cases where you have to create a pod independently. In fact, creating a Kubernetes pod independently is a great way to get started with managing your own containerized applications. By understanding how to create and manage pods on your own, you'll be well on your way to becoming a Kubernetes expert.
Kubectl's CLI is commonly used to create pods. To create a pod, kubectl's imperative commands require the user to explicitly specify the image that would be running in the pod.
The syntax for running pod running ‘ubuntu’ is as follows:
kubectl run <pod-name> --image=<image>
An example of the above syntax:
kubectl run ubuntu --image=ubuntu
Apart from the commands discussed above, there are some important parameters that can help you work faster with Imperative commands and Kubernetes in general. Let’s take a look at them.
Explain
Kubernetes has a lot of commands, which makes it impossible for the user to memorize everything. Though everything is available on the documentation, going over the documentation, again and again, is not efficient and could seriously slow you down. Kubectl gives an elegant solution to this in the form of ‘explain’. You can think of ‘explain’ as mini documentation that is accessible through the CLI.
‘Explain’ provides a list of parameters that a command supports, along with the use case of the commands with examples. Most importantly, it can provide you with a full-fledged YAML containing all the parameters that the object supports. Let’s take a close look.
Examples to see parameters and description of a command:
kubectl explain pods
kubectl explain pods.spec.containers
Examples to see a full-fledged YAML of a command:
kubectl explain pod --recursive
Imperative to Declarative
If you're working with declarative commands, you'll need a YAML manifest. However, if you use imperative commands, you can generate these files without actually creating the objects. For example, if you use the `—dry-run=client -o yaml" flag with an imperative command like kubectl, you'll get a YAML version of the operation (like creating objects) that you're trying to do without actually applying the changes on the cluster. This can save you time and effort that would be spent writing YAML files from scratch. Plus, by storing the generated manifests in code repositories, you can use them declaratively as needed.
Example:
kubectl create deployment squadcast --replicas=3 --image=ubuntu --dry-run=client -o yaml > squadcast-deployment.yaml
Conclusion
Learning any new technology takes time and effort, but with Kubernetes, there are many ways you can make the learning process easier. First, get familiar with kubectl and its documentation. Second, learn some of the imperative commands, which will help you remember key commands and perform operations more quickly.
In this article, we've covered everything you need to know about imperative commands — what they are, when to use them and how to use them correctly. We've provided multiple examples of advanced imperative commands in action, so you can start using them for your own experiments and projects. Thanks for reading!
Squadcast is an incident management tool that’s purpose-built for SRE. Get rid of unwanted alerts, receive relevant notifications and integrate with popular ChatOps tools. Work in collaboration using virtual incident war rooms and use automation to eliminate toil.