Kubernetes è uno strumento open-source fondamentale nella orchestrazione dei container. Kubernetes aiuta a orchestrare e gestire cluster su scala in vari ambienti cloud o persino su server on-premise. Un cluster è un insieme di host destinati all'esecuzione di applicazioni e servizi containerizzati. Un cluster ha bisogno di un minimo di due nodi per funzionare – un nodo master e un nodo worker. È possibile scalare l'infrastruttura Kubernetes aggiungendo altri nodi worker. Un nodo master e i suoi nodi worker devono essere in grado di comunicare su una rete affinché l'infrastruttura funzioni. Per una panoramica delle funzionalità più importanti di Kubernetes, segui il nostro tutorial su Conoscere Kubernetes.
In questo tutorial, ti mostreremo diversi strumenti e tecniche per aiutare con l'ispezione e la risoluzione dei problemi del networking di Kubernetes.
Prerequisiti
-
Per seguire questo tutorial, dovresti avere un cluster Kubernetes. Abbiamo un tutorial che spiega Come installare e utilizzare Kubernetes su Ubuntu 20.04 che può guidarti nella configurazione di un cluster di base per la dimostrazione.
-
Dovresti anche avere kubectl installato localmente. A seconda del tuo ambiente locale, segui la documentazione ufficiale su installazione degli strumenti Kubernetes. Il kubectl dovrebbe essere configurato per connettersi al tuo cluster. Lo spiegheremo più dettagliatamente nella sezione seguente.
Eseguiremo diversi comandi sia localmente che sul nodo Kubernetes. Cominciamo!
Configurazione di kubectl locale per la connessione a un cluster Kubernetes remoto
Iniziamo installando kubectl. Il nostro ambiente locale esegue Ubuntu, segui questo link se utilizzi un ambiente locale diverso. Per installare gli strumenti kubectl su un ambiente locale Ubuntu/Debian con il gestore di pacchetti apt, esegui i seguenti comandi per aggiornare il repository apt e installare i pacchetti necessari:
|
1 2 |
sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl |
Successivamente, esegui il seguente comando per scaricare la chiave di firma pubblica di Google Cloud:
|
1 |
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg |
Quindi, aggiungi il repository apt di Kubernetes:
|
1 |
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list |
Dopodiché, aggiorna l'indice apt e installa kubectl con il seguente comando:
|
1 2 |
sudo apt-get update sudo apt-get install -y kubectl |
Quindi, verifica che kubectl sia installato controllando la versione con il seguente comando:
|
1 |
kubectl version |
Ecco l'output se hai appena installato kubectl localmente:

Nello screenshot qui sopra, kubectl sta cercando di connettersi al cluster Kubernetes locale. Tuttavia, non riesce perché non abbiamo ancora un cluster Kubernetes in esecuzione sulla nostra macchina locale.
Per connetterti al cluster Kubernetes remoto, dovrai prima scaricare le credenziali di Kubernetes dal cluster remoto. Ecco un comando per copiare le credenziali dal nodo master:
|
1 |
scp -r hackins@178.22.66.253:/home/hackins/.kube . |
Sostituisci le parti evidenziate con il tuo nome utente ssh e l'IP pubblico del nodo master. Una volta completato il download delle credenziali, copiale nella tua directory home:
|
1 |
cp -r .kube $HOME/ |
Questo è tutto. Il tuo kubectl locale dovrebbe essere in grado di connettersi e inviare comandi al tuo cluster Kubernetes remoto. Per confermare che il tuo kubectl locale sia connesso al cluster remoto, controlla nuovamente con il comando version:
|
1 |
kubectl version --output='json' |
Ecco l'output, che mostra una connessione riuscita:

Opzionalmente, puoi eseguire il comando get nodes in questo modo:

Ottenere il Cluster IP di un Pod
Puoi ottenere il Cluster IP di un Pod eseguendo il comando kubectl get pod sulla tua macchina locale. Per elencare più informazioni come il nodo che ospita il pod e il cluster IP del pod, aggiungi il flag -o wide al comando:
|
1 |
kubectl get pod -o wide |
Ecco un output dal nostro cluster Kubernetes. Nel tutorial dei prerequisiti avevamo creato un deployment del server web Nginx, come puoi vedere:

La colonna IP mostra l'indirizzo IP interno dei singoli pod. Se il pod che stai cercando non appare nell'elenco, potresti trovarti in un namespace diverso. Puoi impartire il seguente comando per elencare i pod in tutti i namespaces:
|
1 |
kubectl get pod -o wide --all-namespaces |
Ottenere l'indirizzo IP di un Servizio
Puoi anche ottenere l'indirizzo IP di un Servizio sul tuo cluster. Aggiungendo il flag --all-namespaces , ottieni tutti i servizi in esecuzione sul cluster:
|
1 |
kubectl get service --all-namespaces |
L'output del comando sopra è il seguente. L'IP del Servizio si trova nella colonna cluster-ip :

