Skip to main content

The guide to kubectl I never had.

kubectl thumbnail

What kind of engineer are you? πŸ€” Can somebody guess by just looking at you? More than likely not.

Would that somebody be able to tell by looking at your keyboard instead? Might be a bit easier now. ⌨️

You know you are dealing with a Kubernetes engineer when the β€œkβ€œ key on their keyboard has seen better days. At the Glasskube office, you will find spare β€œkβ€œ keys all over the place, just in case πŸ˜„

I’m joking of course. I’m not really sure about what a faded keyboard says about its owner. What I do know for sure is how important kubectl is to anybody who wants to be a proficient Kubernetes administrator.

kubectl is the CLI tool used to communicate to the Kubernetes API it can seem simple at first but can quickly get complicated. So in this blog post, I aim to write the guide I wish I had when I started. Focusing first on command syntax and useful commands, before moving on to the vibrant ecosystem of plugins and tools built to expand the functionalities of kubectl and Kubernetes. Sharing tips and tricks along the way as well as a helpful kubecltl cheatsheet at the end. πŸ“‹

Let’s get to it. ☸️

Disclaimer πŸ›‘β€‹

This isn’t an article about Kubernetes. K8s is an incredibly vast technology, encompassing numerous concepts, such as various types of Kubernetes objects and their interactions. For this discussion, I'll assume you're familiar with these concepts. Instead, I'll focus specifically on kubectl, its usage, and the tools built around it.

Just before we begin​

If you are a fan of supporting Open Source projects working to make Kubernetes package management better for everyone then please consider supporting Glasskube, by giving us a Star on GitHub πŸ™

Screenshot 2024-04-26 at 10 54 54

Installation​

To install kubectl, you have a few different options depending on your operating system. Here's how to install it on some common platforms:

Linux (Ubuntu/Debian)​

sudo apt-get update && sudo apt-get install -y kubectl

MacOS using Homebrew​

brew install kubectl

Windows using Chocolatey​

choco install kubernetes-cli

After installation, you can verify if kubectl has been installed correctly by running:

kubectl version --client

kubectl commands:​

kubectl is a Command Line Interface (CLI) tool used to communicate with the Kubernetes API. There are many commands, too many to remember.

k8s hard gif

Don’t worry though it’s not as daunting as some might want you to think.

We will explore ways to quickly access command references, k8s-object-specific commands, helpful aliases, and command completion. But first, how are command strings built?

The syntax​

English and Chinese are subject-verb-object (SVO) languages.

Hindi and Korean are subject-object-verb (SOV) languages.

If kubectl were a language, it would be a kubectl + verb + object/[name optional] + flag (kvof) language πŸ˜„

kubectl syntax

Also similar to languages, the best way to learn and absorb grammar is by using it in context and not memorizing long verb and object lists.

ℹ️ If you are stuck and want to quickly reference the existing Kubernetes objects in any Kubernetes version run kubectl api-resources.

Commands are built by choosing that action [verb] you want to apply to the desired Kubernetes resource [object] usually followed by the name of the resource additionally you have a large array of filters [flags] that can be applied to the command which will determine the final scope and output.

kubectl command building

Let’s look at a simple example of command building using the commonly used get verb to retrieve all resources in the glasskube-system namespace, and the output is in yaml format:

kubectl get all --namespace glasskube-system -o yaml

ℹ️ If you come across a Kubernetes resource that you haven’t heard of before or need a refresher use kubectl explain [resource-name] to get an in-terminal description and usage instructions.

Working imperatively​

When working in Kubernetes environments your tasks are many, anything from deploying new apps, troubleshooting faulty resources, inspecting usage, and much more. Later on, we will explore how useful declarative ways of working are more appropriate for defining and deploying workloads, but for everything else we have our arsenal of useful imperative Kubernetes commands at the ready.

Simple commands to get us started are:

# Create a new deployment named "nginx-deployment" with the nginx image
kubectl run nginx-deployment --image=nginx

