Reference

Useful kubectl Commands

Comprehensive kubectl cheat sheet — imperative commands, resource management, JSONPath, and more.

Aliases & Setup

# alias
alias k=kubectl

# autocomplete (bash)
source <(kubectl completion bash)
complete -F __start_kubectl k

# autocomplete (zsh)
source <(kubectl completion zsh)

# set default editor
export KUBE_EDITOR=vim,nano,micro

Short resource names:

ShortFull Name
popods
deploydeployments
svcservices
nsnamespaces
nonodes
rsreplicasets
dsdaemonsets
stsstatefulsets
cmconfigmaps
saserviceaccounts
pvpersistentvolumes
pvcpersistentvolumeclaims
ingingresses
netpolnetworkpolicies
csrcertificatesigningrequests
ependpoints
evevents
scstorageclasses
pdbpoddisruptionbudgets

Dry Run & YAML Generation

Use --dry-run=client -o yaml to generate YAML without creating the resource.

# generate YAML and redirect to file
k run <pod-name> --image=<image> --dry-run=client -o yaml > pod.yaml

# generate deployment YAML
k create deployment <deployment-name> --image=<image> --dry-run=client -o yaml > deploy.yaml

# generate service YAML
k expose deployment <deployment-name> --port=<port> --dry-run=client -o yaml > svc.yaml

Creating Resources (Imperative)

kubectl run (Pods)

# basic pod
k run <pod-name> --image=<image>

# pod with labels
k run <pod-name> --image=<image> --labels="<key>=<value>,<key>=<value>"

# pod with port
k run <pod-name> --image=<image> --port=<port>

# pod with environment variables
k run <pod-name> --image=<image> --env="<key>=<value>" --env="<key>=<value>"

# pod with command and args
k run <pod-name> --image=<image> -- <command>

# pod with custom command
k run <pod-name> --image=<image> --command -- /bin/sh -c "<command>"

# pod with resource requests and limits
k run <pod-name> --image=<image> --requests="cpu=100m,memory=128Mi" --limits="cpu=200m,memory=256Mi"

# pod with service account
k run <pod-name> --image=<image> --serviceaccount=<service-account-name>

# temporary interactive pod (auto-removed on exit)
k run <pod-name> --image=<image> --rm -it -- /bin/sh

# generate YAML
k run <pod-name> --image=<image> --dry-run=client -o yaml > pod.yaml

kubectl create deployment

# basic deployment
k create deployment <deployment-name> --image=<image>

# with replicas
k create deployment <deployment-name> --image=<image> --replicas=<count>

# with port
k create deployment <deployment-name> --image=<image> --port=<port>

# multiple containers
k create deployment <deployment-name> --image=<image-1> --image=<image-2>

# generate YAML
k create deployment <deployment-name> --image=<image> --dry-run=client -o yaml > deploy.yaml

kubectl create service clusterip

# basic ClusterIP service
k create service clusterip <service-name> --tcp=<port>:<target-port>

# named port mapping
k create service clusterip <service-name> --tcp=<port>:<target-port>

# headless service (no cluster IP)
k create service clusterip <service-name> --tcp=<port>:<target-port> --clusterip="None"

# generate YAML
k create service clusterip <service-name> --tcp=<port>:<target-port> --dry-run=client -o yaml

kubectl create service nodeport

# basic NodePort service
k create service nodeport <service-name> --tcp=<port>:<target-port>

# with specific node port
k create service nodeport <service-name> --tcp=<port>:<target-port> --node-port=<node-port>

# generate YAML
k create service nodeport <service-name> --tcp=<port>:<target-port> --dry-run=client -o yaml

kubectl expose

# expose deployment as ClusterIP
k expose deployment <deployment-name> --port=<port> --target-port=<target-port> --type=ClusterIP

# expose deployment as NodePort
k expose deployment <deployment-name> --port=<port> --type=NodePort

# expose pod
k expose pod <pod-name> --port=<port> --target-port=<target-port> --name=<service-name>

# with custom service name
k expose deployment <deployment-name> --port=<port> --name=<service-name>

# generate YAML
k expose deployment <deployment-name> --port=<port> --dry-run=client -o yaml > svc.yaml

