Terminal speed: alias, dry-run, fast delete
Tricks that save minutes in the terminal: a short alias, variables for flags, and vim set up for YAML.
Why this matters
The most frequent word in a Kubernetes terminal is kubectl. You type it
hundreds of times a session, and it almost always comes with the same
flags. A few shell and editor settings save minutes on every task. On the
CKAD exam, where time is limited, those minutes decide the outcome.
In this lesson: the k alias, autocompletion, the do and now
variables, generating manifests instead of writing YAML by hand, and vim
settings that don't break indentation.
alias k
An alias swaps a short word for a longer command:
alias k=kubectl
k get pod
An alias lives until you close the terminal. To have it in every new
window, add the line to your shell's config file: ~/.bashrc for bash,
~/.zshrc for zsh. On macOS, the default terminal opens zsh, so
~/.bashrc won't be read there.
On the CKA and CKAD exams, the k alias and bash autocompletion are
already set up on every machine, as stated in the
exam tips.
Still worth checking first: k version --client.
Autocompletion
kubectl generates its own autocompletion script for your shell. You load it into the current shell, and Tab starts completing commands, object types, and even Pod names from the cluster.
The alias doesn't get autocompletion for free: bash knows the rule for the
name kubectl, but nothing about k. You add the rule for the alias as a
separate line. This is covered in the
kubectl Quick Reference.
bash (Linux, WSL2, bash 4 and newer):
source <(kubectl completion bash)
complete -o default -F __start_kubectl k
For full support in an interactive terminal you need the
bash-completion package (on Ubuntu and WSL2 it's usually already
installed).
bash on macOS is bash 3.2. There, source <(...) returns exit code 0 but
loads nothing, and Tab silently doesn't work. The approach from the
macOS instructions
works on any bash version:
source /dev/stdin <<<"$(kubectl completion bash)"
complete -o default -F __start_kubectl k
zsh (the default on macOS):
source <(kubectl completion zsh)
alias k=kubectl
compdef __start_kubectl k
If zsh says command not found: compdef, the zsh completion system isn't
enabled: add autoload -Uz compinit && compinit to ~/.zshrc before these
lines.
Check it: type k ge and hit Tab. It should complete to k get.
The do and now variables
Two shortcuts for the flags you type most often. The names do and now
come from the CKAD community, they're not a built-in kubectl feature.
They're plain environment variables holding a piece of the command line:
export do="--dry-run=client -o yaml"
export now="--force --grace-period=0"
The quotes are required. Without them, only the first flag ends up in the
variable, and export answers with the error
export: `-o': not a valid identifier.
$do: a manifest skeleton
--dry-run=client means "don't send this to the cluster, just assemble
the object." -o yaml prints the assembled object as YAML. Together they
turn an imperative command into a manifest generator:
k run web --image=busybox:1.36.1 $do -- sh -c 'sleep 3600' > /tmp/pod.yaml
No Pod shows up in the cluster, k get pod says No resources found.
Next you edit the file and apply it:
k apply -f /tmp/pod.yaml
$now: delete without waiting
A plain delete gives the process time to shut down. Kubernetes sends the
container SIGTERM and waits terminationGracePeriodSeconds, 30 seconds by
default, then finishes it off with SIGKILL. If the program ignores
SIGTERM, kubectl delete hangs for the full 30 seconds. That's what
happens, for example, with sleep run as a container's main process: it
doesn't catch SIGTERM, so kubectl delete waits out the full grace period
before SIGKILL finishes it off.
With $now the command returns right away:
k delete pod web $now
Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "web" force deleted from default namespace
That warning is worth reading. --force removes the object from the API
right away, while the container on the node is actually stopped later:
kubectl get pod can already answer NotFound while the process on the
node hasn't stopped yet.
While the process is alive, a replacement with the same name can start
right next to it. For a learning Pod that's harmless. For a database under
a StatefulSet, two copies running at once can corrupt data, which is why
production doesn't do this
(Forced Pod termination).
Generation instead of hand-written YAML
Writing a manifest from scratch is slow, and it's easy to get the indentation wrong. Almost every object is generated with a command first, then finished by hand:
k create deploy web --image=nginx:1.27.3-alpine --replicas=3 $do > /tmp/deploy.yaml
k create cm app --from-literal=KEY=val $do > /tmp/cm.yaml
k create service clusterip web --tcp=80:80 $do > /tmp/svc.yaml
Not every generator works the same way. k create deploy, k create cm
and k create service assemble the object on your machine and work even
without a cluster available. But k expose deploy web --port=80 $do reads
the Deployment from the cluster: if it doesn't exist yet, you get Error from server (NotFound): deployments.apps "web" not found. Apply the
Deployment first, then expose. k run ... $do also talks to the API
server, and fails with a connection error without a cluster.
When you forget a field's structure, the built-in documentation helps.
kubectl pulls it from the cluster:
k explain pod.spec.containers
k explain deploy.spec --recursive shows the whole field tree at once.
It's worth treating the generated file as the source of truth. k diff -f file compares it against what's currently in the cluster, and stays
silent if there's no difference.
vim for YAML
In YAML, indentation carries meaning, and tabs are forbidden. If your
editor inserts tabs or throws off the indent, the manifest won't pass
validation. A minimal ~/.vimrc for YAML:
set expandtab
set shiftwidth=2
set tabstop=2
expandtab turns a tab into spaces. shiftwidth=2 and tabstop=2 set the
indent to 2 spaces: that's the standard width for Kubernetes manifests, and
all the documentation is written with it.
Common mistakes
export do=--dry-run=client -o yamlwithout quotes. Only--dry-run=clientends up indo, and YAML doesn't get printed.- The alias is there, but the
completeline (orcompdefin zsh) got forgotten.kubectlcompletes on Tab,kdoesn't. - Settings added to
~/.bashrc, but the terminal runs zsh. A new window doesn't see them. - On macOS,
source <(kubectl completion bash)in bash 3.2. No error, but no completion either. k expose deploy ... $dobefore the Deployment is in the cluster.- Using
$nowout of habit on live Pods with data.
What you'll need for the tasks
alias,complete -o default -F __start_kubectl k, and a way to loadkubectl completion bashthat works on your bash version.export do="--dry-run=client -o yaml"andexport now="--force --grace-period=0".- The generators
k create configmap,k create deploy,k create service clusteripwith$do, hand-editing the YAML,k apply -fandk diff -f. - From earlier lessons in the module: namespace and the
-nflag, labels and selectors,k get --show-labels,k describe.
Homework
Practice the theory on your own cluster: 1 step with a check. Set up the cluster with the Kubernetes locally track, the tasks live in the k8s-practice repository.
./run.sh start k8s-speed-kubectl # set up the starting state
./run.sh verify k8s-speed-kubectl # check the current step
Done reading?
Mark the lesson as read to move your track progress forward.
Lesson marked as done.
Go through it with an AI agent
The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.
Tell the agent: use MCP izi, give me lesson k8s-basics/speed-kubectl
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress