Introduction
In this blog, you will find a compilation of kubectl commands to manage and interact with Kubernetes clusters that I have found useful. For each command, you will be giving the syntax to use the command as well as a short description of the command.
Commands
Note
In the commands that follow, you will find, in bold, placeholders similar to <pod-name> or <name-space>, which will require to be replaced with the appropriate information.
cluster
Retrieve cluster details.
$ kubectl cluster-info
To get the cluster ID, run the command below.
$ kubectl get ns kube-system -o jsonpath='{.metadata.uid}{"\n"}'
config
Display the configuration of the cluster.
$ kubectl config view
Display all users.
$ kubectl config view -o jsonpath='{range .users[*]}{.name}{"\n"}{end}'
Retrieve one user details.
$ kubectl config view -o jsonpath='{.users[?(@.name == "<user-name>")].user}{"\n"}'
containers
List all containers inside a pod.
$ kubectl get pod <pod-name> -n <name-space> -o jsonpath='{.spec.containers[*].name}{"\n"}'
exec
Note
The double dash (--
) in the command signals the end of command options for kubectl. Everything after the double dash is the command that should be executed inside the pod; the double dash is required.
The command takes the following options:-i
or --stdin
: Keep stdin open even if not attached.-t
or --tty
: Allocate a pseudo-TTY.-c
or --container
: Specify the container name (useful for pods hosting multiple containers).-n
or --namespace
: Specify the namespace of the pod.
To open an interactive shell (e.g.; bash
) in a pod hosting one container, execute the command below.
$ kubectl exec -it <pod-name> -n <name-space> -- /bin/bash
Since pods are capable of hosting multiple containers, you can specify a specific container by using the -c flag.
$ kubectl exec -it <pod-name> -c <container-name> -n <name-space> -- /bin/bash
To execute a single command without entering an interactive shell, use.
$ kubectl exec <pod-name> -n <name-space> -- env
labels
To list all labels on a pod, you use the --show-labels
option. This will display the pod’s name, status, and other information, including a “LABELS” column listing the labels applied to the pod.
$ kubectl get pod <pod-name> -n <name-space> --show-labels
To list all labels on all resources across all namespaces, you use the --show-labels
and --all-namespaces
(or its shorthand -A) options. The command kubectl get all does not, despite its name, show all resources in the cluster.
$ kubectl get all -A --show-labels
To list all labels on all nodes, use.
$ kubectl get nodes --show-labels
logs
Retrieve the logs for a pod under a specific namespace.
$ kubectl logs <pod-name> -n <name-space>
Retrieve the logs for a pod that was previously running under a specific namespace.
$ kubectl logs <pod-name> -n <name-space> --previous
Retrieve the logs for a specific container running in a pod under a specific namespace. If the pod has only one container, the container name is optional.
$ kubectl logs <pod-name> -c <container-name> -n <name-space>
To stream the logs of a container or pod in real-time, you will need to use --follow
(or its shorthand -f) option. The --follow
option causes kubectl logs to keep the connection open and continuously display new log entries as they are generated by the container. To stop the continuous log streaming, just press Ctrl+C in your terminal.
$ kubectl logs <pod-name> -n <name-space> -f
or to check the logs of a specific container inside a pod.
$ kubectl logs <pod-name> -c <container-name> -n <name-space> -f
By default, the kubectl logs command retrieves all of the available logs for a specific pod or container. However, you can use the --tail
option to fetch only the most recent logs from the given pod or container.
$ kubectl logs <pod-name> -c <container-name> -n <name-space> --tail=<number-of-lines>
If you need to monitor the logs of your pod or container continuously, you can add the -f option.
$ kubectl logs <pod-name> -n <name-space> --tail=<number-of-lines> -f
To retrieve the logs of all containers running in a pod, use.
$ kubectl logs <pod-name> -n <name-space> –all-containers=true
By using label selectors (option --selector
or its shorthand -l), you can aggregate logs from a group of pods, which is useful for getting an overview of a service or application; i.e., instead of specifying individual pod names, you can filter pods by their labels.
$ kubectl logs --selector <label-key>=<label-value> -n <name-space>
or if multiple labels are required
$ kubectl logs -l <label1-key>=<label1-value>,<label2-key>!=<label2-key> -n <name-space>
When streaming logs from multiple pods selected by a label, the --prefix=true
option adds the pod name as a prefix to each log line thereby identifying which pod produced which log entry.
$ kubectl logs -l <label-key>=<label-value> --prefix=true -n <name-space> -f
Labels let you target groups of pods easily without specifying each pod name. To retrieve the logs from all pods within a given namespace and from all containers within the pods, use.
$ kubectl logs -l <label-key>=<label-value> -n <namespace> --all-containers=true
When you use a selector, kubectl logs will retrieve the last ten (10) lines of logs, but it defaults to -1 without a selector. If you require this behavior, execute.
$ kubectl logs -l <label-key>=<label-value> -n <namespace> --tail=-1
To fetch logs from all pods in a deployment, you use the command below, which fetches logs from every pod that is managed by the deployment.
$ kubectl logs deployment/<deployment-name> -n <namespace> --all-pods=true
To fetch logs from all pods manage by a StatefulSet, use.
$ kubectl logs statefulset/<stateful-set-name> -n <namespace>
When using kubectl logs to retrieve logs from a pod or container, the --since
and --since-time
options allow you to specify the timeframe for the logs you want to see; only one of these options can be used at a time. However, they differ in how you define that timeframe:--since
is used to retrieve logs newer than a specific duration (relative duration). Note that you can specify the duration in hours (h), minutes (m), or seconds (s).
For example:
To fetch logs from the last 1 hour, 30 minutes, and 20 seconds: 1h30m20s.--since-time
is used to retrieve logs generated after a specific point in time (absolute timestamp). It requires a timestamp in the format YYYY-MM-DDTHH:MM:SS.fffffffffZ (RFC3339).
Where:
YYYY represents the year
MM represents the month
DD represents the day
T is a separator indicating the start of the time portion
HH represents the hour
MM represents the minute
fffffffff represents the second
Z signifies Coordinated Universal Time (UTC)
For example:
Starting from midnight on 14th May 2023: 2023-05-14T00:00:00Z
Starting 10:00:00 AM on 20th September 2023: 2023-09-20T10:00:00Z
Please note that the log rotation policy configured in your Kubernetes cluster might affect how far back you can retrieve logs with either flag. If logs are rotated frequently, older logs may not be available.
If you need to know when each log line was generated, the --timestamps=true
option prefixes each log line with a timestamp.
$ kubectl logs <pod-name> -n <name-space> --timestamps=true
In addition to append timestamps, you can filter log outputs that start from a specified duration in the past. It is particularly useful for investigating issues that occurred within a known period.
$ kubectl logs <pod-name> -n <name-space> --since=<duration>
To retrieve log outputs since a specified timestamp, use.
$ kubectl logs <pod-name> -n <name-space> --since-time=<timestamp>
namespace
List all the namespaces within a cluster.
$ kubectl get namespaces --all-namespaces
or
$ kubectl get namespaces
Note
If the STATUS of a namespace is displaying Terminating, you will need to follow the steps below to delete the namespace.
- Get the name of the namespace that is stuck in the Terminating state.
$ kubectl get namespaces
- Select the namespace that is stuck in the Terminating state and save the contents of the namespace in a JSON file.
$ kubectl get ns <terminating-namespace> -o json > ns.json
- Edit the JSON file by removing the kubernetes value from the finalizers field. Save the file.
$ vi ns.json
...
"spec": {
"finalizers": [
"kubernetes"
]
},
...
- After removing the kubernetes value from the finalizers field, the contents of the JSON file should resemble the following listing.
$ cat ns.json
...
"spec": {
"finalizers": [
]
},
...
- To apply the change, run the command below.
$ kubectl replace --raw "/api/v1/namespaces/<terminating-namespace>/finalize" -f ./ns.json
- Verify that the terminating namespace has been removed.
$ kubectl get namespaces
node
Confirm what platform is running on the cluster.
$ kubectl describe node | grep -i "kubernetes.io/arch"
To retrieve nodes information.
$ kubectl get nodes
To retrieve number of nodes, operating system, and container runtime.
$ kubectl get nodes -o wide
pods
Display what node a pod is scheduled.
$ kubectl get pods -o wide -n <name-space>
Retrieve a list of host IP addresses with the additional phase field indicating if the pod is running or not.
$ kubectl get pods -o jsonpath='{range .items[*]}{.status.hostIP}{"\t"}{.status.phase}{"\n"}{end}' -n <name-space>
Retrieve pods across all namespaces.
$ kubectl get pods --all-namespaces
Retrieve pods under a specific namespace.
$ kubectl get pods -n <name-space>
Display details of a specific pod under a specific namespace.
$ kubectl describe pod <pod-name> -n <name-space>
Retrieve all containers in a pod with all of their ports.
$ kubectl get pod <pod-name> -o jsonpath='{range .spec.containers[*]}{.name}{"\t\t"}{range .ports[*]}{.name}{"="}{.containerPort}{"\t\t"}{end}{"\n"}{end}' -n <name-space>
Delete a pod under a specific namespace.
$ kubectl delete pod <pod-name> -n <name-space>
Delete all pods without specifying their names.
$ kubectl delete pods --all -n <name-space>
port-forward
Forward a local port to a port on a K8s resource. This command establishes a secure tunnel between your local machine and the resource allowing you to access the resource as if it were running locally. This is particularly useful for troubleshooting and debugging resources that are not exposed externally.
$ kubectl port-forward <resource-type>/<resource-name> <local-port>:<resource-port> -n <namespace>
Where:
resource-type specifies the type of K8s resource. It defaults to pod, if omitted.
resource-name specifies the name of the K8s resource.
local-port is the port number on your local machine; i.e, this is the port that you’ll use to access the resource from your local machine.
resource-port is the port number for the K8s resource; i.e., the traffic sent to the local port on your machine will be forwarded to this port of the resource.
Note
kubectl port-forward does not return. To continue, you will need to open another terminal. The port-forwarding session ends when you manually close it by pressing Ctrl+C, which sends an interrupt signal to the process, in the terminal where the command was initiated, when the resource being forwarded terminates, or when a timeout is reached due to inactivity.
To run this command in the background, you can add the & operator at the end of the command.
$ kubectl port-forward <resource-type>/<resource-name> <local-port>:<resource-port> -n <namespace> &
To stop the background process, you will need to find its process ID by executing this command.
$ ps -aux | grep -i "kubectl port-forward"
Where:
ps -aux displays information about all active processes from all users.
grep -i “kubectl port-forward” filters the results to only show lines containing the kubectl port-forward expression; the search is case-insensitive (-i).
Locate the relevant line, then kill the process by running the command below.
$ kill <pid>
Where:
pid is the process ID of the kubectl port-forward command.
If you don’t need a specific local port, you can omit the local port; kubectl automatically choose and allocate a local port.
$ kubectl port-forward <resource-type>/<resource-name> :<resource-port> -n <namespace>
To get a list of all forwarded ports active, you can use the following command.
$ ps -ef | grep -i "port-forward"
Where:
ps -ef lists all processes running on the system with detailed information, including the process ID, command line arguments, and user.
grep -i “port-forward” filters the results to only show lines containing the port-forward expression; the search is case-insensitive (-i).
resources
Retrieve built-in resource types (pods, services, daemon sets, deployments, replica sets, jobs, cronjobs, and stateful sets) under a specific namespace.
$ kubectl get all -n <name-space>
Note
The kubectl delete command might not be successful initially if you use finalizers to prevent accidental deletion. Finalizers are keys on resources that signal pre-delete operations. Finalizers control the garbage collection on resources, and they’re designed to alert controllers about what cleanup operations to do before they remove a resource.
If you try to delete a resource that has a finalizer on it, the resource remains in finalization until the controller removes the finalizer keys, or the finalizers are removed by using kubectl. After the finalizer list is emptied, Kubernetes can reclaim the resource and put it into a queue to be deleted from the registry.
See Using Finalizers to Control Deletion for more information.
Remove a resource in the Terminating state.
To remove a finalizer from a resource, you typically update the resource’s metadata to remove the finalizer entry. This action signals Kubernetes that the cleanup tasks are complete, allowing the resource to be fully deleted.
To ensure the resource has one or more finalizers attach, you can use kubectl get or kubectl describe. If finalizers are attached, you remove them by executing the command below.
$ kubectl patch <resource> <resource-name> -p '{"metadata":{"finalizers":null}}'
version
Display the Kubernetes version running on the client and server.
$ kubectl version
volumes
Note
PersistentVolume resources are cluster-scoped and thus cannot be created in a specific namespace. On the other hand, PersistentVolumeClaims can only be created in a specific namespace, and they can then only be used by pods in the same namespace.
For more in-depth information, see Persistent Volumes
List all PersistentVolumes.
$ kubectl get pv
List all PersistentVolumeClaims.
$ kubectl get pvc -n <name-space>
List storage classes.
$ kubectl get storageclass
or
$ kubectl get sc
Display more information about the given storage class.
$ kubectl get sc <storage-class-name> -o yaml
Conclusion
Since kubectl is the official command-line interface (CLI) to interact with a Kubernetes cluster, familiarizing yourself with it is a must. By mastering this tool, you can effectively manage, monitor, and interact with your Kubernetes cluster. And although these are but a few examples of the many commands and options available in kubectl, it’s evident that the power and flexibility of Kubernetes as a container orchestration tool lie in its comprehensive CLI.