• Get application security done the right way! Detect, Protect, Monitor, Accelerate, and more…
  • 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 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.