Installing kubectl
Install and configure kubectl on macOS, Linux and Windows. Version skew rules, kubeconfig, shell completion, and the plugins worth having from day one.
kubectl is the command-line client for the Kubernetes API. It is a single binary with no dependencies, and it is the tool you will spend most of your Kubernetes time in.
Install
macOS
brew install kubectl
Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
For upgrades through your package manager, the official apt and yum repositories are the better route. Note they are versioned per minor release, so moving from 1.31 to 1.32 means updating the repository URL as well.
Windows
winget install -e --id Kubernetes.kubectl
choco install kubernetes-cli and scoop install kubectl work equally well.
Verify
kubectl version --client
Client Version: v1.31.2
Kustomize Version: v5.4.2
--client matters here, without it, kubectl version tries to contact a cluster and errors if none is configured.
Version skew
kubectl is supported one minor version either side of the cluster's API server. A v1.31 client works with 1.30, 1.31 and 1.32.
Outside that range things mostly work until they suddenly do not, usually a missing field on a newer resource, or a subcommand the older server does not recognise.
kubectl version # shows both client and server
If you work across clusters on different versions, asdf or kubectl version-switching tools let you keep several binaries and select per context. In practice, keeping the client at the newest cluster version you talk to covers most cases.
Connecting to a cluster
kubectl reads ~/.kube/config. Local cluster tools write it for you:
kind create cluster # writes and selects the context
minikube start # same
Cloud CLIs add a context on request:
aws eks update-kubeconfig --region us-east-1 --name production
gcloud container clusters get-credentials production --region us-central1
az aks get-credentials --resource-group rg --name production
kubectl config get-contexts
kubectl config current-context
kubectl cluster-info
kubectl cluster-info returning a URL means you are connected. connection refused usually means no cluster is running; Unauthorized means credentials, not connectivity.
Several config files can be merged with a colon-separated KUBECONFIG:
export KUBECONFIG=~/.kube/config:~/.kube/client-a.yaml
Set this up on day one
Shell completion
The highest-value five minutes you will spend. Completion covers resource names, not just subcommands, so you stop copying and pasting Pod names:
# bash
echo 'source <(kubectl completion bash)' >> ~/.bashrc
# zsh
echo 'source <(kubectl completion zsh)' >> ~/.zshrc
# fish
kubectl completion fish > ~/.config/fish/completions/kubectl.fish
The alias
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
The second line is what most people omit, and without it completion stops working through the alias.
Context in your prompt
Nothing in kubectl's output tells you which cluster you are on, and running a destructive command against the wrong one is the most common serious mistake people make. Show the context in your prompt, kube-ps1, or the Kubernetes segment in starship, powerlevel10k or oh-my-zsh:
[prod:payments] ~/work $
Plugins worth having
krew is kubectl's plugin manager:
kubectl krew install ctx ns tree neat
| Plugin | What it does |
|---|---|
ctx | Switch contexts with fuzzy matching |
ns | Switch namespaces the same way |
tree | Show resources as an ownership tree |
neat | Strip generated fields from get -o yaml output |
kubectl neat deserves particular mention: kubectl get pod x -o yaml includes managed fields, status and defaults, and neat strips it to something you can actually read or reuse as a manifest.
Outside krew, stern for multi-Pod log tailing and k9s for a terminal UI are both worth installing.
Commands to confirm it works
kubectl cluster-info
kubectl get nodes
kubectl get pods -A
kubectl api-resources # every type this cluster supports, with short names
kubectl explain pod.spec # field docs from the live API server
kubectl explain is the one to remember. It documents fields against the server you are connected to, so it always matches your version rather than whatever a search result described.
Quick reference
| Task | Command |
|---|---|
| Client version | kubectl version --client |
| Both versions | kubectl version |
| Am I connected | kubectl cluster-info |
| List contexts | kubectl config get-contexts |
| Switch cluster | kubectl config use-context <name> |
| Default namespace | kubectl config set-context --current --namespace=<ns> |
| Completion (zsh) | source <(kubectl completion zsh) |
| Install a plugin | kubectl krew install <name> |
| Field docs | kubectl explain <resource>.<field> |
| Supported types | kubectl api-resources |
Key takeaways
- kubectl is one binary and does not need to match the cluster exactly. One minor version either side.
kubectl version --clientavoids the error when no cluster is configured.- Local tools and cloud CLIs write your kubeconfig: you rarely edit it by hand.
- Install shell completion and the
kalias, including thecomplete -o default -F __start_kubectl kline. - Put the context in your prompt. It is the cheapest protection against the wrong-cluster mistake.
kubectl explainmatches your cluster's version, unlike documentation you find by searching.krew,sternandk9sare the additions most people end up installing anyway.
Check your understanding
A version check that errors
On a fresh machine with no cluster configured, kubectl version fails with a connection error. How do you check the installed version?
Completion that stops at the alias
A developer adds alias k=kubectl and sources kubectl completion. Completion works for kubectl but not for k. What is missing?
Frequently Asked Questions
How do I install kubectl?
Use your platform's package manager: brew install kubectl on macOS, winget install -e --id Kubernetes.kubectl on Windows, and either the official apt or yum repository or the release binary on Linux. It is a single static binary with no dependencies, so downloading it and placing it on your PATH works anywhere. Confirm with kubectl version --client.
Does kubectl need to match my cluster version?
Not exactly. kubectl is supported within one minor version either side of the API server, so a v1.31 client works with clusters running 1.30, 1.31 or 1.32. Beyond that, most things still work until a newer resource field or subcommand is missing, at which point failures look confusing. kubectl version shows both client and server so you can check the gap. If you manage clusters on different versions, keep the client at the newest version you talk to.
Why does kubectl version give a connection error?
Because it reports both the client and the server version by default, so it tries to reach a cluster. With no kubeconfig, or no cluster running, that fails. kubectl version --client reports only the local binary and contacts nothing. This trips up almost everyone immediately after installing, and does not indicate a problem with the installation.
How do I connect kubectl to my cluster?
Local tools handle it for you, kind create cluster and minikube start both write and select a context in ~/.kube/config. For cloud clusters, run the provider's command: aws eks update-kubeconfig, gcloud container clusters get-credentials, or az aks get-credentials. Verify with kubectl cluster-info, which prints the API server URL when connected. A connection refused means no cluster is reachable; Unauthorized means the credentials are the problem rather than the connection.
How do I enable kubectl autocompletion?
Source the completion script from your shell profile: echo 'source <(kubectl completion zsh)' >> ~/.zshrc for zsh, or the bash equivalent. It completes resource names as well as subcommands, so you stop copying and pasting Pod names. If you also alias k=kubectl, add complete -o default -F __start_kubectl k, without that line completion works for kubectl but not through the alias, which is the step most people miss.
What kubectl plugins are worth installing?
Install krew first, then ctx and ns for fast context and namespace switching, tree for viewing resource ownership hierarchies, and neat for stripping managed fields and status out of get -o yaml so the output is readable. Outside krew, stern handles multi-Pod log tailing far better than kubectl logs -l, and k9s gives you a terminal UI that makes browsing a cluster much quicker than repeated get and describe commands.