Kubernetes, also known as K8S, is a popular container orchestration tool for managing and scaling containerized infrastructure.

kubectl is the common CLI tool that we use to query and manage a Kubernetes cluster. kubectl uses the API interface of Kubernetes to view, control, and manage the cluster. It is supported across different platforms and can be easily set up to manage a cluster.

In this article, we’ll be covering some common kubectl commands that help in day to day administration of Kubernetes.

Getting kubectl

kubectl is already installed as part of the Kubernetes cluster setup. In case you’re managing a cluster from a remote system, you can easily install it to work with any cluster setup.

On a Linux system, you can use the below command to get the latest version of kubectl:

$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

Make sure to place the downloaded binary to a fixed location, add the location to your PATH variable and make it executable with chmod +x command.

On a Windows box, you can download the latest available kubectl version by first getting the latest stable release version from https://dl.k8s.io/release/stable.txt

And then download it by replacing {version} with the latest release using curl as:

$ curl -LO https://dl.k8s.io/release/{version}/bin/windows/amd64/kubectl.exe

For v 1.20.0, here’s the curl command:

$ curl -LO https://dl.k8s.io/release/v1.20.0/bin/windows/amd64/kubectl.exe

If you don’t have curl on your system, you can also download the kubectl executable using your browser like any other download.

For other supported methods and platforms, you can find the official guide to get kubectl here.

Verify kubectl Setup

To check your kubectl setup, you can run the version command as:

$ kubectl version --client

The general syntax for kubectl usage is:

$ kubectl [command] [TYPE] [NAME] [flags]

Set Context and Configuration

Before using kubectl commands on a Kubernetes cluster, we have to set the configuration and context first. It can be done with kubectl command itself.

To view kubectl current configuration, use:

$ kubectl config view

To list all available contexts:

$ kubectl config get-contexts

To get current context for kubectl:

$ kubectl config current-context

We can change the context in use by using:

$ kubectl config use-context [cluster-name]

To authorize a new user to be added in kubeconf:

$ kubectl config set-credentials NAME [--client-certificate=path/to/certfile] [--client-key=path/to/keyfile] [--token=bearer_token] [--username=basic_user] [--password=basic_password]

For example, to set only the “client-key” field on the “cluster-admin” without touching other values, we can use:

$ kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key

Or, as another example, to set basic auth for, say “cluster-admin” entry, you can specify username and password as:

$ kubectl config set-credentials cluster-admin --username=[username] --password=[password]

If you want to embed client certificate data in the “cluster-admin” entry, syntax changes to:

$ kubectl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true

If you want kubectl to use a specific namespace and save it for all subsequent kubectl commands in that context:

$ kubectl config set-context --current --namespace=[NAMESPACE]

Creating Objects

kubectl is used to deploy different objects supported in a Kubernetes cluster. Its manifest can be defined in a YAML or JSON file with extension .yaml or .yml and .json respectively.

Using the given manifest file, we can create defined resources using the following command:

$ kubectl apply -f [manifest.yaml]

Or to specify multiple YAML files, use:

$ kubectl apply -f [manifest1.yaml] [manifest2.yaml]

To create a resource(s) in all manifest files present in a directory:

$ kubectl apply -f ./dir

Or to create resources from a URL:

$ kubectl apply -f [URL]

Or directly from image name from the repository as:

$ kubectl create deployment [deployment-name] --image=[image-name]

For example, to deploy a single instance of Nginx web server:

$ kubectl create deployment nginx --image=nginx

Finally, to deploy resources directly by typing the YAML contents in CLI without referring to an actual saved manifest file, try something like:

# Create multiple YAML objects from stdin
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000000"
---
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep-less
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000"
EOF

View/Find Resources

kubectl provides get command to list down the deployed resources, get their details, and find out more about them.

To list all services in the default namespace, use:

$ kubectl get services

Similarly, for listing pods in all the namespaces, the syntax will be:

$ kubectl get pods --all-namespaces

If we need to list down more details of deployed pods, use -o wide flag as:

$ kubectl get pods -o wide

Syntax to get deployment details goes like this:

$ kubectl get deployment [deployment-name]

To get a pod’s YAML content, we can use -o yaml flag like:

$ kubectl get pod [pod-name] -o yaml

Often we need to get details on Kubernetes resources. kubectl’s describe command helps in getting those details.

We can get more details about a node as:

$ kubectl describe nodes [node-name]

Or similarly for pods as:

$ kubectl describe pods [pod-name]

kubectl allows sorting the output based on a particular field. To list services sorted by service name, use:

$ kubectl get services --sort-by=.metadata.name

Or to get all running pods in the namespace, we can try:

$ kubectl get pods --field-selector=status.phase=Running

To fetch just the external IPs of all nodes, if assigned, we can use -o jsonpath flag with the below syntax:

$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

To fetch labels attached to a resource, say pods, try:

$ kubectl get pods --show-labels

For getting a list of events but which is sorted by timestamp, we can use -sort-by flag as:

$ kubectl get events --sort-by=.metadata.creationTimestamp

If we want to compares the current state of the cluster against the state that the cluster would be in if the manifest was applied, we use diff command as:

$ kubectl diff -f ./manifest-file.yaml

Modifying Resources

Deployed resources would often be modified for any configuration changes.

To perform a rolling update of, say “www” containers of, say “frontend” deployment by updating their image, we can use:

$ kubectl set image deployment/frontend www=image:v2

We can check the history of deployments including revision as:

$ kubectl rollout history deployment/frontend

Or to rollback to a previous deployment, use:

$ kubectl rollout undo deployment/frontend

We can also rollback to a specific revision by specifying --to-revision flag as:

$ kubectl rollout undo deployment/frontend --to-revision=2

And to check rolling update status, we use:

$ kubectl rollout status -w deployment/frontend

For rolling restart of, say “frontend” deployment, use:

$ kubectl rollout restart deployment/frontend

We can specify a JSON manifest to replace a pod by passing it to standard input as shown below:

$ cat pod.json | kubectl replace -f -

It may happen that you need to force replace, delete, and then re-create a resource (NOTE: this will also cause a service outage) which can be done as:

$ kubectl replace --force -f [manifest-file]

Labeling a resource (which supports labels) is easy and can be done using:

$ kubectl label pods [pod-name] new-label=[label]

Similarly, annotation can be added to a resource using:

$ kubectl annotate pods [pod-name] icon-url=[url]

Autoscaling a deployment is possible with:

$ kubectl autoscale deployment [dep-name] --min=[min-val] --max=[max-val]

Here, dep-name is the name of the deployment to be autoscaled and min-val and max-val denotes the minimum and maximum value to be used for auto-scaling.

Editing resources

It is possible to edit an API resource in your preferred editor with edit command.

$ kubectl edit [api-resource-name]

Or to use your own alternative editor, specify KUBE_EDITOR like:

KUBE_EDITOR="nano" kubectl edit [api-resource-name]

Scaling resources

Scaling resource is one of the features supported by Kubernetes and kubectl makes it easy to do so.

For scaling a replica set named, say foo to 3, we use:

$ kubectl scale --replicas=3 rs/foo

Or instead, we can refer to a manifest YAML file to specify the resource to be scaled as:

$ kubectl scale --replicas=3 -f foo.yaml

We can additionally perform scaling based on the current state of deployment as:

$ kubectl scale --current-replicas=2 --replicas=3 deployment/nginx

Deleting resources

Created resources will eventually need some modifications or deletion. With kubectl, we can delete existing resources in several ways.

To delete a pod using the specification from the JSON file, we use:

$ kubectl delete -f ./pod.json

We can delete pods and services with the same names pod-name and service-name as:

$ kubectl delete pod,service [pod-name] [service-name]

If the resources are labeled and we need to delete resources with a specific label, say label-name, we can use:

$ kubectl delete pods,services -l name=[label-name]

To delete every pods and service contained in a namespace, use:

$ kubectl -n [namespace] delete pod,svc --all

Interacting with running Pods

We can use kubectl to get details about running pods that helps administer a Kubernetes cluster.

One of the common commands is to get logs of a pod which can be done as:

$ kubectl logs [pod-name]

Or to dump pod logs with a specific label:

$ kubectl logs -l name=[label-name]

Or to get logs for a specific container as:

$ kubectl logs -l name=[label-name] -c [container-name]

We can also stream logs as we do with Linux tail -f command with kubectl’s -f flag as well:

$ kubectl logs -f [pod-name]

Running a pod interactively can be done with kubectl as:

$ kubectl run -i --tty busybox --image=busybox -- sh

Or to run a pod in specific namespace use:

$ kubectl run nginx --image=nginx -n [namespace]

You can attach it to a running container with attach command:

$ kubectl attach [pod-name] -i

Port forwarding can be done for a pod at runtime with the below command:

$ kubectl port-forward [pod-name] [local-machine-port]:[pod-port]

To execute something directly in a pod login and get the output use:

$ kubectl exec [pod-name] -- [command]

The above command works if the pod contains a single container. For multi-container pods, use:

$ kubectl exec [pod-name] -c [container-name] -- [command]

To show performance metrics for a given pod and its containers, we can use:

$ kubectl top pod [pod-name] --containers

Or to sort it by a measure say CPU or memory, we can achieve it using:

$ kubectl top pod [pod-name] --sort-by=cpu

Interacting with Nodes and cluster

kubectl can interact with the nodes and cluster. Here are some of the commands kubectl uses for the same.

For marking a node as un-schedulable, use:

$ kubectl cordon [node-name]

To drain a node as part of the preparation for maintenance:

$ kubectl drain [node-name]

To mark the node back as schedulable, use:

$ kubectl uncordon [node-name]

For getting performance metrics related to a node, we can use:

$ kubectl top node [node-name]

To get details about the current cluster:

$ kubectl cluster-info

We can additionally dump the cluster state to standard output using:

$ kubectl cluster-info dump

Or to dump to a file use:

$ kubectl cluster-info dump --output-directory=/path/to/cluster-state

Conclusion

Kubernetes is the buzzword in the industry and knowing how to manage it effectively will always boost your career. kubectl is the primary interface to interact with a Kubernetes cluster and this article demonstrated how powerful this tool is in the hands of an experienced user.

Still, we are able to cover only a summarised view of what more can kubectl possibly do. To explore it in further detail and check out what all it supports, refer to its official documentation here.