kubectl create configmap

# from literal values
k create configmap <configmap-name> --from-literal=<key>=<value> --from-literal=<key>=<value>

# from file
k create configmap <configmap-name> --from-file=<file>

# from file with custom key
k create configmap <configmap-name> --from-file=<key>=<file>

# from env file
k create configmap <configmap-name> --from-env-file=<file>

# from directory
k create configmap <configmap-name> --from-file=<directory>/

# generate YAML
k create configmap <configmap-name> --from-literal=<key>=<value> --dry-run=client -o yaml

kubectl create secret

# generic from literals
k create secret generic <secret-name> --from-literal=<key>=<value> --from-literal=<key>=<value>

# generic from file
k create secret generic <secret-name> --from-file=<key>=<file>

# TLS secret
k create secret tls <secret-name> --cert=<cert-file> --key=<key-file>

# docker registry secret
k create secret docker-registry <secret-name> \
  --docker-server=<server> \
  --docker-username=<username> \
  --docker-password=<password>

# generate YAML
k create secret generic <secret-name> --from-literal=<key>=<value> --dry-run=client -o yaml

kubectl create namespace

# create namespace
k create namespace <namespace>

kubectl create serviceaccount

# create service account
k create serviceaccount <service-account-name>

# in specific namespace
k create serviceaccount <service-account-name> -n <namespace>

kubectl create job

# basic job
k create job <job-name> --image=<image> -- <command>

# create job from existing cronjob
k create job <job-name> --from=cronjob/<cronjob-name>

kubectl create cronjob

# basic cronjob
k create cronjob <cronjob-name> --image=<image> --schedule="<cron-expression>" -- <command>

kubectl create ingress

# single rule
k create ingress <ingress-name> --rule="<host>/<path>=<service-name>:<port>"

# with TLS
k create ingress <ingress-name> --rule="<host>/<path>=<service-name>:<port>,tls=<tls-secret-name>"

# multiple rules
k create ingress <ingress-name> --rule="<host-1>/=<service-name-1>:<port>" --rule="<host-2>/=<service-name-2>:<port>"

# with default backend
k create ingress <ingress-name> --default-backend=<service-name>:<port>

# with annotation
k create ingress <ingress-name> --rule="<host>/=<service-name>:<port>" \
  --annotation=<key>=<value>

kubectl create role

# basic role
k create role <role-name> --verb=get,list,watch --resource=pods

# with specific resource names
k create role <role-name> --verb=get --resource=pods --resource-name=<resource-name>

# multiple resources
k create role <role-name> --verb=get,list --resource=pods,services

# with API group
k create role <role-name> --verb=get --resource=deployments.apps

kubectl create rolebinding

# bind to user
k create rolebinding <rolebinding-name> --role=<role-name> --user=<username>

# bind to group
k create rolebinding <rolebinding-name> --role=<role-name> --group=<group-name>

# bind to service account
k create rolebinding <rolebinding-name> --role=<role-name> --serviceaccount=<namespace>:<service-account-name>

kubectl create clusterrole

# basic cluster role
k create clusterrole <clusterrole-name> --verb=get,list,watch --resource=pods

# non-resource URLs
k create clusterrole <clusterrole-name> --verb=get --non-resource-url=<url>

kubectl create clusterrolebinding

# bind to user
k create clusterrolebinding <clusterrolebinding-name> --clusterrole=<clusterrole-name> --user=<username>

# bind to service account
k create clusterrolebinding <clusterrolebinding-name> --clusterrole=<clusterrole-name> --serviceaccount=<namespace>:<service-account-name>

kubectl create quota

# basic quota
k create quota <quota-name> --hard=pods=10,requests.cpu=4,requests.memory=8Gi

# with limits
k create quota <quota-name> --hard=pods=10,limits.cpu=8,limits.memory=16Gi

kubectl create pdb

# with min-available
k create pdb <pdb-name> --selector=<key>=<value> --min-available=<count>

# with max-unavailable
k create pdb <pdb-name> --selector=<key>=<value> --max-unavailable=<count>

kubectl create token

# create token for service account
k create token <service-account-name>

# with duration
k create token <service-account-name> --duration=<duration>

Updating Resources

kubectl set