# Delete a pod named "nginx-deployment" in the default namespace
kubectl delete pod nginx-deployment

To take imperative commands to the next step know that you can modify resources by using the TUI editor: By running kubectl edit -n [namespace] [resource-name] a text editor like the one below will open. Make you edits and close the editor just like in vim by running ESC + :q!.

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Pod
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
creationTimestamp: "2024-04-22T17:07:39Z"
generateName: glasskube-controller-manager-556ff6fccf-
labels:
control-plane: controller-manager
pod-template-hash: 556ff6fccf
name: glasskube-controller-manager-556ff6fccf-4qlxz
namespace: glasskube-system
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: glasskube-controller-manager-556ff6fccf
uid: 430e90e9-32f3-45f6-92dc-4bae26ae1654
"/var/folders/2q/wjmbwg1n5vn8v7vlw17nsz0h0000gn/T/kubectl-edit-1306753911.yaml" 209L, 5898B

Most commands are applicable to all sorts of Kubernetes objects. Insofar as it is useful further down we will touch on specific commands that are useful for certain Kubernetes resources. Before that though, it’s worth learning about some useful flags that can be applied to many different objects.

Useful flags:​

--env:

The --env flag allows you to specify environment variables for the container being created.

kubectl run nginx-deployment --image=nginx --env="ENV_VARIABLE=value"

--template: This flag allows you to specify a Go template for the output format of your kubectl command. It's handy when you want to customize the output structure, filtering, or presentation.

kubectl get pods --template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'

--dry-run=[client/server]: Massively useful when you want render a manifest for an object you don't remember how to write from scratch or have a template at hand. The --dry-run flag prints the object manifest that would be sent without sending it. Use the server option to see the server side request that would be generated.

kubectl create secret generic github-api-token --from-literal token=$GITHUB_TOKEN --dry-run=client -o yaml

Concatenating the command with other tools can be very useful too. Taking the example above, you can pipe the output of the generated manifest and pass in into a third party secret manager like Sealed-secrets to create a kubeseal secret manifest.

kubectl create secret generic github-api-token --from-literal token=$GITHUB_TOKEN --dry-run=client -o yaml | kubeseal --format yaml > api-token-secret.sealed.yaml

--field-selector: With this flag, you can filter resources based on specific fields. For instance, you can filter pods based on their status or labels.

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

--field-selector type=[Normal/Warning]: This is a specific use of the --field-selector flag, where you filter events based on their type, either Normal or Warning.

**kubectl events -n [resource-namespace] --for=[resource-kind]/[resource-name]: ** This command fetches events related to a specific resource in the specified namespace. It continuously watches for new events related to the given resource.

kubectl events -n my-namespace --for=deployment/my-deployment

Old School vs. New School watching flags:​

watch vs. -w:

watch: This is a traditional Unix command used to execute a specified command repeatedly at regular intervals, displaying its output in the terminal. Unlike the -w flag in kubectl, the watch command does not automatically update the terminal output when changes occur.

-w: This is a modern flag in kubectl that enables continuous watching for changes to resources.

Working with Pods​

Pods are the smallest abstraction inside the Kubernetes ecosystem, they are the logical units that house your containers. Pods consume resources and can be executed into and produce logs. Here are some commands that will help you manage pods.

# Show resource usage of a pod
kubectl top pod -n [namespace] [pod-name]

# Run a command inside a new pod in the cluster
kubectl run -it ubuntu --image ubuntu --rm -- bash

# Show resource labels as columns
# e.g. kubectl get pods -n [namespace] -L vault-active -L vault-sealed
kubectl get pods -n [namespace] -L vault-active -L vault-sealed

# Execute a command inside a pod
kubectl exec -it [pod-name] -n [namespace] --

# Port forward to a pod
kubectl port-forward [pod-name] [local-port]:[remote-port] -n [namespace]

