Ciao! Andrew è uno sviluppatore di Linode. Nel processo di costruzione di una soluzione Kubernetes gestita, ho scoperto e creato diversi trucchi che utilizzo per semplificare le attività quotidiane con Kubernetes. Ho voluto condividere questi cinque con voi e spero che li troviate utili come li ho trovati io.
1. Il trucco del meta-shell
Ho visto questo trucco per la prima volta nell'intervento di Olive Power sulla preparazione CKA alla KubeCon Europe di quest'anno.
kubectl <command> --help | grep kubectl
Ogni comando di kubectl contiene una serie di esempi nella sua guida e questo è un modo rapido per vederli tutti in una volta. Questi esempi possono dare idee su come combinare parametri e flag in modi utili che potrebbero non essere ovvi leggendo la documentazione.
Attualmente, il comando kubectl run restituisce il maggior numero di esempi: 18. Tuttavia, il comando che uso più spesso è kubectl get. Diamo un'occhiata a uno dei suoi esempi:
kubectl get pod test-pod -o custom-columns=CONTAINER:.spec.containers[0].name,IMAGE:.spec.containers[0].image
Questo comando trasforma l'output di kubectl get, fornendo solo la versione del contenitore distribuito per questo pod. Con alcune piccole modifiche, è possibile rendere l'output molto più utile. Si noti che vengono richiesti il nome e l'immagine solo per il primo contenitore (containers[0]). Utilizzando la sintassi JSONPath supportata da kubectl, è possibile elencare tutte le versioni di tutti i contenitori in tutti i pod.
kubectl get pod -o custom-columns=CONTAINER:.spec.containers[*].name,IMAGE:.spec.containers[*].image -A
Questo trucco può evitare di frugare nelle risorse dei singoli pod per trovare un'immagine canary o un errore di versione nel cluster. Con un alias di kgi (e il selettore dello spazio dei nomi -A rimosso), è possibile trovare la versione di kube-apiserver in esecuzione nel cluster. Vedere sotto:
$ kgi -n kube-system -l component=component=kube-apiserver
CONTAINER IMAGE
kube-apiserver k8s.gcr.io/kube-apiserver:v1.14.5
kube-apiserver k8s.gcr.io/kube-apiserver:v1.14.5
kube-apiserver k8s.gcr.io/kube-apiserver:v1.14.5
Il comando seguente stampa un elenco aggiornato di tutti gli esempi incorporati. Sceglietene uno con qualche flag che non avete mai visto prima e sperimentate!
for c in $(kubectl --help | egrep "^\s+([a-z-]+)" -o); do echo -e "$(kubectl $c --help | egrep '^\s+kubectl')"; done
2. Ottenere l'uso della memoria per spazio dei nomi
Alcuni di noi sanno che awk è molto più di awk { print $1 }. Di recente, ho approfondito e imparato le basi di questo linguaggio incredibilmente potente che ci è stato fornito da alcuni dei titani della storia di Unix. Ecco un esempio di un programma awk molto utile, ma abbastanza breve da poter essere chiamato "one-liner". Questo programma somma e stampa il numero di MiB di memoria utilizzati da tutti i pod in ogni spazio dei nomi e utilizza la funzione printf di awk per un output pulito, anche quando il cluster contiene nomi di spazi dei nomi lunghi. Considerate l'uso di awk quando avete bisogno di una visione aggregata dell'output di kubectl.
kubectl top pod -A --no-headers=true | awk '{a[$1] += $4} END {for (c in a) printf "%-35s %s\n", c, a[c]}'
3. Visualizzare i segreti in testo normale
Quando si sviluppa un'applicazione che si basa sui segreti, può essere complicato trovare un modo per convertire l'output di kubectl in base64. Forse si è scritta una pipeline di shell o un piccolo script per decodificarli. Ho visto alcune opzioni diverse con vari svantaggi: non supporta l'output multilinea, aggiunge o elimina le newline lungo il percorso o perde il contesto dei nomi dei campi. Con il plugin secret decode di Ashley Schuett per kubectl, è possibile visualizzare i segreti in forma leggibile all'interno dell'output di kubectl get ed evitare tutti questi problemi.
La documentazione del progetto raccomanda di usare curl per prelevare il binario da GitHub e aggiungerlo al nostro percorso. Poiché si tratta di una serie di dati sensibili, vi invito a compilarlo da sorgente e a esaminare prima il sorgente. Fortunatamente, questo plugin consiste in un singolo file sorgente ben formattato:
git clone git@github.com:ashleyschuett/kubernetes-secret-decode.git
cd kubernetes-secret-decode
GO111MODULE=off go build -o $GOPATH/bin/kubectl-ksd
Il nome del binario creato nell'ultimo passaggio deve iniziare con kubectl- perché sia riconosciuto come plugin. Assicuratevi che $GOPATH/bin sia presente nel vostro $PATH, quindi potete usarlo in questo modo:
kubectl ksd get secret -n <namespace-name> <secret-name> -o yaml
4. Registri recenti e precedenti
Se si dispone di un servizio che può raggiungere settimane o mesi di uptime, i log dei container possono raggiungere dimensioni tali da far produrre una quantità ridicola di output ai tipici comandi di log di kubectl. Si potrebbe avere l'impressione di stare mettendo alla prova i limiti della capacità del terminale di dipingere il testo, o di essere stupiti dalla quantità di traffico di rete sostenuta da ciò che dovrebbe essere leggibile dall'uomo. In questi casi, ci sono diversi modi per ridurre l'output e arrivare ai messaggi che si vogliono vedere.
Il primo è il --tail=N
che inizia a stampare le ultime N righe del file.
kubectl logs --tail=10 -f -n kube-system -l component=kube-apiserver
C'è anche --since=time
che accetta intervalli di tempo come 30s, 1h o 5m per riferirsi rispettivamente a un numero di secondi, ore o minuti.
kubectl logs --since=5m -f -n kube-system -l component=kube-apiserver
Un altro flag per i log su cui ho fatto affidamento è -p. Stampa i log dell'esecuzione precedente del contenitore; i log di un contenitore che è uscito. Questo avrebbe reso molto più facile i miei primi giorni con Kubernetes, quando cercavo di riavviare i pod e di "catturare" i loro log, con qualche rapida azione di mouse e tastiera, prima che si bloccassero di nuovo.
kubectl logs -p -n kube-system -l component=etcd
5. Risparmiare tempo nell'attesa
Quando si è tentati di scrivere un ciclo con un comando sleep, di solito c'è un modo migliore per farlo. Indipendentemente dall'intervallo scelto, è probabile che si perdano uno o più secondi. Se si tratta di un processo automatizzato, i secondi si accumulano. A questo serve il comando kubectl wait e il relativo pacchetto apimachinery. Questo comando consente di mettere in pausa gli script per il tempo specifico necessario affinché la condizione sia soddisfatta nel cluster. Si può anche usare per inviare messaggi di allarme su Slack nel momento in cui una nuova release arriva nel cluster. Divertitevi con questo comando.
Ecco alcuni esempi:
kubectl wait --for=condition=Available deployment/metrics-server
kubectl wait --for=condition=Initialized pod/csi-linode-controller-0
Le condizioni disponibili variano in base al tipo di risorsa e possono essere scoperte usando kubectl describe alla voce "Conditions:". Una data risorsa può avere molte condizioni diverse allo stesso tempo.
Trucchi bonus!
A volte si guarda l'output e si vorrebbe che venissero visualizzate alcune informazioni aggiuntive sulla rete o di altro tipo, giusto? Per aiutarvi, aggiungete -owide al comando. Questo funziona per quasi tutti i tipi di risorse e le colonne visualizzate possono essere personalizzate per le definizioni di risorse personalizzate (CRD). Esempi:
kubectl get pods -A -owide
kubectl get services -A -owide
Infine, se non l'avete ancora notato, è stato aggiunto -A come alias per il flag --all-namespaces
. Credo che questa funzione, da sola, abbia fatto risparmiare al mondo milioni di battute da quando è stata introdotta. Un altro grande risparmio di tempo è l'aggiunta di alias k=kubectl
alla vostra shell rc.
Questo post ha toccato principalmente le funzioni integrate di kubectl. Per un approfondimento ancora maggiore, esiste il libro open source kubectl, leggibile online. Si concentra sull'uso di Kustomize, uno strumento integrato che consente di organizzare e comporre le risorse Kubernetes. Lo consiglio vivamente, soprattutto se siete alla ricerca di framework per progetti Kubernetes con una superficie minimamente vulnerabile. Per una raccolta di altri comandi utili, date un'occhiata a Krew, il gestore di pacchetti ufficiale per i plugin di kubectl.
Commenti (2)
Great post Andrew, this is actually cool.
#2, getting memory usage based on namespace is a nice hack, on #3, i’d prefer to use rancher to get most of these information.
What do you think, have you tried rancher before?
Thanks : )
I have used Rancher before, in fact Linode has an official Rancher integration which you can read about here: https://www.linode.com/docs/kubernetes/how-to-deploy-kubernetes-on-linode-with-rancher-2-x/
I do like Rancher for managing access to a cluster, the fact that each user gets a ServiceAccount token proxied through the Rancher deployment is very cool.
For viewing secrets, I still use the technique in #3.