# update container image
k set image deployment/<deployment-name> <container-name>=<image>:<tag>

# set environment variable
k set env deployment/<deployment-name> <key>=<value>

# set env from configmap
k set env deployment/<deployment-name> --from=configmap/<configmap-name>

# set env from secret
k set env deployment/<deployment-name> --from=secret/<secret-name>

# set resource requests and limits
k set resources deployment/<deployment-name> --requests=cpu=100m,memory=128Mi --limits=cpu=200m,memory=256Mi

# set service account
k set serviceaccount deployment/<deployment-name> <service-account-name>

kubectl scale

# scale deployment
k scale deployment <deployment-name> --replicas=<count>

# scale replicaset
k scale rs <replicaset-name> --replicas=<count>

# scale statefulset
k scale statefulset <statefulset-name> --replicas=<count>

# conditional scale (only if current replicas match)
k scale deployment <deployment-name> --replicas=<count> --current-replicas=<current-count>

kubectl rollout

# check rollout status
k rollout status deployment/<deployment-name>

# view rollout history
k rollout history deployment/<deployment-name>

# view specific revision
k rollout history deployment/<deployment-name> --revision=<revision>

# undo last rollout
k rollout undo deployment/<deployment-name>

# undo to specific revision
k rollout undo deployment/<deployment-name> --to-revision=<revision>

# restart rollout (triggers rolling update)
k rollout restart deployment/<deployment-name>

# pause rollout
k rollout pause deployment/<deployment-name>

# resume rollout
k rollout resume deployment/<deployment-name>

kubectl autoscale

# autoscale deployment
k autoscale deployment <deployment-name> --min=<min> --max=<max> --cpu-percent=<percent>

kubectl label

# add label
k label pod <pod-name> <key>=<value>

# overwrite existing label
k label pod <pod-name> <key>=<value> --overwrite

# remove label
k label pod <pod-name> <key>-

# label a node
k label node <node-name> <key>=<value>

# label all pods
k label pods --all <key>=<value>

kubectl annotate

# add annotation
k annotate pod <pod-name> <key>="<value>"

# remove annotation
k annotate pod <pod-name> <key>-

kubectl taint

# add taint with NoSchedule effect
k taint node <node-name> <key>=<value>:NoSchedule

# add taint with NoExecute effect
k taint node <node-name> <key>=<value>:NoExecute

# add taint with PreferNoSchedule effect
k taint node <node-name> <key>=<value>:PreferNoSchedule

# remove taint
k taint node <node-name> <key>=<value>:NoSchedule-

# remove all taints with a key
k taint node <node-name> <key>-

kubectl patch

# JSON strategic merge patch
k patch deployment <deployment-name> -p '{"spec":{"replicas":<count>}}'

# merge type patch
k patch deployment <deployment-name> --type=merge -p '{"spec":{"replicas":<count>}}'

# JSON patch type (add, remove, replace operations)
k patch deployment <deployment-name> --type=json -p '[{"op":"replace","path":"/spec/replicas","value":<count>}]'

# patch a node (e.g., remove a taint)
k patch node <node-name> --type=json -p '[{"op":"remove","path":"/spec/taints/0"}]'

Apply / Edit / Delete / Replace

# apply from file
k apply -f <file>

# apply from directory
k apply -f <directory>/

# apply from URL
k apply -f <url>

# edit resource in-place
k edit deployment <deployment-name>

# edit in specific namespace
k edit deployment <deployment-name> -n <namespace>

# delete resource
k delete pod <pod-name>

# force delete (immediate)
k delete pod <pod-name> --force --grace-period 0

# delete by file
k delete -f <file>

# delete all pods in namespace
k delete pods --all -n <namespace>

# delete by label
k delete pods -l <key>=<value>

# replace resource (delete + recreate)
k replace -f <file>

# force replace (useful for immutable fields)
k replace --force -f <file>

Viewing & Inspecting Resources

kubectl get

# wide output
k get pods -o wide

# YAML output
k get pod <pod-name> -o yaml

# JSON output
k get pod <pod-name> -o json

# all namespaces
k get pods -A
k get pods --all-namespaces

# show labels
k get pods --show-labels

