When we are managing different Kubernetes clusters, it is usual that not all of them are running under the same kube-apiserver version number. Usually between versions that are not too far apart and for the most ordinary operations we may find that having the same version of the kubectl client for all of them just works…
However, in the Kubernetes documentation it is explicitly stated that in order to avoid unforeseen problems, the distance between the minor version of kubectl and the kube-apiserver version should not be greater than one version.
In other words, and taking into account semantic versioning with MAJOR.MINOR.PATCH we have that:
Given two versions,
X1.Y1.Z1 and X2.Y2.Z2 it follows that,
X1 == X2 and |Y1 - Y2| <= 1
In scenarios like this, the asdf tool comes to the rescue. Actually asdf is a generalist tool, based on plugins and able to manage different versions of runtimes. We are going to use it to have different versions of the kubectl client available on our command line and use each of them with the cluster of the same version.
We are going to work in this post 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 are assuming Bash and Git, for a different combination of shell, operative system and installation method please refer to the full documentation.
First of all, let’s ensure that required dependencies for future packages are installed:
1
sudo apt update && sudo apt install -y curl git jq
Then, download the latest asdf version release to 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
Note that if you have tried previous installations the
~/.asdfdirectory may already exist.
Add asdf scripts to .bashrc in order to add the asdf binary to the PATH and enable autocompletion:
1
2
3
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
source ~/.bashrc
Finally check that asdf has been successfully installed:
1
asdf version
Installing the asdf-kubectl plugin
Plugins are how asdf knows to handle different tools and each plugin is hosted in its own repository with some executable scripts to support versioning such tool.
Get a full list of sopported plugins and their repositories here.
In our case, you can add the kubectl plugin via its Git URL:
1
asdf plugin-add kubectl https://github.com/asdf-community/asdf-kubectl.git
Installing a specific kubectl version
asdf enforces exact versions, if you need it, print all available versions for the kubectl tool.
1
asdf list all `kubectl`
Optionally you can also get a subset of available versions by filtering by major, or major and minor version, respectively:
1 2 asdf list all kubectl 1 asdf list all kubectl 1.27The
latesthelper is available to resolve to the actual stable version number at the time of execution.
So now that we have a plugin for kubectl, we can install an arbitrary version of the tool:
1
asdf install kubectl 1.27.5
To find out the versions installed for
kubectlat any time type:
1 asdf list kubectl
Setting a specific kubectl version
It’s the moment to set the current kubectl version to use by:
1
asdf global kubectl 1.27.5
When we set the version of a tool, we add it to the
.tool-versionsfile. The scopes of an installation can be (from lowest to highest priority):
globalwrites the version to$HOME/.tool-versionslocalwrites the version to$PWD/.tool-versionsshellset the version to an environment variable namedASDF_${TOOL}_VERSION
Check that kubectl version actually matches the current set version of asdf:
1
2
asdf current
kubectl version --client --short
Last but not least 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 we have installed the necessary versions of the kubectl client, it is a good idea to associate each one with the cluster of the same version via an alias command.
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
In this way, the invocation of the kdev alias will transparently perform for us the context switch to such cluster and its corresponding kubectl version, displaying these info through the console:
1
2
3
kdev
# kubernetes-admin@dev
# kubectl 1.27.5 /home/manuel/.tool-version
Do not forget to define in ~/.bashrc a different alias command for each cluster you want to manage with its specific kubectl version.
Summary
This tool helps us to save the fact of having only one version of the kubectl client tool on our command line (usually offered by the distribution’s package manager).
If you liked the asdf tool, you should know that asdf is equally useful to have several versions of runtime languages like (among many other) Go, Node, Ruby or Python… just replace kubectl in the commands I have shown you above with gvm, nvm, rbenv or pyenv respectively, and enjoy!

Comments powered by Disqus.