# Show container logs
kubectl logs -n [namespace] [pod-name]
kubectl logs -n [namespace] /deployment/[deployment-name] # Use -f flag for continuous streaming

# Run a command inside an existing container
kubectl exec -it -n [namespace] [pod-name] -- [command...]

Working with nodes​

Nodes are the underlying instances that provide computational power and storage on top of which your Kubernetes cluster runs.

# Show node resource utilization
kubectl top node [node-name] # Node name is optional; without shows table of all nodes

# Get node information
kubectl get node

Working with Deployments, DaemonSets and StatefulSets​

Deployments, DaemonSets, and StatefulSets are higher-level abstractions in Kubernetes that manage the deployment and scaling of application workloads.

# Restart a workload (e.g. deployment, stateful set, daemon set)
kubectl rollout restart -n [namespace] [workload-kind]/[workload-name] # Triggers a re-creation of all pods for this workload, adhering to the workload configuration

# Check the status of a deployment rollout
kubectl rollout status deployment/[name]

# View rollout history of a deployment
kubectl rollout history deployment/[name] # View rollout history of a deployment

# Scale a deployment to the specified number of replicas
kubectl scale deployment/ --replicas=[number] # Scale a deployment to the specified number of replicas

# Watch events related to a deployment
kubectl events -n glasskube-system --for=deployment/glasskube-controller-manager

#Update Deployment Image
kubectl set image deployment/[deployment-name] [container-name]=new-image:tag

# Delete DaemonSet
kubectl delete daemonset [daemonset-name]

Working with jobs​

Jobs manage the execution of pods to perform a particular task and ensure the task is completed successfully before terminating.

# Run a CronJob manually
kubectl create job [job-name] --image=image/name

# Creates a new job from the job template specified in the cronjob
kubectl create job -n [namespace] --from=cronjob/[cron-job-name] [job-name]

Working with secrets​

Secrets are used to store sensitive information like passwords, OAuth tokens, and SSH keys securely in Kubernetes.

# Create Secret
kubectl create secret generic [secret-name] --from-literal=key1=value1 --from-file=ssh-privatekey=~/.ssh/id_rsa

# Get a value from a secret
kubectl get secrets -n [namespace] [secret-name] --template='{{ .data.[key-name] | base64decode }}'

# Get a value from a secret using jsonpath
kubectl get secrets [secret-name] -o jsonpath="{.data.key1}" | base64 --decode

ℹ️ JSONPath is a query language used to extract specific data from JSON documents. In Kubernetes, JSONPath expressions are often used with the -o jsonpath flag in kubectl commands to extract specific information from the output of those commands.

Shell completions​

As you have probably noticed, kubectl commands can get long in no time. A really nifty shell completion script can be added to your bash or zshell file to enable easy tab completions. No more memorizing. To do so in all your shell sessions, add the following to your ~/.zshrc file:

source <(kubectl completion zsh)

And restart the shell. Follow the instructions here if you are using bash:

# Install bash-completion package
sudo apt-get install -y bash-completion
# Store the output of the completion command in .bashrc
echo "source <(kubectl completion bash)" >> ~/.bashrc
# Activate the completion rules
source ~/.bashrc

kubectl autocomplete

Working declaratively​

Declarative management of Kubernetes resources involves specifying the desired state of your resources using YAML manifest files and applying those manifests to the cluster.

Create YAML files​

All Kubernetes objects are defined in YAML files, regardless if you write them yourself or not, YAML file definitions are how the Kubernetes API knows what the state of the cluster should be:

apiVersion: apps/v1
kind: Deployment
metadata:
name: glasskube-deployment
spec:
replicas: 3
selector:
matchLabels:
app: glasskube
env: prod
template:
metadata:
labels:
app: glasskube
env: prod
spec:
containers:
- name: glasskube-container
image: your-glasskube-image:latest

To create this deployment from scratch use the kubectl create command:

kubectl create -f glasskube-deployment.yaml