# label selector (equality-based)
k get pods -l <key>=<value>
k get pods -l <key>=<value>,<key>=<value>
k get pods -l <key>!=<value>

# label selector (set-based)
k get pods -l '<key> in (<value-1>,<value-2>)'
k get pods -l '<key> notin (<value>)'
k get pods -l '!<key>'

# field selector
k get pods --field-selector=status.phase=Running
k get pods --field-selector=metadata.name=<pod-name>

# sort by
k get pods --sort-by=.metadata.creationTimestamp
k get pods --sort-by=.status.containerStatuses[0].restartCount

# get multiple resources
k get pods,svc,deploy

# watch for changes
k get pods -w

kubectl describe

# describe pod
k describe pod <pod-name>

# describe node
k describe node <node-name>

# describe service
k describe svc <service-name>

# describe all pods
k describe pods

kubectl logs

# view logs
k logs <pod-name>

# follow logs (stream)
k logs -f <pod-name>

# previous container logs (after restart)
k logs <pod-name> --previous

# specific container in multi-container pod
k logs <pod-name> -c <container-name>

# tail last N lines
k logs <pod-name> --tail=<count>

# logs since time duration
k logs <pod-name> --since=<duration>

# logs by label selector
k logs -l <key>=<value>

kubectl exec

# run a command
k exec <pod-name> -- <command>

# interactive shell
k exec -it <pod-name> -- /bin/sh

# specific container in multi-container pod
k exec -it <pod-name> -c <container-name> -- /bin/sh

kubectl port-forward

# forward pod port
k port-forward pod/<pod-name> <local-port>:<pod-port>

# forward service port
k port-forward svc/<service-name> <local-port>:<service-port>

kubectl get events

# get events sorted by time
k get events --sort-by=.metadata.creationTimestamp

# events for a specific resource
k get events --field-selector=involvedObject.name=<resource-name>

kubectl explain

# explain a resource
k explain <resource>

# explain a specific field
k explain <resource>.<field>

# recursive (show all fields)
k explain <resource>.<field> --recursive

# specific API version
k explain <resource> --api-version=<api-version>

Cluster & Node Operations

# cluster info
k cluster-info

# list API resources (with short names)
k api-resources

# namespaced resources only
k api-resources --namespaced=true

# cluster-scoped resources only
k api-resources --namespaced=false

# list API versions
k api-versions

# top nodes (resource usage)
k top nodes

# top pods
k top pods

# top pods sorted by cpu
k top pods --sort-by=cpu

# top pods sorted by memory
k top pods --sort-by=memory

# top pods with containers
k top pods --containers

# mark node as unschedulable
k cordon <node-name>

# mark node as schedulable
k uncordon <node-name>

# drain node (evict pods for maintenance)
k drain <node-name> --ignore-daemonsets --delete-emptydir-data

Config & Context

# show current context
k config current-context

# list all contexts
k config get-contexts

# switch context
k config use-context <context-name>

# set default namespace for current context
k config set-context --current --namespace=<namespace>

# view full config
k config view

# view config for current context only
k config view --minify

RBAC

# check if you can perform an action
k auth can-i <verb> <resource>

# check as a specific user
k auth can-i <verb> <resource> --as=<username>

# check as a service account
k auth can-i <verb> <resource> --as=system:serviceaccount:<namespace>:<service-account-name>

# check all permissions
k auth can-i --list

# check in specific namespace
k auth can-i <verb> <resource> -n <namespace>

# show current user info
k auth whoami

Certificates

# list certificate signing requests
k get csr

# approve a CSR
k certificate approve <csr-name>

# deny a CSR
k certificate deny <csr-name>

# delete a CSR
k delete csr <csr-name>

JSONPath & Custom Columns

JSONPath

# basic field
k get pods -o jsonpath='{.items[*].metadata.name}'

# multiple fields with range
k get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'

# specific index
k get pods -o jsonpath='{.items[0].metadata.name}'

# filter with conditional
k get pods -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'

# node internal IPs
k get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'

# all container images
k get pods -o jsonpath='{.items[*].spec.containers[*].image}'

Custom Columns

# inline custom columns
k get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName

# from file
k get pods -o custom-columns-file=<file>

# nodes with taints
k get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints