When managing multiple Kubernetes clusters, it’s common for each one to run a different kube-apiserver version. If those versions aren’t too far apart, a single kubectl client may work fine for most routine operations… but the Kubernetes documentation is explicit about it: to avoid unexpected issues, the minor version of kubectl shouldn’t differ from kube-apiserver by more than one.
In other words, using semantic versioning (MAJOR.MINOR.PATCH):
Given two versions,
X1.Y1.Z1 and X2.Y2.Z2 the following must hold:
X1 == X2 and |Y1 - Y2| <= 1
This is where asdf comes in handy: a general-purpose, plugin-based tool for managing multiple runtime versions. We’ll use it to keep several kubectl client versions available on the command line, and switch to the right one depending on the cluster we’re working with.
This post is based on the following components and versions:
- Ubuntu 22.04.3 LTS
- asdf 0.13.1
- kubectl 1.27.5
Installing the asdf tool
Here we assume Bash and Git. For a different combination of shell, operating system, or installation method, please refer to the full documentation.
First, make sure the required dependencies are installed:
1
sudo apt update && sudo apt install -y curl git jq
Then, clone the latest asdf release into the ~/.asdf directory:
1
2
ASDF_VERSION=$(curl -sL https://api.github.com/repos/asdf-vm/asdf/releases/latest | jq -r ".name")
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch $ASDF_VERSION
If you have attempted a previous installation, the
~/.asdfdirectory may already exist.
Add the asdf scripts to .bashrc to add the asdf binary to your PATH and enable autocompletion:
1
2
3
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
source ~/.bashrc
Finally, verify that asdf was installed successfully:
1
asdf version
Installing the asdf-kubectl plugin
Plugins enable asdf to support different tools. Each plugin has its own repository and includes executable scripts for managing that tool’s versions.
Get a full list of supported plugins and their repositories here.
In this case, add the kubectl plugin from its Git URL:
1
asdf plugin-add kubectl https://github.com/asdf-community/asdf-kubectl.git
Installing a specific kubectl version
asdf uses exact versions. To list all available versions of kubectl, run:
1
asdf list all `kubectl`
You can also list a subset of available versions by filtering by major version, or by major and minor version, respectively:
1 2 asdf list all kubectl 1 asdf list all kubectl 1.27The
latesthelper resolves to the current stable version number at the time of execution.
Now that the kubectl plugin is available, install any version of the tool:
1
asdf install kubectl 1.27.5
To list the installed
kubectlversions at any time, run:
1 asdf list kubectl
Setting a specific kubectl version
Set the current kubectl version with:
1
asdf global kubectl 1.27.5
When you set a tool version,
asdfwrites it to a.tool-versionsfile. The available scopes, from lowest to highest priority, are:
globalwrites the version to$HOME/.tool-versionslocalwrites the version to$PWD/.tool-versionsshellsets the version through an environment variable namedASDF_${TOOL}_VERSION
Check that the kubectl version matches the version currently selected by asdf:
1
2
asdf current
kubectl version --client --short
Finally, enable kubectl autocompletion and, optionally, define k as an alias:
1
2
3
4
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
source ~/.bashrc
Defining an alias command for each cluster
Now that the required kubectl client versions are installed, it is useful to associate each one with a cluster running the same version through an alias.
The following configuration assumes that there is one kubeconfig file per cluster:
1
2
3
4
5
6
7
8
9
cat << EOF >> ~/.bashrc
# Alias for DEV cluster
alias kdev='asdf global kubectl 1.27.5 && \
export KUBECONFIG=$HOME/.kube/config.dev && \
source <(kubectl completion bash) && \
kubectl config current-context && \
asdf current kubectl'
EOF
source ~/.bashrc
Invoking the kdev alias switches to that cluster and its corresponding kubectl version, then displays that information in the console:
1
2
3
kdev
# kubernetes-admin@dev
# kubectl 1.27.5 /home/manuel/.tool-version
Define a separate alias in ~/.bashrc for every cluster you want to manage with its own kubectl version.
Conclusion
This approach avoids being limited to the single kubectl client version usually provided by the distribution’s package manager, letting you work with the right version for each cluster without conflicts.
asdf is just as useful for managing multiple versions of runtime languages such as Go, Node, Ruby, or Python. Simply replace kubectl in the commands above with gvm, nvm, rbenv, or pyenv, respectively.