Apply YAML Files (client-side apply)​

Applying YAML files is the standard method for managing Kubernetes resources. You define the desired state of your resources in YAML format and apply those YAML files to the cluster.

 kubectl apply -f manifest.yaml

Server-Side Apply (SSA)​

Server-Side Apply is a newer approach to applying configuration changes to Kubernetes resources. With SSA, changes are applied directly on the server side, meaning that the Kubernetes API server takes responsibility for ensuring that the desired state is achieved.

kubectl apply --server-side -f manifest.yaml

Plugins and tooling πŸ§°β€‹

Whenever I see some back and forth around what Kubernetes is and isn’t. What use cases it’s best suited for and how should it best be thought of, the same Kelsey Hightower tweet pops into my head.

Kelsey Hightower tweet

The sentiment is widely agreed upon, as evidenced by the extensive ecosystem of Kubernetes plugins and tools designed to assist in various stages of the Kubernetes lifecycle.

Krew the Kubernetes plugin manager​

A great plugin manager to find new plugins is krew, install is here.

Command to install kubectl plugins via Krew:

kubectl krew install <PLUGIN_NAME>

Let’s explore some of the main plguing and tooling categories and highlight some of the most useful projects out there. Since there are so many worth bringing attention to, I will add a section of Honorable mentions to each section.

Content and Namespace switching πŸ”€β€‹

In Kubernetes environments, you consistently operate within 2 hierarchical contexts the clusters and the namespaces. Ensuring accurate command execution requires specifying the appropriate context to obtain the desired output. Switching cluster contexts or namespaces can involve lengthy commands to remember, which is where tools like Kubectl and Kubens come in.

Kubectx and Kubens​

Easily see the available clusters and namespaces and swith between them effortlessly. Installation instructions here.

Kubectx screenshare

Honorable mentions:

  • kubectl-cf: A faster way to switch between kubeconfig files (not contexts).

Visibility πŸ”­β€‹

Kubernetes clusters are complex systems, with many moving parts that depend on each other so that your apps run. To have clear visibility into what is happening at all times is crucial.

k9s​

K9s is a handy and low-weight interactive Kubernetes dashboard that runs right in the terminal. As well as visualizing your k8s resources, you can also easily execute into pods, edit manifest, and manage your workloads all in one place. It is probably one of my favorite tools for Kubernetes management

Install is here.

k9s-gif

kubectl tree​

A kubectl plugin to explore ownership relationships between Kubernetes objects through ownersReferences on the objects.

kubectl tree Install:

kubectl krew install tree
kubectl tree --help

kubecolor​

KubeColor is used to add colors to your kubectl output.

Kubecolor Installations instructions here.

Package management πŸ“¦β€‹

Cluster package management with conventional package management tools can be a pain in the neck, and updating packages is a hassle. Configuration is clunky and applying your desired package stack declaratively has been still out of reach, until now.

Glasskube:​

With Glasskube all the pain points found in conventional package managers like helm are solved to ensure you have time to manage your workloads and not have to worry about managing your k8s package stack.

Networking πŸŒβ€‹

Kubectl-Cilium:​

kubectl-Cilium is a plugin that interacts with Cilum which is an eBPF-based, cloud-native solution for providing, securing, and observing network connectivity between workloads.

Cilium

Install:

kubectl krew install cilium

cert-manager:​

cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, simplifying obtaining, renewing, and using those certificates.

cert-manager

Installation instructions here.

Honorable mentions:

Ksniff: A kubectl plugin that utilizes tcpdump and Wireshark to start a remote capture on any pod in your Kubernetes cluster.

RBAC πŸ«·β€‹

Kubelogin​

Kubelogin is a plugin for Kubernetes OpenID Connect (OIDC) authentication, also known as kubectl oidc-login.

Installation instructions here.

Kube-policy-advisor:​

