My two options to make life easier when working with kubectl, without any 3rd party tools installation (which I don’t like).
Switching context
AFAIK, lot of tutorials recommend kubectx for this purpose.
Let’s be honest, this can be done using more native way (with
some limitations ofc). I prefer simple alias here:
alias kct='kubectl config use-context'
Plus: autcompletion works out of the box here.
Minus: There is not option kct - to switch back to previous context.
But honestly, I don’t remember a single time when I needed it.
Switching namespaces
Just as before, there is kubens present for this purpose.
And more native way to do so is following shell function:
kns() {
kubectl config set-context --current=true --namespace=$1
}
This time, the shell function instead of an alias is needed
to handle the parameter $1 which accepts the namespace name.
Just use kns <namespace> and you are in that namespace.
Plus: native solution. Minuses:
- No
kns -to switch back to previous namespace. - No autocompletion this time.
Just as before first minus is a minor for me, but the second one is real pain. So let’s fix it.
Autocompletion
Little bit of theory: how does autcompletion works in shell?
By default - it’s a function or script that is meant to return the variable called COMPREPLY which is an array of values that you can choose from.
Simple, right?
So we need a function that returns the list of namespaces. Kubectl provides it:
kubectl get namespaces
But this func return a table, with more infos that we actually
need. I could use awk for example, to prepare the list, but again,
there is a more native way for it.
kubectl implements possibility to customize the output format.
One important thing here, is that it uses the golang templating to do so.
The interesting value address is the same as within the Kubernetes object manifest, which looks like this for namespace:
apiVersion: v1
kind: Namespace
metadata:
name: <nazwa>
According to this, the address we are interested in is: .metadata.name.
Let’s combine it with disabling the headers and we have a ready command:
kubectl get namespaces --no-headers -o=custom-columns=NAME:.metadata.name
It returns the list of namespaces, just as the autocompletion requires.
Let’s pack it into a function that generates COMPREPLY array.
I’ve also added a timeout, so the shell won’t be blocked if the cluster
is not responding:
_kns_autocomplete() {
COMPREPLY=($(kubectl --request-timeout='3s' get namespaces --no-headers -o=custom-columns=NAME:.metadata.name))
}
Function name can be anything, but it’s a common practice to start the name of autocompletion functions with an underscore (which also prevents accidental calling of this function).
Last step: Shell must know that _kns_autocomplete generates completions for the kns function. For this purpose, I use the complete command:
complete -F _kns_autocomplete kns
Flag -F means autocompletion function, and the last parameter is the name of the function for which we assign autocompletion.
Final code:
_kns_autocomplete() {
COMPREPLY=($(kubectl --request-timeout='3s' get namespaces --no-headers -o=custom-columns=NAME:.metadata.name))
}
kns() {
kubectl config set-context --current=true --namespace=$1
}
complete -F _kns_autocomplete kns
Function are defined in the file that is executed at shell startup, e.g. .zshrc or any other file that is called by it.
To keep things tidy, I keep it in .aliases file.
Summary
I’d say this is a prefect example of small imprevements in workflow without doing bigger mess by installing 3rd party tools. And I’m aware that it’s not a 100% equal solution, but it works for me.
Try it out yourself. Doing improvements like this is really satisfying :) And you can always learn something new.