Małe usprawnienia pt. 2 - kubectl i autouzupełnianie
Kubectl Usprawnienia

Małe usprawnienia pt. 2 - kubectl i autouzupełnianie

Moje dwa sposoby na ułatwienie sobie życia przy pracy z kubectl, bez potrzeby instalowania kolejnych narzędzi.

Przełączanie kontekstu

Z tego co widziałem, bardzo dużo ludzi poleca do tego celu kubectx. Ponieważ nie jestem fanem instalowania kolejnych narzędzi gdy nie ma potrzeby (zwłaszcza do tak pierdołowatego problemu), zrobiłem to po swojemu przez krótki alias:

alias kct='kubectl config use-context'

Dużym plusem, jest to że z miejsca działa tutaj autouzupełnianie shellowe, wiec nie trzeba pamiętać dokładnej nazwy każdego kontekstu.

Minus?

Brakuje opcji kct - czyli możliwości przełączenia się do poprzedniego wybranego kontekstu. Ale szczerze? Nie przypominam sobie żebym tego kiedykolwiek potrzebował.

Przełączanie namespace’ów

Podobnie jak wcześniej, często pojawia się tutaj kubens. Ale skoro można zrobić to prościej, to po go instalować? Ja proponuję tak, tym razem funckję shellową:

kns() {
    kubectl config set-context --current=true --namespace=$1
}

Funkcja shellowa jest potrzebna, żeby obsłużyć parametr $1, czyli nazwę namespace’u. Wystarczy wpisać kns <namespace> i już jesteśmy w tym namespace’ie.

Tym razem, minusy są dwa: brakuje kns - oraz brakuje autouzuepłniania.

O ile z pierwszym ja problemu nie miałem, o tyle to drugie już się bardzo przydaje. Więc warto by je dorobić samemu.

Autouzuepłnianie

Najpierw chwila teorii: jak właściwie działa autouzuepłnianie w shellu?

Jest to nic innego jak skrypt lub funkcja, która jes wywoływna, po dwukrotnym wciśnieci klawisza TAB. Shell oczekuje, że skrypt lub funkcja zwrócą tablicę wartości o nazwie COMPREPLY, z której następnie można będzie wybrać odpowiednią wartość.

Proste, prawda?

Więc potrzebujemy funkcję która zwróci listę namespace’ów. Kubectl udostępnia taką opcję, więc skorzystajmy z niej:

kubectl get namespaces

Funkcja owszem zwraca wszystkie namespace’y, ale w formie tabeli, a nie listy. I oczywiście, można by było odfiltrować potrzebne wartości przez np. awk, ale mam inną propozycję.

Kubectl pozwala na wybranie formatu wyjścia jako tzw. custom column. Posiłkując się --help, wyczytałem, że należy tu przekazać adres wartości, zgodny ze strukturą manifestu obiektu w k8s.

Dla namespace’a wygląda on tak:

apiVersion: v1
kind: Namespace
metadata:
  name: <nazwa>

Więc wychodzi, że adres który nas interesuje to: .metadata.name. Dodajmy do tego wyłączenie nagłówków i mamy gotową komendę:

kubectl get namespaces --no-headers -o=custom-columns=NAME:.metadata.name

Polecenie zwraca listę NS’ów, dokładnie tak jak oczekuje tego mechanizm autozupełniania. Opakujmy to w funkcję zwracającą tablicę COMPREPLY, przy przy okazji dodając jeszcze timeout, żeby shell nie został przyblokowany gdyby klaster nie odpowiadał:

_kns_autocomplete() {
    COMPREPLY=($(kubectl --request-timeout='3s' get namespaces --no-headers -o=custom-columns=NAME:.metadata.name))
}

Nazwa funkcji jest generalnie dowolna, ale przyjeło się, że funkcje uzuepłniające zaczyna się podkreślnikiem (przy okazju utrudnia ich przypadkowe wywołanie).

Ostatni krok: Musimy powiedzieć powłoce, że _kns_autocomplete generuje uzupełnienia dla funkcji kns. Do tego celu używam polecenia complete:

complete -F _kns_autocomplete kns

Flaga -F oznacza funkcję autozupełniania, a ostatni parametr to nazwa funkcji do której przypisujemy autouzupełnienie.

Ostateczny kod:

_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

Funkcje oczywiście definiuję w pliku uruchamianym przy starcie powłoki, np. .zshrc lub jakimkolwiek innym który jest przez niego wtedy wywoływany.

Dla zachowania porządku, u mnie jest to .aliases.

Podsumowanie

Powiedziałbym, że to idealny przykład małego usprawnienia pracy. A przy okazji nie robię dodatkowego bałaganu instalując więcej narzędzi, niż faktycznie potrzebuję.

Spróbuj sam :) Dla mnie takie ciągłe usprawnienie pracy jest bardzo satysfakcjonujące. I zawsze można się czegoś nowego nauczyć.