Skip to main content
RunBook Academy

KubernetesVI · kubectl for Administratorskubectl for administrators

kubectl plugins (krew) and shell completion

Intermediate⏱ ~14 minkubectlkrew

What you'll learn

  • Install and use kubectl plugins via krew
  • Identify the most-used production plugins (kubectx, kubens, kubectl-tree, kubectl-neat)
  • Configure shell completion for bash, zsh, and fish
  • Reason about plugin supply chain and security risks

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

kubectl is extensible: any executable named kubectl-<name> in $PATH is a plugin. This convention makes plugin distribution trivial — drop a binary, get a new subcommand — but it also means every plugin runs code on your workstation. This lesson covers the plugin manager (krew), the production plugins worth installing, and the supply-chain discipline that goes with them.

How plugins work

When you run kubectl foo bar baz, kubectl searches $PATH for executables named kubectl-foo. If it finds one, it runs the executable with the rest of the arguments appended:

$ kubectl foo bar baz
-> runs kubectl-foo with arguments: bar baz

The plugin receives the arguments after foo and is expected to talk to the cluster. To discover cluster information (current context, namespace, server URL), the plugin reads the environment variables that kubectl sets before invoking it:

  • KUBECTL_PLUGINS_CURRENT_NAMESPACE — current namespace
  • KUBECTL_PLUGINS_GLOBAL_FLAG_CONTEXT--context value
  • KUBECTL_PLUGINS_GLOBAL_FLAG_SERVER--server value
  • KUBECTL_PLUGINS_GLOBAL_FLAG_CLUSTER_NAME--cluster value

A well-behaved plugin respects these flags and passes them to its own kubectl invocations. A misbehaving plugin ignores them and hits the wrong cluster — a common source of multi-cluster incidents.

# List all installed plugins
kubectl plugin list

# A plugin's location
which kubectl-foo

# Run a plugin's help
kubectl foo --help

krew — the plugin manager

krew is the de-facto plugin manager. It is a package manager for kubectl plugins, hosted by Kubernetes SIG CLI. Plugins are distributed as tarballs with a plugin manifest.

# Install krew (Linux/macOS)
(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install --help > /dev/null
)

# After install: ensure ~/.krew/bin is in $PATH
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

# Use krew to manage plugins
# Substitute the plugin you want:
PLUGIN=ctx

kubectl krew install "$PLUGIN"
kubectl krew upgrade                 # upgrade all plugins
kubectl krew search "$PLUGIN"
kubectl krew list
kubectl krew uninstall "$PLUGIN"
kubectl krew info "$PLUGIN"

krew stores plugins in ~/.krew/bin/. After installing krew, add this directory to $PATH so the plugin binaries are discoverable by kubectl.

The production plugin set

Six plugins cover most production needs:

kubectx and kubens — fast context and namespace switching with interactive fzf prompts:

kubectl krew install kubectx

kubectl ctx                                # pick a context (fzf)
kubectl ctx prod-eu-west-1                 # switch directly
kubectl ns                                 # pick a namespace (fzf)
kubectl ns team-a-prod                     # switch directly

kubectx/kubens add visual prompts to the kubeconfig that show the current context prominently in the terminal. This is the single biggest win for multi-cluster safety.

kubectl-tree — visualise object ownership trees:

kubectl krew install tree

kubectl tree deployment web                # Deployment -> ReplicaSet -> Pods
kubectl tree pod web-7c8                   # Pod <- ReplicaSet <- Deployment
kubectl tree service web                   # Service (no children)

The output is an ASCII tree showing the ownerReferences chain. It is the right tool for “what does this Deployment actually own” — particularly for garbage-collection questions.

kubectl-neat — strip default fields from YAML for readable diffs:

kubectl krew install neat

kubectl get pod web-7c8 -o yaml | kubectl neat
kubectl neat diff -f deployment.yaml

kubectl neat removes server-defaulted fields (status, metadata.resourceVersion, managedFields, etc.) so diffs show only what the operator changed. The kubectl neat diff command wraps kubectl diff and is the right tool for reviewing a PR’s manifest changes.

