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.