Ottenere e accedere ai Network Namespace dei Pod
Ogni pod Kubernetes ha un network namespace assegnato. I network namespace, chiamati anche netns, sono librerie di rete native in Linux che forniscono isolamento tra i dispositivi di rete.
Per verificare la risoluzione DNS o la connettività di rete generale, puoi eseguire comandi all'interno del network namespace di un pod. Per fare ciò, inizia cercando l'ID di processo di uno dei container in un pod. Puoi farlo facilmente in Docker utilizzando comandi specifici di Docker. Il primo comando elenca i container in esecuzione su un nodo. Accedi a uno dei tuoi nodi worker ed esegui il comando seguente:
|
1 |
docker ps |

Nell'output, siamo interessati alla colonna container ID o Names. Nota il container Nginx che abbiamo distribuito nel tutorial dei prerequisiti How to Install and Use Kubernetes on Ubuntu 20.04.
Successivamente, copia l'ID o il nome del container poiché lo useremo nel comando successivo per trovare l'ID del processo:
|
1 |
docker inspect --format '{{ .State.Pid }}' container-id-o-name |
Sostituisci la parte evidenziata con il valore copiato dal comando precedente. Di seguito è riportato l'output che abbiamo ottenuto, che è l'ID del processo:

Ora che abbiamo un ID di processo, possiamo usarlo per eseguire il comando nsenter all'interno del network namespace del processo:
|
1 |
sudo nsenter -t container-pid -n ip addr |
Sostituisci la parte evidenziata con l'ID del processo ottenuto nel comando precedente. Quindi, al posto di ip addr, puoi inserire qualsiasi comando che desideri eseguire all'interno del network namespace del pod. Puoi anche eseguirlo con sudo nel caso in cui si verifichi un errore di autorizzazione negata.
Il comando nsenter ti consente di eseguire una gamma più ampia di comandi disponibili su un nodo rispetto all'uso di docker exec che ti limita solo ai comandi installati all'interno del container.
Recuperare l'interfaccia Ethernet virtuale di un Pod
Un network namespace su un pod comunica con il netns root del nodo attraverso un canale ethernet virtuale. Dal lato del nodo, questo canale appare come un dispositivo il cui nome inizia con veth e termina con un identificatore univoco, come veth742f721 o veth90. Mentre all'interno del pod il canale si identifica come eth0.
Potresti voler sapere quale dispositivo veth è associato a quale pod. Puoi iniziare elencando tutti i dispositivi di rete sul nodo, quindi elencare tutti i dispositivi nella rete del pod. Per identificare quale dispositivo veth è associato a un particolare pod, puoi correlare i numeri dei dispositivi tra i due elenchi.
Usa il comando nsenter per eseguire il comando ip addr nel network namespace del pod. Dovrai conoscere uno degli ID di processo del container. Per questo, fai riferimento alla sezione precedente su Ottenere e accedere ai Network Namespace dei Pod.
Successivamente, esegui il seguente comando sul terminale del tuo nodo worker, sostituendo la parte evidenziata in modo appropriato:
|
1 |
sudo nsenter -t container-pid -n ip addr |
Il comando restituisce un elenco delle interfacce del pod:

Nota i if7 caratteri dopo eth0@ nell'output sopra. Questo significa che l' eth0 è accoppiato con la settima interfaccia del nodo. Successivamente, elenca le interfacce all'interno del namespace predefinito del nodo eseguendo il comando ip addr comando:
|
1 |
ip addr |
Il comando elenca le interfacce come mostrato di seguito:

Nell'output, la settima interfaccia è veth254b50e6@if3 – la pipe ethernet virtuale accoppiata con il pod su cui stiamo effettuando il test.
Revisione delle regole di Iptables
Puoi eseguire il comando iptables-save per elencare tutte le iptables su un nodo:
|
1 |
iptables-save |
L'output del comando può essere lungo, quindi puoi salvarlo in un file per un'ispezione successiva:
|
1 |
iptables-save > iptables.txt |
Puoi anche usare less per impaginare l'output:
|
1 |
iptables-save | less |
Poiché siamo interessati solo alle regole NAT di Kubernetes, aggiungi il flag -L per specificare il target corretto:
|
1 |
sudo iptables -t nat -L KUBE-SERVICES |
Ecco l'output:

Ispezione dei dettagli IPVS
Kube-proxy è un proxy di rete in esecuzione su ciascun nodo del cluster Kubernetes. Può essere utilizzato per configurare IPVS per gestire la traduzione degli IP dei Service virtuali in IP dei pod. Per elencare la tabella di traduzione degli IP, puoi utilizzare il comando ipvsadm . Innanzitutto, devi installarlo sul tuo nodo:
|
1 |
sudo apt install ipvsadm |
Ora puoi eseguire il seguente comando:
|
1 |
sudo ipvsadm -Ln |
Per mostrare un singolo IP di un Service, aggiungi il flag -t , specificando l'indirizzo IP desiderato:
|
1 |
ipvsadm -Ln -t 10.244.1.255 |
Interrogazione del DNS del cluster
Ci sono diversi modi che puoi seguire per eseguire il debug della risoluzione DNS del tuo cluster. La documentazione ufficiale descrive un modo che consiste nel distribuire un container di debug con tutti gli strumenti necessari, per poi utilizzare kubectl per eseguire nslookup.
In alternativa, puoi interrogare il DNS utilizzando i comandi dig e nsenter direttamente dal nodo stesso. Innanzitutto, dovrai installare dig sul tuo nodo master. Per Ubuntu, installalo con il comando apt comando:
|
1 |
sudo apt install dnsutils |

Torna al terminale sulla tua macchina locale ed esegui il comando seguente per trovare l'IP del cluster del servizio kube-dns :
|
1 |
kubectl get service -n kube-system kube-dns |
Il comando restituisce:

La colonna cluster-ip contiene il valore di cui abbiamo bisogno. Ora possiamo usare nsenter per eseguire dig nel namespace del container. Tuttavia, avrai bisogno dell'ID di processo del container per accedere al suo namespace. Consulta la sezione Ottenere e accedere ai namespace di rete dei pod sopra per indicazioni.
Una volta ottenuto l' container-id, esegui il seguente comando sul tuo nodo master:
|
1 |
sudo nsenter -t 27168 -n dig kubernetes.default.svc.cluster.local @10.96.0.10 |
Il comando dig accetta l'IP del servizio DNS del cluster ( @10.96.0.10) e cerca il nome di dominio completo del Service service-name.namespace.svc.cluster.local:

Per informazioni su come trovare i nomi dei servizi e i namespace, dai un'occhiata alla sezione Ottenere l'indirizzo IP di un Service.
Revisione del tracciamento delle connessioni Conntrack
Puoi utilizzare il comando conntrack per visualizzare tutte le connessioni attualmente tracciate:
|
1 |
sudo conntrack -L |
Restituisce un output simile allo screenshot:

Aggiungi il flag -E per monitorare continuamente le connessioni in entrata:
|
1 |
sudo conntrack -E |
Per visualizzare le connessioni tracciate verso un particolare indirizzo di destinazione, aggiungi il flag -d e specifica l'indirizzo di destinazione:
|
1 |
sudo conntrack -L -d 80.45.6.4 |
A volte la tabella di tracciamento delle connessioni si riempie, con la conseguente interruzione delle nuove connessioni. Questo causa problemi che impediscono ai nodi di stabilire connessioni affidabili. Se ciò accade, nei log di sistema verranno visualizzati messaggi come il seguente, nella posizione /var/log/syslog:
|
1 |
Mar 07 19:12:11 worker-105 kernel: nf_conntrack: tabella piena, scarto pacchetto. |
Esiste un'impostazione di sistema per il numero massimo di connessioni da tracciare. Utilizza il seguente comando per elencare il valore corrente:
|
1 |
sysctl net.netfilter.nf_conntrack_max |
Produce il seguente output:

È possibile modificare il valore utilizzando il -w flag:
|
1 |
sudo sysctl -w net.netfilter.nf_conntrack_max=231074 |
Potresti voler modificare il tuo /etc/sysctl.conf file per rendere il valore permanente e garantire che persista dopo i riavvii. Apri il file con nano:
|
1 |
sudo nano /etc/sysctl.conf |
Successivamente, modifica il valore se la riga esiste o aggiungi la riga alla fine del file, specificando il nuovo valore:
|
1 |
net.netfilter.nf_conntrack_max=231074 |
Conclusione
Quando si distribuiscono più servizi containerizzati, si trarrà grande vantaggio da Kubernetes poiché offre un punto di gestione centrale. Per garantire la connettività tra i vari pod Kubernetes, abbiamo mostrato alcuni comandi di ispezione della rete che è possibile utilizzare per risolvere eventuali problemi relativi all'infrastruttura Kubernetes.
Per saperne di più su Kubernetes, sui suoi vantaggi, sulla configurazione e sulla distribuzione di applicazioni su Kubernetes, dai un'occhiata ai nostri vari tutorial su Kubernetes.
Buon computing!
Commenti
Ancora nessun commento. Scrivi il primo.