kubectl-debug (from kubectl-debug project, not the built-in kubectl debug) — alternative debug tooling:

kubectl krew install debug

Less commonly used since kubectl debug was added natively.

stern — multi-pod log tailing:

kubectl krew install stern

stern -l app=web                          # tail all web pods
stern web-7c8 --container nginx           # specific pod
stern -n team-a-prod -l app=web --tail 50 # with flags

stern tails logs from multiple pods (and multiple containers) into one stream, with the pod name as a prefix. Far more useful than kubectl logs -l app=web -f for multi-replica triage.

kubectl-images — show images used across the cluster:

kubectl krew install images

kubectl images                            # all images across pods
kubectl images -A | sort                  # with namespaces
kubectl images --digests                  # with image digests

Production teams use this for image inventory: “where is this vulnerable image still deployed?”

Shell completion

kubectl completion makes the kubectl CLI discoverable from the shell:

# Bash
echo 'source <(kubectl completion bash)' >>~/.bashrc

# Zsh (oh-my-zsh has a kubectl plugin)
echo 'source <(kubectl completion zsh)' >>~/.zshrc

# Fish
kubectl completion fish | source

After installing completion, kubectl <TAB> lists subcommands, flags, and (with krew plugins) plugin names. With cobra-based plugins, completion also lists resource kinds.

For production workstations, enable completion for both kubectl and kubeconfig:

kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null

Plugin supply chain

The kubectl plugin model is, in supply-chain terms, equivalent to installing npm packages globally. The discipline:

  1. Pin plugin versions. kubectl krew install <plugin> installs the latest; pin in a dotfile repository with a version manifest:
    kubectl krew install kubectx --version v0.9.5
  2. Audit plugin updates. Subscribe to release notes; review before upgrading. Plugins run with your user privileges.
  3. Limit plugin scope. If the plugin reads $HOME/.kube/ config, it can read cluster credentials. Don’t install plugins that exfiltrate the kubeconfig.
  4. Run kubectl on a hardened jump host for high-security environments. The plugins run there, not on operator workstations.

Cross-course references

  • The Linux course part XXVI-Linux-SSH covers shell completion and SSH agent; kubectl completion is the cluster-level equivalent.
  • The Ansible course part XXVIII-Ansible-Plugins covers Ansible plugins; kubectl plugins follow the same distribution model (executable in $PATH).
  • The Docker course part XLIX-Docker-TLS covers TLS supply chain for image pulls; krew plugin supply chain is the same problem at the kubectl layer.

Quiz

Knowledge check · 4 questions

  1. Q1. How does kubectl discover plugins?

  2. Q2. krew plugins run as sandboxed processes that cannot read the user's kubeconfig or environment.

  3. Q3. An operator runs `kubectl ctx prod-eu-west-1` (kubectx) to switch context. They then run `kubectl delete deployment web -n team-a-prod` thinking they're in staging. Walk through how the plugin and the kubectl command interact, and what would have prevented this.

    Operator has current-context set to `staging-eu-west-1`. They want to switch to prod. They run `kubectl ctx` (kubectx interactive prompt). They type `p` and pick `prod-eu-west-1` from the list. The kubeconfig's current-context is now `prod-eu-west-1`. They then run `kubectl delete deployment web -n team-a-prod`. The Deployment is deleted in prod.

  4. Q4. Name two risks of installing kubectl plugins from krew, and one mitigation for each.

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • Install kubectx/kubens on every operator workstation. The visual context prompt is the single biggest win for multi-cluster safety.
  • Pin krew plugin versions in a versioned manifest. Treat plugin updates like library updates: review the diff before upgrading.
  • Enable shell completion for the operator’s shell. Most flag typos are caught by completion that would otherwise surface as silent command-line errors.
  • Use kubectl neat for diffs in code review. Diffs that include defaulted fields are unreadable and hide the actual change.
  • Audit plugins regularly. kubectl krew list is the inventory; review which plugins are installed and remove the unused ones.