Core Commands & Resource Management
kubectl: Core Commands & Resource Management kubectl is the Kubernetes command-line tool. It communicates with the cluster API server to manage workloads, inspe…
kubectl: Core Commands & Resource Management
kubectl is the Kubernetes command-line tool. It communicates with the cluster API server to manage workloads, inspect resources, and apply configuration. All kubectl commands follow a pattern: kubectl <verb> <resource> [name] [flags].
Getting Resources
# List resources
kubectl get pods # pods in current namespace
kubectl get pods -n kube-system # pods in specific namespace
kubectl get pods -A # all namespaces
kubectl get pods -o wide # extra info (node, IP)
kubectl get pods -o yaml # full YAML spec
kubectl get pods -o json # JSON output
kubectl get pods -l app=nginx # filter by label
kubectl get pods --field-selector status.phase=Running
# Common resource types (short names work too)
kubectl get pods / po
kubectl get deployments / deploy
kubectl get services / svc
kubectl get configmaps / cm
kubectl get secrets
kubectl get namespaces / ns
kubectl get nodes / no
kubectl get ingress / ing
kubectl get persistentvolumes / pv
kubectl get persistentvolumeclaims / pvc
kubectl get statefulsets / sts
kubectl get daemonsets / ds
kubectl get replicasets / rs
kubectl get jobs
kubectl get cronjobs / cj
kubectl get serviceaccounts / sa
# Describe (detailed info + events)
kubectl describe pod my-pod
kubectl describe deployment my-deploy
kubectl describe node worker-1
# Watch for changes
kubectl get pods -w
kubectl get pods --watch
Creating & Applying Resources
# Apply manifest (create or update)
kubectl apply -f deployment.yaml
kubectl apply -f ./manifests/ # apply all files in directory
kubectl apply -f https://example.com/app.yaml
# Create (fails if already exists)
kubectl create deployment nginx --image=nginx:1.25
kubectl create service clusterip my-svc --tcp=80:80
kubectl create configmap my-config --from-literal=key=value
kubectl create configmap my-config --from-file=config.properties
kubectl create secret generic my-secret --from-literal=password=s3cr3t
kubectl create secret docker-registry regcred --docker-server=registry.example.com --docker-username=user --docker-password=pass
# Quick pod for testing
kubectl run tmp --image=busybox --rm -it --restart=Never -- sh
kubectl run nginx --image=nginx --port=80
# Expose a deployment as a service
kubectl expose deployment nginx --port=80 --type=ClusterIP
kubectl expose deployment nginx --port=80 --type=LoadBalancer
Updating & Deleting
# Edit live resource
kubectl edit deployment my-deploy # opens in $EDITOR
kubectl edit cm my-config
# Patch (non-interactive update)
kubectl patch deployment my-deploy -p '{"spec":{"replicas":3}}'
kubectl patch deployment my-deploy --type=merge -p '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":30}}}}'
# Set image (rolling update)
kubectl set image deployment/my-deploy container=nginx:1.26
# Delete
kubectl delete pod my-pod
kubectl delete -f deployment.yaml
kubectl delete deployment my-deploy
kubectl delete pod my-pod --grace-period=0 --force # force delete
# Delete all pods matching label
kubectl delete pods -l app=nginx
# Scale
kubectl scale deployment my-deploy --replicas=5
# Rollout
kubectl rollout status deployment/my-deploy
kubectl rollout history deployment/my-deploy
kubectl rollout undo deployment/my-deploy # rollback
kubectl rollout undo deployment/my-deploy --to-revision=2
Labels & Annotations
# Add/update label
kubectl label pod my-pod env=production
kubectl label pod my-pod env=staging --overwrite
# Remove label (trailing dash)
kubectl label pod my-pod env-
# Add annotation
kubectl annotate deployment my-deploy kubernetes.io/change-cause="update to v2"
# Select by label
kubectl get pods -l app=nginx,env=production
kubectl get pods -l 'env in (production, staging)'
kubectl get pods -l 'env notin (development)'
Namespaces, Contexts & Configuration
kubectl: Namespaces, Contexts & Configuration Namespaces Namespaces partition cluster resources between multiple users or teams. Most resources are namespace-sc…
kubectl: Namespaces, Contexts & Configuration
Namespaces
Namespaces partition cluster resources between multiple users or teams. Most resources are namespace-scoped; a few (nodes, PVs, namespaces themselves) are cluster-scoped.
# List namespaces
kubectl get namespaces
# Create namespace
kubectl create namespace staging
# Work in a specific namespace
kubectl get pods -n staging
kubectl apply -f app.yaml -n staging
# Set default namespace for current context
kubectl config set-context --current --namespace=staging
# Delete namespace (deletes all resources inside!)
kubectl delete namespace staging
# Namespace-scoped vs cluster-scoped resources
kubectl api-resources --namespaced=true # namespace-scoped
kubectl api-resources --namespaced=false # cluster-scoped
Contexts & kubeconfig
A context is a named triple of (cluster, namespace, user). kubeconfig stores credentials and contexts — typically at ~/.kube/config.
# View current config
kubectl config view
kubectl config view --minify # only current context
kubectl config view --raw # decode base64 secrets
# Current context
kubectl config current-context
# List contexts
kubectl config get-contexts
# Switch context
kubectl config use-context prod-cluster
# Rename context
kubectl config rename-context old-name new-name
# Delete context
kubectl config delete-context old-context
# Merge kubeconfigs (combine cluster credentials)
KUBECONFIG=~/.kube/config:~/Downloads/new-cluster.yaml kubectl config view --flatten > ~/.kube/config
# Use a different kubeconfig file
kubectl --kubeconfig=/path/to/config get pods
export KUBECONFIG=/path/to/config # or set env var
ConfigMaps & Secrets
# ConfigMap from literal values
kubectl create configmap app-config --from-literal=DB_HOST=postgres --from-literal=DB_PORT=5432
# ConfigMap from file
kubectl create configmap nginx-conf --from-file=nginx.conf
kubectl create configmap app-props --from-env-file=.env
# View ConfigMap data
kubectl get configmap app-config -o yaml
kubectl describe configmap app-config
# Secret (values are base64-encoded in YAML, not encrypted)
kubectl create secret generic db-creds --from-literal=username=admin --from-literal=password=s3cr3t
# TLS secret
kubectl create secret tls my-tls --cert=tls.crt --key=tls.key
# Decode secret value
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d
# Update secret (edit base64-encodes values in $EDITOR)
kubectl edit secret db-creds
RBAC
# List roles and bindings
kubectl get roles,rolebindings -n default
kubectl get clusterroles,clusterrolebindings
# Check permissions (as yourself)
kubectl auth can-i create pods
kubectl auth can-i delete deployments -n production
# Check permissions as another user/serviceaccount
kubectl auth can-i get pods --as=jane
kubectl auth can-i list secrets --as=system:serviceaccount:default:my-sa
# Create role + binding
kubectl create role pod-reader --verb=get,list,watch --resource=pods
kubectl create rolebinding read-pods --role=pod-reader --user=jane --serviceaccount=default:my-sa
Debugging, Scaling & Advanced Operations
kubectl: Debugging, Scaling & Advanced Operations Logs & Exec # Pod logs kubectl logs my-pod kubectl logs my-pod -c container-name # specific container in multi…
kubectl: Debugging, Scaling & Advanced Operations
Logs & Exec
# Pod logs
kubectl logs my-pod
kubectl logs my-pod -c container-name # specific container in multi-container pod
kubectl logs my-pod --previous # logs from previous (crashed) container
kubectl logs my-pod -f # follow (stream)
kubectl logs my-pod --tail=100 # last 100 lines
kubectl logs my-pod --since=1h # last hour
kubectl logs -l app=nginx # logs from all pods with label
# Exec into container
kubectl exec -it my-pod -- bash
kubectl exec -it my-pod -c sidecar -- sh # specific container
kubectl exec my-pod -- ls /app # one-off command
# Copy files
kubectl cp my-pod:/app/config.yaml ./config.yaml # pod → local
kubectl cp ./data.sql my-pod:/tmp/data.sql # local → pod
Port Forwarding & Proxy
# Forward local port to pod
kubectl port-forward pod/my-pod 8080:80
kubectl port-forward deployment/my-deploy 8080:80
kubectl port-forward service/my-svc 8080:80
# Access background
kubectl port-forward svc/postgres 5432:5432 &
# Proxy to API server (all kubectl API accessible at localhost:8001)
kubectl proxy
# then: curl http://localhost:8001/api/v1/namespaces/default/pods
# Debug with ephemeral containers (K8s 1.23+)
kubectl debug -it my-pod --image=busybox --target=app
kubectl debug node/worker-1 -it --image=ubuntu
Resource Usage & Events
# Resource usage (requires metrics-server)
kubectl top pods
kubectl top pods -n production -l app=nginx
kubectl top nodes
# Events (sorted by time)
kubectl get events --sort-by=.lastTimestamp
kubectl get events -n staging
kubectl get events --field-selector reason=BackOff
# Resource requests/limits
kubectl describe pod my-pod | grep -A3 Requests
kubectl describe node worker-1 | grep -A10 "Allocated resources"
JSONPath & Custom Output
# JSONPath queries
kubectl get pod my-pod -o jsonpath='{.status.podIP}'
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
# Custom columns
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName
# Sort output
kubectl get pods --sort-by=.metadata.creationTimestamp
kubectl get pods --sort-by=.status.containerStatuses[0].restartCount
# All resources across a namespace (for audit)
kubectl api-resources --verbs=list --namespaced -o name | xargs -I{} kubectl get {} -n default 2>/dev/null
Helpful Plugins & Tips
kubectx / kubens (ahmetb): instantly switch contexts and namespaces — brew install kubectx.
krew: kubectl plugin manager — kubectl krew install <plugin>.
kubectl neat: strips clutter from -o yaml output (managedFields, status) — great for diffing.
kubecolor: colorized kubectl output — drop-in alias for kubectl.
k9s: terminal UI for Kubernetes — real-time cluster view with logs, exec, and port-forward.
stern: tail logs from multiple pods simultaneously, with regex filtering.
kubectl diff -f file.yaml: preview what apply would change without applying.
kubectl explain pod.spec.containers: built-in API field documentation without leaving the terminal.
# Useful aliases
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgd='kubectl get deploy'
alias kl='kubectl logs -f'
alias ke='kubectl exec -it'
# Shell completion
source <(kubectl completion bash) # bash
source <(kubectl completion zsh) # zsh
# or add to ~/.bashrc / ~/.zshrc
# Dry-run (validate without applying)
kubectl apply -f app.yaml --dry-run=client
kubectl apply -f app.yaml --dry-run=server # validates against cluster API
# Generate YAML from imperative command
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > deployment.yaml
kubectl expose deployment nginx --port=80 --dry-run=client -o yaml >> deployment.yaml