Home Managing different versions of Kubernetes clusters with asdf
Post
Cancel

Managing different versions of Kubernetes clusters with asdf

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 ~/.asdf directory 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.27

The latest helper 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 kubectl at 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-versions file. The scopes of an installation can be (from lowest to highest priority):

  • global writes the version to $HOME/.tool-versions
  • local writes the version to $PWD/.tool-versions
  • shell set the version to an environment variable named ASDF_${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!

This post is licensed under CC BY 4.0 by the author.

Bootstrapping Kubernetes clusters with kubeadm

Load balancers in a nutshell

Comments powered by Disqus.