kubectl - kubectl controls the Kubernetes cluster manager
kubectl [command] [TYPE] [NAME] [flags]
Options you will use
get TYPE [NAME]- list resources. -o wide|yaml|json|name|jsonpath=...|custom-columns=..., -l SELECTOR, -A (all namespaces), -n NS, --show-labels, --sort-by=JSONPATH, -w (watch)
describe TYPE NAME- human-readable detail. The Events table at the bottom is the first place to look when something is wrong. Name is a prefix match.
apply -f FILE|DIR|-- create or update from manifests (declarative). Records kubectl.kubernetes.io/last-applied-configuration for the 3-way merge.
create TYPE NAME ...- imperative generators: deployment, configmap, secret generic|tls|docker-registry, job, cronjob, namespace, service, serviceaccount. With --dry-run=client -o yaml they print a manifest instead.
run NAME --image=IMG- a single Pod. --restart=Never, --rm -it for a throwaway shell, --command -- CMD, --dry-run=client -o yaml.
delete TYPE NAME | -f FILE | -l SEL- delete and WAIT for it to be gone. --force --grace-period=0 skips the wait (dangerous for StatefulSets).
edit TYPE NAME- open the live object in the editor; saving applies it.
scale TYPE/NAME --replicas=N- set the replica count
rollout status|history|undo|restart|pause|resume- manage Deployment/StatefulSet/DaemonSet rollouts. undo --to-revision=N.
set image TYPE/NAME C=IMG- change a container image (triggers a rollout). Also set env, set resources.
label / annotate- KEY=VAL to set, KEY- to remove, --overwrite to change an existing value
logs POD|TYPE/NAME- -c CONTAINER, -f follow, --previous (the crashed instance), --tail=N, --timestamps, -l SELECTOR
exec POD -- CMD- -it POD -- sh for a shell; -c CONTAINER
explain TYPE[.field.path]- API field documentation; --recursive for the whole tree
api-resources- every resource type, its short name, API group and whether it is namespaced
top node|pod- CPU/memory from metrics-server; --sort-by=cpu|memory, --containers
config get-contexts|use-context|set-context --current --namespace=NS|view- kubeconfig management
auth can-i VERB RESOURCE- ask the apiserver whether you are allowed; --as to impersonate
cordon|uncordon|drain NODE- node maintenance; drain --ignore-daemonsets --delete-emptydir-data
wait --for=condition=Ready pod/NAME- block until a condition holds (or --for=delete)
completion bash- print the bash completion script: source <(kubectl completion bash)
-n, --namespace NS- If present, the namespace scope for this CLI request. Default: the context's namespace, else default.
-A, --all-namespaces- If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
-o, --output FORMAT- Output format: json, yaml, name, wide, jsonpath=..., custom-columns=..., go-template=...
-l, --selector SELECTOR- Selector (label query) to filter on, supports '=', '==', '!=', 'in', 'notin' (e.g. -l key1=value1,key2=value2).
-f, --filename FILE- Filename, directory, or URL to files identifying the resource. - reads stdin.
-k, --kustomize DIR- Process the kustomization directory. This flag can't be used together with -f or -R.
-R, --recursive- Process the directory used in -f, --filename recursively.
--dry-run[=MODE]- none (default), client (print what would be sent, nothing leaves your machine) or server (the apiserver validates and runs admission, nothing is stored).
-h, --help- Help for the command (every subcommand has one: kubectl create role -h shows examples).
--context NAME- The name of the kubeconfig context to use (cluster + user + namespace), for this call only.
--kubeconfig FILE- Path to the kubeconfig file to use for CLI requests. Default: $KUBECONFIG, else ~/.kube/config.
--cluster NAME- The name of the kubeconfig cluster to use.
--user NAME- The name of the kubeconfig user to use.
--as USER- Username to impersonate for the operation. User could be a regular user or a service account (system:serviceaccount:NS:NAME). Needs the impersonate permission.
--as-group GROUP- Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid UID- UID to impersonate for the operation.
-s, --server URL- The address and port of the Kubernetes API server.
--token TOKEN- Bearer token for authentication to the API server. It ends up in your shell history and ps output.
--certificate-authority FILE- Path to a cert file for the certificate authority.
--client-certificate FILE- Path to a client certificate file for TLS.
--client-key FILE- Path to a client key file for TLS.
--insecure-skip-tls-verify- If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
--request-timeout DURATION- The length of time to wait before giving up on a single server request (e.g. 1s, 2m). 0 = no timeout.
-v, --v LEVEL- Number for the log level verbosity. -v=6 prints every HTTP request, -v=8 the bodies too.
--field-selector SELECTOR- Selector (field query) to filter on, supports '=', '==', and '!=' (e.g. --field-selector status.phase=Running). Only some fields are indexed server-side.
-w, --watch- After listing/getting the requested object, watch for changes.
--timeout DURATION- The length of time to wait before giving up (e.g. 60s, 5m).
--force- Immediate deletion / replace by delete + create. Can cause data loss.
--show-labels- When printing, show all labels as the last column.
-L, --label-columns LABELS- Accepts a comma separated list of labels that are going to be presented as columns.
--no-headers- When using the default or custom-column output format, don't print headers.
--sort-by JSONPATH- If non-empty, sort list types using this field specification (e.g. .metadata.creationTimestamp).
--ignore-not-found- If the requested object does not exist the command will return exit code 0.
--overwrite- Allow an existing label/annotation/taint value to be overwritten.
--replicas N- The new desired number of replicas.
--image IMAGE- The image for the container to run.
--port PORT- The port to expose.
-c, --container NAME- Container name. If omitted, use the kubectl.kubernetes.io/default-container annotation, else the first container.
-p, --patch PATCH- The patch to apply (kubectl patch).
--type TYPE- The type: of patch (strategic|merge|json), of service (ClusterIP|NodePort|LoadBalancer) or of secret.
--name NAME- The name for the newly created object.
--target-port PORT- Name or number for the port on the container that the service should direct traffic to.
--for CONDITION- The condition to wait on / the object to show events for.
--from SOURCE- The source to read from (a resource, a file or a cronjob, depending on the command).
--patch-file FILE- A file containing a patch to be applied to the resource.
--client- If true, shows client version only (no server required).
Examples
$ kubectl get pods -o widepods with their IP and node
$ kubectl get deploy,rs,pods --show-labelsthe ownership chain, with labels
$ kubectl create deployment web --image=nginx:1.27 --replicas=3 --dry-run=client -o yaml > web.yamlgenerate a manifest instead of writing one
$ kubectl get pods -wwatch changes live (Ctrl+C to stop)
$ kubectl get pods -o jsonpath='{.items[*].metadata.name}'just the names
$ kubectl logs deploy/web --previouslogs of the last crashed container of one pod of the deployment
$ kubectl rollout undo deploy/web --to-revision=2roll back to a specific revision
Gotchas
- With no ~/.kube/config kubectl falls back to http://localhost:8080 and says "The connection to the server localhost:8080 was refused". sudo kubectl reads /root/.kube/config, not yours.
- kubectl talks ONLY to the apiserver. Nothing it does touches a node directly: the apiserver writes to etcd, and controllers, the scheduler and the kubelets react.
- alias k=kubectl breaks Tab completion until you also run: complete -o default -F __start_kubectl k
Taught in
- 15.1 The lab cluster, kubectl and kubeconfig
- 17.1 Requests and limits: what each one actually controls
- 17.3 QoS classes, oom_score_adj, and who gets evicted first
- 17.9 LimitRange and ResourceQuota: per-pod defaults vs namespace totals
- 17.11 nodeSelector and node affinity
- 17.13 Taints and tolerations: the node repels, the pod tolerates
- 17.18 Reading FailedScheduling, and PriorityClass with preemption
- 17.26 PodDisruptionBudgets and why they matter during a drain
Try kubectl in a real terminal Free, in your browser - a real Ubuntu terminal to try it in, with missions that check your work.