Kube-policy-advisor makes it easier to create K8s Pod Security Policies (PSPs) or OPA Policy from either a live K8s environment or from a single .yaml file containing a pod specification (Deployment, DaemonSet, Pod, etc). Install:

kubectl krew install advise-policy

Honorable mentions:

  • kubectl-who-can: Shows which subjects have RBAC permissions to VERB [TYPE | TYPE/NAME | NONRESOURCEURL] in Kubernetes.

  • rakkess: Review Access - kubectl plugin to show an access matrix for server resources

  • kubectl-rolesum: Summarize RBAC roles for the specified subject (ServiceAccount, User and Group).

Linting πŸ“‹β€‹

Kubectl-neat:​

Kubectl-neat removes clutter from Kubernetes manifests to make them more readable. It primarily looks for two types of things to ignore: default values inserted by Kubernetes' object model and common mutating controllers. Install:

kubectl krew install neat

KubeLinter:​

KubeLinter analyzes Kubernetes YAML files and Helm charts, and checks them against a variety of best practices, with a focus on production readiness and security.

Installation instructions https://github.com/stackrox/kube-linter?tab=readme-ov-file#installing-kubelinter.

Cluster maintenance and Security πŸ›‘οΈβ€‹

KubePug​

KubePug downloads a generated data.json file containing API deprecation information for a specified release of Kubernetes, scans a running Kubernetes cluster to determine if any objects will be affected by deprecation and displays affected objects to the user. Example: You can check the status of a running cluster with the following command.

$ kubepug --k8s-version=v1.22 # Will verify the current context against v1.22 version
[...]
RESULTS:
Deprecated APIs:
PodSecurityPolicy found in policy/v1beta1
β”œβ”€ Deprecated at: 1.21
β”œβ”€ PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.Deprecated in 1.21.
-> OBJECT: restrictive namespace: default

Deleted APIs:
APIs REMOVED FROM THE CURRENT VERSION AND SHOULD BE MIGRATED IMMEDIATELY!!
Ingress found in extensions/v1beta1
β”œβ”€ Deleted at: 1.22
β”œβ”€ Replacement: networking.k8s.io/v1/Ingress
β”œβ”€ Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give servicesexternally-reachable urls, load balance traffic, terminate SSL, offer namebased virtual hosting etc.DEPRECATED - This group version of Ingress is deprecated by networking.k8s.io/v1beta1 Ingress. See the release notes for more information.
-> OBJECT: bla namespace: blabla

Install:

kubectl krew install deprecations

Kubescape:​

Kubescape is an open-source Kubernetes security platform for your clusters, CI/CD pipelines, and IDE that separates out the security signal from the scanner noise.

kubescape-screen

Installation instructions here.

Honorable mentions:

  • kubectl-watch: Another watch tool with visualization view of delta change for kubernetes resources.

Troubleshooting πŸ§‘β€πŸ”§β€‹

Inspektor-Gadget:​

Inspektor-gadget is a collection of tools (or gadgets) to debug and inspect Kubernetes resources and applications.

Inspektor Gadget tools are known as gadgets. You can deploy one, two, or many gadgets.

inspektor gadget

K8s-gpt:​

k8sgpt is a tool for scanning your Kubernetes clusters, diagnosing, and triaging issues in simple English.

k8sgpt

Installation instructions here.

Honorable mentions:

Logging πŸͺ΅β€‹

Stern:​

Stern allows you to tail multiple pods on Kubernetes and multiple containers within the pod. Each result is color-coded for quicker debugging. Install:

kubectl krew install stern

ℹ️ Some security implications of using kubectl plugins include possible Vulnerabilities, Privilege Escalation, and inadvertent Data Leakage. Make sure to only use actively maintained plugins and ideally have an active community around them.

Aliases πŸ“‡β€‹

With so many kubectl commands to remember, simplify your life by using keyboard shortcuts or aliases.

