☸️ Kubernetes & EKS Ops Cheat Sheet
Daily-driver command reference — kubectl core, the entity model, multi-cluster context handling, and the EKS/Helm/Argo Rollouts/observability layer used in production.
💡 Always confirm your context before running anything against
prod:kubectl config current-context
📖 Kubernetes Entity Glossary
1. Cluster-Level
| Entity | What it is |
|---|---|
| Node | A physical or virtual machine that runs workloads. |
| Namespace | A logical partition of resources within a cluster. |
| Context | A saved combination of cluster + user + namespace, used to target a specific cluster. |
2. Workload Management
| Entity | What it is |
|---|---|
| Pod | Smallest deployable unit; one or more containers sharing network/storage. |
| Deployment | Manages rollout, scaling, and self-healing of stateless Pods. |
| ReplicaSet | Ensures a set number of Pod replicas are running (usually managed by a Deployment, not directly). |
| DaemonSet | Runs one copy of a Pod on every (or selected) node — e.g. log shippers, CNI agents. |
| StatefulSet | Manages Pods needing stable identity, ordered rollout, and persistent storage — e.g. databases. |
| Job | Runs a Pod to completion for a batch task. |
| CronJob | Runs Jobs on a schedule. |
| HorizontalPodAutoscaler (HPA) | Scales replica count based on CPU/memory/custom metrics. |
| VerticalPodAutoscaler (VPA) | Adjusts a Pod's CPU/memory requests over time. |
| PodDisruptionBudget (PDB) | Limits how many Pods of a set can be down at once during voluntary disruptions. |
3. Networking & Traffic
| Entity | What it is |
|---|---|
| Service | Stable virtual IP/DNS name exposing a set of Pods. |
| Endpoint / EndpointSlice | The actual Pod IPs backing a Service. |
| Ingress | HTTP(S) routing rules for external traffic into the cluster. |
| IngressClass | Declares which controller handles a given Ingress. |
| IngressRoute | CRD used by some controllers (e.g. Traefik) instead of core Ingress. |
| Gateway / HTTPRoute | Gateway API resources — the newer, more expressive successor to Ingress. |
| NetworkPolicy | Firewall rules between Pods (default-deny, allow-lists, etc). |
4. Storage & Configuration
| Entity | What it is |
|---|---|
| ConfigMap | Non-sensitive key-value configuration data. |
| Secret | Sensitive data (passwords, tokens, certs) — base64-encoded, not encrypted by default. |
| PersistentVolume (PV) | A piece of provisioned storage in the cluster. |
| PersistentVolumeClaim (PVC) | A Pod's request/binding to a PV. |
| StorageClass | Defines how volumes are dynamically provisioned (EBS type, EFS, etc). |
| VolumeSnapshot | Point-in-time copy of a PVC, if the CSI driver supports it. |
5. Security & Identity
| Entity | What it is |
|---|---|
| ServiceAccount | Identity a Pod uses to talk to the API server (or, via IRSA, to AWS). |
| Role / RoleBinding | Permissions scoped to one namespace. |
| ClusterRole / ClusterRoleBinding | Permissions scoped cluster-wide. |
| PodSecurityStandard (PSS) | Namespace-level enforcement of baseline/restricted/privileged Pod rules. |
| ClusterIssuer / Issuer | cert-manager resource that issues TLS certificates. |
| CertificateRequest / Certificate | cert-manager's request and resulting cert object. |
6. Resource Management
| Entity | What it is |
|---|---|
| ResourceQuota | Caps total resource consumption in a namespace. |
| LimitRange | Default/min/max resource requests-limits per Pod/container in a namespace. |
| PriorityClass | Determines scheduling/preemption priority for Pods. |
7. Logging & Monitoring
| Entity | What it is |
|---|---|
| Event | Cluster-recorded state changes and errors (scheduling, pulls, probes). |
| Metrics Server | Feeds kubectl top and HPA with live CPU/memory usage. |
| ServiceMonitor / PodMonitor | Prometheus Operator CRDs that tell Prometheus what to scrape. |
| PrometheusRule | CRD defining alerting/recording rules. |
| Alertmanager | Routes/groups/dedupes firing alerts to receivers (Slack, Google Chat, etc). |
8. Custom Resources
| Entity | What it is |
|---|---|
| CustomResourceDefinition (CRD) | Extends the API with a new object type (e.g. Rollout, NodePool, PrometheusRule). |
| CustomResource (CR) | An instance of a CRD-defined type. |
| Operator | A controller that watches CRs and reconciles real-world state to match them. |
🚀 Quick Reference
| Task | Command |
|---|---|
| List pods | kubectl get pods |
| List pods (all ns) | kubectl get pods -A |
| List nodes | kubectl get nodes |
| Describe pod | kubectl describe pod <pod> |
| Tail logs | kubectl logs -f <pod> |
| Shell into pod | kubectl exec -it <pod> -- /bin/bash |
| Apply manifest | kubectl apply -f deployment.yaml |
| Delete manifest | kubectl delete -f deployment.yaml |
| Current context | kubectl config current-context |
| Switch namespace | kubectl config set-context --current --namespace=<ns> |
Cluster
kubectl cluster-info
kubectl version
kubectl get nodes -o wide
kubectl describe node <node-name>
kubectl top nodesPods
kubectl get pods -o wide
kubectl get pods -A
kubectl get pods --field-selector=status.phase=Pending
kubectl describe pod <pod>
kubectl delete pod <pod>
kubectl logs <pod>
kubectl logs -f <pod>
kubectl logs <pod> -c <container> # multi-container pod
kubectl logs <pod> --previous # crashed container's last logs
kubectl exec -it <pod> -- /bin/bash
kubectl exec -it <pod> -c <container> -- /bin/sh
# debug a pod without a shell (distroless images etc.)
kubectl debug -it <pod> --image=busybox --target=<container>
kubectl debug node/<node-name> -it --image=busybox # debug a nodeDeployments / ReplicaSets / DaemonSets / StatefulSets
kubectl get deploy
kubectl describe deployment <deployment>
kubectl scale deployment <deployment> --replicas=3
kubectl rollout status deployment <deployment>
kubectl rollout history deployment <deployment>
kubectl rollout undo deployment <deployment>
kubectl rollout restart deployment <deployment> # prefer this over deleting pods
kubectl get rs
kubectl get ds -A
kubectl get statefulset
kubectl rollout status statefulset <name>Jobs & CronJobs
kubectl get jobs
kubectl get cronjobs
kubectl create job manual-run --from=cronjob/<cronjob-name> # trigger a CronJob manually
kubectl delete job <job-name>Autoscaling
kubectl get hpa
kubectl describe hpa <name>
kubectl autoscale deployment <deployment> --cpu-percent=70 --min=2 --max=10
kubectl get vpa # if VPA CRDs installed
kubectl describe vpa <name>
kubectl get pdb # PodDisruptionBudgetsServices / Ingress / Networking
kubectl get svc
kubectl describe svc <service>
kubectl expose deployment nginx --type=NodePort --port=80
kubectl get ingress
kubectl describe ingress <name>
kubectl get ingressclass
kubectl get ingressroutes -A # Traefik CRD
kubectl get gateway,httproute -A # Gateway API, if in use
kubectl get endpoints <service>
kubectl get networkpolicy -A
kubectl describe networkpolicy <name>ConfigMaps / Secrets
kubectl get configmaps
kubectl describe configmap <configmap>
kubectl delete configmap <configmap>
kubectl get secrets
kubectl describe secret <secret>
kubectl delete secret <secret>
kubectl get secret <secret> -o jsonpath='{.data.<key>}' | base64 -d # decode a valueStorage
kubectl get pv
kubectl get pvc -A
kubectl describe pvc <pvc>
kubectl get storageclass
kubectl get volumesnapshot -ARBAC & Identity
kubectl get sa
kubectl describe sa <serviceaccount>
kubectl get role,rolebinding -n <namespace>
kubectl get clusterrole,clusterrolebinding
kubectl auth can-i <verb> <resource> # e.g. can-i delete pods
kubectl auth can-i <verb> <resource> --as=system:serviceaccount:<ns>:<sa>Resource Governance
kubectl get resourcequota -n <namespace>
kubectl describe resourcequota <name> -n <namespace>
kubectl get limitrange -n <namespace>
kubectl get priorityclassNamespaces
kubectl get ns
kubectl create namespace dev
kubectl delete namespace dev
kubectl config set-context --current --namespace=devPort Forward
kubectl port-forward pod/<pod> 8080:80
kubectl port-forward svc/<service> 8080:80Resource Files
kubectl apply -f deployment.yaml
kubectl create -f deployment.yaml
kubectl delete -f deployment.yaml
kubectl replace -f deployment.yaml
kubectl diff -f deployment.yaml # preview changes before apply
kubectl explain <resource> # e.g. `kubectl explain deployment.spec` — inline API docsCertificates (cert-manager)
kubectl get clusterissuer
kubectl get certificaterequests
kubectl get certificates
kubectl describe certificate <name> # check Ready condition and renewal timeCustom Resources / CRDs
kubectl get crd
kubectl explain <crd-kind> # inline docs for a CRD, same as built-ins
kubectl api-resources # list every resource type the cluster knows, with short names
kubectl api-versionsMonitoring & Troubleshooting
kubectl get events --sort-by=.lastTimestamp
kubectl get events -A --sort-by=.lastTimestamp | tail -30
kubectl top pods
kubectl top pods -n <namespace>
kubectl get pods --field-selector=status.phase=Pending
kubectl describe pod <pod> # check before logs — Events section shows scheduling/pull failures
kubectl logs -f <pod>
# useful output formats
kubectl get pods -o yaml
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase
kubectl get pods --watch🔀 Multi-Context Management
Switching between AWS EKS clusters (and any local cluster) is the main source of "wrong cluster" mistakes. aws eks update-kubeconfig adds/updates an entry in your kubeconfig — it doesn't remove others.
View available contexts
kubectl config get-contextsCURRENT NAME CLUSTER NAMESPACE
* arn:aws:eks:ap-south-1:xxxx:cluster/prod-eks ... esb-custom-oms
arn:aws:eks:ap-south-1:xxxx:cluster/stg-eks ... esb-custom-oms
default ... defaultThe * marks the active context.
Switch context
kubectl config use-context default
kubectl config use-context arn:aws:eks:ap-south-1:xxxx:cluster/prod-eksRun one-off commands against a different context without switching
kubectl --context=stg-eks get podsCheck current context
kubectl config current-contextRename long EKS ARNs to something usable
kubectl config rename-context arn:aws:eks:ap-south-1:xxxx:cluster/prod-eks eks-prod
kubectl config rename-context arn:aws:eks:ap-south-1:xxxx:cluster/stg-eks eks-stgSeparate kubeconfig files per environment
Instead of one growing kubeconfig, keep prod isolated:
export KUBECONFIG=~/.kube/eks-prod-config
aws eks update-kubeconfig --name production --region ap-south-1 --kubeconfig ~/.kube/eks-prod-configMerge multiple kubeconfigs read-only for viewing:
KUBECONFIG=~/.kube/config:~/.kube/eks-prod-config kubectl config view --flatten > ~/.kube/merged-configkubectx / kubens (optional, faster switching)
brew install kubectx # macOS
sudo snap install kubectx # Linux
kubectx # list contexts
kubectx eks-prod # switch
kubens <namespace> # switch namespace without editing contextShell aliases for frequent clusters
# ~/.bashrc or ~/.zshrc
alias k8s-local='kubectl config use-context default'
alias k8s-prod='kubectl config use-context eks-prod'
alias k8s-stg='kubectl config use-context eks-stg'Shell prompt indicator
Show the active context/namespace in your prompt (e.g. via kube-ps1 or an Oh My Zsh plugin) so a prod mistake is visible before you hit enter — the single highest-leverage guardrail for multi-cluster work.
Cleaning up
kubectl config delete-context <context-name>Troubleshooting context/kubeconfig issues
cat ~/.kube/config # inspect for corruption/merge issues
ls -la ~/.kube/config # check permissions
aws eks update-kubeconfig --name <cluster> --region <region> # re-fetch a context
kubectl config view --minify --flatten # show only the active context's full configAWS EKS
aws eks update-kubeconfig --region ap-south-1 --name production
kubectl config get-contexts
kubectl config use-context eks-productionKarpenter
kubectl get nodepools
kubectl describe nodepool <nodepool>
kubectl get nodeclaims
kubectl describe nodeclaim <nodeclaim>
kubectl get nodeclaims -o wide
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -f
# prevent Karpenter from disrupting a specific node
kubectl annotate node <node-name> karpenter.sh/do-not-disrupt-Helm
helm list -A
helm status <release> -n <namespace>
helm get values <release> -n <namespace>
helm get manifest <release> -n <namespace>
helm upgrade <release> <chart-path> -n <namespace> -f values.yaml
helm upgrade <release> <chart-path> -n <namespace> --dry-run --debug
helm rollback <release> <revision> -n <namespace>
helm history <release> -n <namespace>
helm template <chart-path> -f values.yaml # render locally before applying
helm lint <chart-path> # validate chart before packagingArgo Rollouts (BlueGreen)
kubectl argo rollouts get rollout <name> -n <namespace> --watch
kubectl argo rollouts promote <name> -n <namespace>
kubectl argo rollouts abort <name> -n <namespace>
kubectl argo rollouts undo <name> -n <namespace>
kubectl argo rollouts status <name> -n <namespace>
kubectl argo rollouts list rollouts -n <namespace>Observability (Prometheus / Alertmanager)
# check alerting rules are loaded
kubectl exec -n monitoring <prometheus-pod> -- promtool check rules /path/to/rules.yaml
# port-forward to Prometheus / Alertmanager / Grafana UI
kubectl port-forward svc/alertmanager-prometheus-kube-prometheus-alertmanager 9093:9093 -n monitoring
kubectl port-forward svc/kube-prometheus-stack-prometheus 9090:9090 -n monitoring
kubectl port-forward svc/kube-prometheus-stack-grafana 3000:80 -n monitoring
# reload config without restart (if --web.enable-lifecycle is set)
kubectl exec -n monitoring <prometheus-pod> -- kill -HUP 1
# check what a ServiceMonitor/PodMonitor/PrometheusRule looks like
kubectl get servicemonitor,podmonitor,prometheusrule -A💡 Best Practices
- ✔ Use namespaces instead of the default namespace.
- ✔ Prefer
kubectl apply(orhelm upgrade) over imperativecreate/kubectl edit— keeps GitOps in sync. - ✔ Use
kubectl rollout restartinstead of deleting pods. - ✔ Always verify the active context before making changes:
kubectl config current-context. - ✔ Use
kubectl describebeforekubectl logs— the Events section often shows the real cause (scheduling, image pull, OOM). - ✔
helm diff upgrade/--dry-runbefore every real upgrade. - ✔ Never edit production resources directly — change the source (Helm values, manifest) and reapply.
- ✔ For alerting rules, drop labels like
namespacefrom expressions if they render asN/A— check label availability withkubectl get --show-labelsfirst. - ✔ Keep prod in its own kubeconfig or renamed context, and put the active context in your shell prompt.
- ✔ Use
kubectl auth can-ibefore assuming an RBAC problem is something else.
📋 One-Line Lookup
| Category | Command |
|---|---|
| Pods | kubectl get pods |
| Nodes | kubectl get nodes |
| Deployments | kubectl get deploy |
| Services | kubectl get svc |
| Ingress | kubectl get ingress |
| ConfigMaps | kubectl get cm |
| Secrets | kubectl get secrets |
| Namespaces | kubectl get ns |
| PVCs | kubectl get pvc -A |
| Events | kubectl get events --sort-by=.lastTimestamp |
| RBAC check | kubectl auth can-i <verb> <resource> |
| All API resources | kubectl api-resources |
| Karpenter NodePools | kubectl get nodepools |
| Helm releases | helm list -A |
| Argo Rollout status | kubectl argo rollouts get rollout <name> --watch |
| Contexts | kubectl config get-contexts |