Einführung
Kubernetes ist ein Container-Orchestrierungssystem, das containerisierte Anwendungen in einem Cluster von Serverknoten verwalten kann. Um die Netzwerkkonnektivität zwischen allen Containern in einem Cluster aufrechtzuerhalten, sind einige fortgeschrittene Netzwerktechniken erforderlich. In diesem Artikel werden einige Tools und Techniken zur Überprüfung dieser Netzwerkkonfiguration kurz beschrieben.
Diese Tools können hilfreich sein, wenn Sie Konnektivitätsprobleme beheben, Probleme mit dem Netzwerkdurchsatz untersuchen oder Kubernetes untersuchen, um zu erfahren, wie es funktioniert.
Wenn Sie mehr über Kubernetes im Allgemeinen erfahren möchten, werden in unserem LeitfadenAn Introduction to Kubernetes die Grundlagen behandelt. Für eine netzwerkspezifische Übersicht über Kubernetes lesen Sie bitteKubernetes Networking Under the Hood.
Anfangen
In diesem Lernprogramm wird davon ausgegangen, dass Sie einen Kubernetes-Cluster haben, in demkubectl
lokal installiert und für die Verbindung mit dem Cluster konfiguriert ist.
Die folgenden Abschnitte enthalten viele Befehle, die auf einem Kubernetes-Knoten ausgeführt werden sollen. Sie werden so aussehen:
echo 'this is a node command'
Befehle, die auf Ihrem lokalen Computer ausgeführt werden sollen, sehen folgendermaßen aus:
echo 'this is a local command'
[.note] #Note: Die meisten Befehle in diesem Lernprogramm müssen als Benutzer vonrootausgeführt werden. Wenn Sie stattdessen einen sudo-fähigen Benutzer auf Ihren Kubernetes-Knoten verwenden, fügen Sie bittesudo
hinzu, um die Befehle bei Bedarf auszuführen.
#
Ermitteln der Cluster-IP eines Pods
Verwenden Sie den Befehlkubectl get pod
auf Ihrem lokalen Computer mit der Option-o wide
, um die Cluster-IP-Adresse eines Kubernetes-Pods zu ermitteln. Diese Option listet weitere Informationen auf, einschließlich des Knotens, auf dem sich der Pod befindet, und der Cluster-IP des Pods.
kubectl get pod -o wide
OutputNAME READY STATUS RESTARTS AGE IP NODE
hello-world-5b446dd74b-7c7pk 1/1 Running 0 22m 10.244.18.4 node-one
hello-world-5b446dd74b-pxtzt 1/1 Running 0 22m 10.244.3.4 node-two
Die SpalteIP enthält die interne Cluster-IP-Adresse für jeden Pod.
Wenn der gesuchte Pod nicht angezeigt wird, vergewissern Sie sich, dass Sie sich im richtigen Namespace befinden. Sie können alle Pods in allen Namespaces auflisten, indem Sie das Flag--all-namespaces
hinzufügen.
Ermitteln der IP eines Dienstes
Wir können eine Service-IP auch mitkubectl
finden. In diesem Fall listen wir alle Services in allen Namespaces auf:
kubectl get service --all-namespaces
OutputNAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.32.0.1 443/TCP 6d
kube-system csi-attacher-doplugin ClusterIP 10.32.159.128 12345/TCP 6d
kube-system csi-provisioner-doplugin ClusterIP 10.32.61.61 12345/TCP 6d
kube-system kube-dns ClusterIP 10.32.0.10 53/UDP,53/TCP 6d
kube-system kubernetes-dashboard ClusterIP 10.32.226.209 443/TCP 6d
Die Dienst-IP finden Sie in der SpalteCLUSTER-IP.
Suchen und Eingeben von Pod-Netzwerk-Namespaces
Jedem Kubernetes-Pod wird ein eigener Netzwerk-Namespace zugewiesen. Netzwerknamespaces (oder Netns) sind ein Linux-Netzwerkprimitiv, das die Isolierung zwischen Netzwerkgeräten ermöglicht.
Es kann nützlich sein, Befehle aus den Netzen eines Pods auszuführen, um die DNS-Auflösung oder die allgemeine Netzwerkkonnektivität zu überprüfen. Dazu müssen wir zuerst die Prozess-ID eines der Container in einem Pod nachschlagen. Für Docker können wir dies mit einer Reihe von zwei Befehlen tun. Listen Sie zunächst die Container auf, die auf einem Knoten ausgeführt werden:
docker ps
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
173ee46a3926 gcr.io/google-samples/node-hello "/bin/sh -c 'node se…" 9 days ago Up 9 days k8s_hello-world_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
11ad51cb72df k8s.gcr.io/pause-amd64:3.1 "/pause" 9 days ago Up 9 days k8s_POD_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
. . .
Suchen Sie diecontainer ID odername aller Container in dem Pod, an dem Sie interessiert sind. In der obigen Ausgabe werden zwei Container angezeigt:
-
Der erste Container ist die App
hello-world
, die im Podhello-world
ausgeführt wird -
Der zweite ist einpause-Container, der im
hello-world
-Pod ausgeführt wird. Dieser Container dient ausschließlich zur Speicherung des Netzwerknamensbereichs des Pods
Um die Prozess-ID eines Containers abzurufen, notieren Sie sich die Container-ID oder den Namen und verwenden Sie sie im folgenden Befehldocker
:
docker inspect --format '{{ .State.Pid }}' container-id-or-name
Output14552
Eine Prozess-ID (oder PID) wird ausgegeben. Jetzt können wir das Programmnsenter
verwenden, um einen Befehl im Netzwerk-Namespace dieses Prozesses auszuführen:
nsenter -t your-container-pid -n ip addr
Stellen Sie sicher, dass Sie Ihre eigene PID verwenden, und ersetzen Sieip addr
durch den Befehl, den Sie im Netzwerk-Namespace des Pods ausführen möchten.
[.note] #Note: Ein Vorteil der Verwendung vonnsenter
zum Ausführen von Befehlen im Namespace eines Pods gegenüber der Verwendung vondocker exec
besteht darin, dass Sie Zugriff auf alle auf dem Befehl verfügbaren Befehle haben Knoten anstelle des normalerweise begrenzten Befehlssatzes, der in Containern installiert ist.
#
Suchen der virtuellen Ethernet-Schnittstelle eines Pods
Der Netzwerknamespace jedes Pods kommuniziert über eine virtuelle Ethernet-Pipe mit den Root-Netzen des Knotens. Auf der Knotenseite wird diese Pipe als Gerät angezeigt, das normalerweise mitveth
beginnt und mit einer eindeutigen Kennung endet, z. B.veth77f2275
oderveth01
. Innerhalb des Pods erscheint dieses Rohr alseth0
.
Es kann nützlich sein, zu korrelieren, welchesveth
-Gerät mit einem bestimmten Pod gekoppelt ist. Zu diesem Zweck werden alle Netzwerkgeräte auf dem Knoten und anschließend die Geräte im Netzwerknamespace des Pods aufgelistet. Wir können dann die Gerätenummern zwischen den beiden Listen korrelieren, um die Verbindung herzustellen.
Führen Sie zunächstip addr
im Netzwerk-Namespace des Pods mitnsenter
aus. Weitere Informationen hierzu finden Sie im vorherigen AbschnittFinding and Entering Pod Network Namespaces
:
nsenter -t your-container-pid -n ip addr
Output1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
10: eth0@if11: mtu 1450 qdisc noqueue state UP group default
link/ether 02:42:0a:f4:03:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.244.3.4/24 brd 10.244.3.255 scope global eth0
valid_lft forever preferred_lft forever
Der Befehl gibt eine Liste der Schnittstellen des Pods aus. Notieren Sie dieif11
-Zahl nacheth0@
in der Beispielausgabe. Dies bedeutet, dass dieeth0
dieses Pods mit der 11. Schnittstelle des Knotens verknüpft sind. Führen Sie nunip addr
im Standard-Namespace des Knotens aus, um dessen Schnittstellen aufzulisten:
ip addr
Output1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
. . .
7: veth77f2275@if6: mtu 1450 qdisc noqueue master docker0 state UP group default
link/ether 26:05:99:58:0d:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::2405:99ff:fe58:db9/64 scope link
valid_lft forever preferred_lft forever
9: vethd36cef3@if8: mtu 1450 qdisc noqueue master docker0 state UP group default
link/ether ae:05:21:a2:9a:2b brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::ac05:21ff:fea2:9a2b/64 scope link
valid_lft forever preferred_lft forever
11: veth4f7342d@if10: mtu 1450 qdisc noqueue master docker0 state UP group default
link/ether e6:4d:7b:6f:56:4c brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::e44d:7bff:fe6f:564c/64 scope link
valid_lft forever preferred_lft forever
Die 11. Schnittstelle istveth4f7342d
in dieser Beispielausgabe. Dies ist die virtuelle Ethernet-Pipe zu dem Pod, den wir untersuchen.
Conntrack Connection Tracking überprüfen
Vor Version 1.11 verwendete Kubernetes iptables NAT und das conntrack-Kernelmodul, um Verbindungen zu verfolgen. Verwenden Sie den Befehlconntrack
, um alle derzeit verfolgten Verbindungen aufzulisten:
conntrack -L
Verwenden Sie das Flag-E
, um kontinuierlich nach neuen Verbindungen zu suchen:
conntrack -E
Verwenden Sie das Flag-d
, um Verbindungen mit Verfolgung zu einer bestimmten Zieladresse aufzulisten:
conntrack -L -d 10.32.0.1
Wenn Ihre Knoten Probleme haben, zuverlässige Verbindungen zu Diensten herzustellen, ist möglicherweise Ihre Verbindungsverfolgungstabelle voll und es werden neue Verbindungen getrennt. In diesem Fall werden in Ihren Systemprotokollen möglicherweise Meldungen wie die folgenden angezeigt:
/var/log/syslog
Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet.
Es gibt eine Sysctl-Einstellung für die maximale Anzahl der zu verfolgenden Verbindungen. Sie können Ihren aktuellen Wert mit dem folgenden Befehl auflisten:
sysctl net.netfilter.nf_conntrack_max
Outputnet.netfilter.nf_conntrack_max = 131072
Verwenden Sie das Flag-w
, um einen neuen Wert festzulegen:
sysctl -w net.netfilter.nf_conntrack_max=198000
Um diese Einstellung dauerhaft zu machen, fügen Sie sie der Dateisysctl.conf
hinzu:
/etc/sysctl.conf
. . .
net.ipv4.netfilter.ip_conntrack_max = 198000
Regeln für die Überprüfung von Iptables
Vor Version 1.11 verwendete Kubernetes iptables NAT, um die virtuelle IP-Übersetzung und den Lastenausgleich für Service-IPs zu implementieren.
Verwenden Sie den Befehliptables-save
, um alle iptables-Regeln auf einem Knoten abzulegen:
iptables-save
Da die Ausgabe langwierig sein kann, möchten Sie möglicherweise zu einer Datei (iptables-save > output.txt
) oder einem Pager (iptables-save | less
) weiterleiten, um die Regeln einfacher überprüfen zu können.
Verwenden Sie den Befehliptables
und das Flag-L
, um nur die NAT-Regeln des Kubernetes-Dienstes aufzulisten und die richtige Kette anzugeben:
iptables -t nat -L KUBE-SERVICES
OutputChain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-SVC-TCOU7JCQXEZGVUNU udp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
KUBE-SVC-ERIFXISQEP7F7OF4 tcp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
KUBE-SVC-XGLOHA7QRQ3V22RZ tcp -- anywhere 10.32.226.209 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:https
. . .
Cluster-DNS abfragen
Eine Möglichkeit zum Debuggen Ihrer Cluster-DNS-Auflösung besteht darin, einen Debug-Container mit allen benötigten Tools bereitzustellen und dannkubectl
zu verwenden, umnslookup
darauf auszuführen. Dies ist inthe official Kubernetes documentation beschrieben.
Eine andere Möglichkeit, den Cluster-DNS abzufragen, besteht darin,dig
undnsenter
von einem Knoten zu verwenden. Wenndig
nicht installiert ist, kann es mitapt
auf Debian-basierten Linux-Distributionen installiert werden:
apt install dnsutils
Ermitteln Sie zunächst die Cluster-IP des Diensteskube-dns:
kubectl get service -n kube-system kube-dns
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.32.0.10 53/UDP,53/TCP 15d
Die Cluster-IP ist oben hervorgehoben. Als Nächstes verwenden wirnsenter
, umdig
im a-Container-Namespace auszuführen. Weitere Informationen hierzu finden Sie im AbschnittFinding and Entering Pod Network Namespaces:
nsenter -t 14346 -n dig kubernetes.default.svc.cluster.local @10.32.0.10
Dieser Befehldig
sucht den vollständigen Domänennamen des Dienstes vonservice-name.namespace.svc.cluster.local und gibt die IP der IP-Adresse des Cluster-DNS-Dienstes (@10.32.0.10
) an.
IPVS-Details anzeigen
Ab Kubernetes 1.11 könnenkube-proxy
IPVS so konfigurieren, dass die Übersetzung von virtuellen Service-IPs in Pod-IPs erfolgt. Sie können die Übersetzungstabelle von IPs mitipvsadm
auflisten:
ipvsadm -Ln
OutputIP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 100.64.0.1:443 rr
-> 178.128.226.86:443 Masq 1 0 0
TCP 100.64.0.10:53 rr
-> 100.96.1.3:53 Masq 1 0 0
-> 100.96.1.4:53 Masq 1 0 0
UDP 100.64.0.10:53 rr
-> 100.96.1.3:53 Masq 1 0 0
-> 100.96.1.4:53 Masq 1 0 0
Verwenden Sie zum Anzeigen einer einzelnen Dienst-IP die Option-t
und geben Sie die gewünschte IP an:
ipvsadm -Ln -t 100.64.0.10:53
OutputProt LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 100.64.0.10:53 rr
-> 100.96.1.3:53 Masq 1 0 0
-> 100.96.1.4:53 Masq 1 0 0
Fazit
In diesem Artikel haben wir einige Befehle und Techniken zum Erkunden und Untersuchen der Details des Netzwerks Ihres Kubernetes-Clusters besprochen. Weitere Informationen zu Kubernetes finden Sie unterour Kubernetes tutorials tag undthe official Kubernetes documentation.