Here you will find a repo with contains a script to generate hundreds of convenient shell aliases for kubectl. The thing is that many of the aliases are long and might become hard to recall. Don’t worry though I found this very pragmatic blog post by Benoit Couetil on how to deal with the many aliases generated by the above script.

Kubectl Cheatsheet​

No guide is complete without a cheatsheet now is it?

# Basic Commands

# List API Resources
kubectl api-resources

# List Resources
kubectl get [name]

# Explain Resources
kubectl explain

# Working with Pods
# Create a new deployment named "nginx-deployment" with the nginx image
kubectl run nginx-deployment --image=nginx

# Show Resource Usage of a Pod
kubectl top pod -n [namespace] [pod-name]

# Run Command in Pod
kubectl run -it [pod-name] --image [image-name] --rm -- [command]

# Show Resource Labels
kubectl get pods -n [namespace] -L [label1] -L [label2]

# Execute Command in Pod
kubectl exec -it [pod-name] -- [command]

# Port Forwarding
kubectl port-forward [pod-name] [local-port]:[remote-port]

# Filtering Pods by Node Name
kubectl get pods --field-selector spec.nodeName=[node-name]

# Filtering Pods by Phase
kubectl get pods --field-selector status.phase=Running

# Delete a pod named "my-pod" in the default namespace
kubectl delete pod my-pod

# Working with Nodes

# Watch Nodes (Old School)
watch kubectl get nodes -o wide

# Watch Nodes (New School)
kubectl get nodes -w

# Node Resource Utilization
kubectl top node [node-name]

# Get Node Resource
kubectl describe node [node-name]

# Working with Deployments, Daemonsets, and StatefulSets

# Restart Workload
kubectl rollout restart -n [namespace] [kind]/[name]

# Rollout Status
kubectl rollout status [kind]/[name]

# Rollout History
kubectl rollout history [kind]/[name]

# Scale Deployment
kubectl scale deployment/[name] --replicas=[replica-count]

#Update Deployment Image
kubectl set image deployment/[deployment-name] [container-name]=new-image:tag

# Watch events related to a deployment
kubectl events -n glasskube-system --for=deployment/glasskube-controller-manager

# Delete DaemonSet
kubectl delete daemonset [daemonset-name]

# Working with Jobs

# Run CronJob Manually
kubectl create job -n [namespace] --from=cronjob/[cron-job-name] [job-name]

# Working with Secrets

# Get Value from Secret
kubectl get secret -n [namespace] [secret-name] -o=jsonpath='{.data.[key]}' | base64 --decode

# Create Secret
kubectl create secret generic [secret-name] --from-literal=key1=value1 --from-file=ssh-privatekey=~/.ssh/id_rsa

# Get a value from a secret
kubectl get secrets -n [namespace] [secret-name] --template='{{ .data.[key-name] | base64decode }}'

# Working with Containers

# Show Container Logs
kubectl logs -n [namespace] [pod-name]
kubectl logs -n [namespace] deployment/[deployment-name]

# Run Command in Container
kubectl exec -it -n [namespace] [pod-name] -- [command]

# Working Imperatively

# Modify Resource
kubectl edit -n [namespace] [resource-kind]/[resource-name]

# Delete Resource
kubectl delete [resource-kind]/[resource-name]

# Create Resource
kubectl create -f [resource-file]

# Working Declaratively

# Use Server-Side Apply (SSA)
kubectl apply --server-side -f [resource-file]

# Events and Logs

# Show Events for Resource
kubectl get events -n [namespace] --field-selector involvedObject.kind=[kind] --field-selector involvedObject.name=[name]

# Filtering Events by Type
kubectl get events --field-selector type=Warning

# Filtering Events by Involved Object Name
kubectl get events --field-selector involvedObject.name=[resource-name]

# Show Resource Usage
kubectl top

Additional resources:​


Screenshot 2024-04-26 at 10 54 54

If you like this sort of content and would like to see more of it, please consider supporting us by giving us a Star on GitHub πŸ™