Eine benutzerdefinierte Netzwerksicherheitsgruppe blockiert Datenverkehr
Wenn Sie auf eine Anwendung zugreifen, die in einem AKS-Cluster (Azure Kubernetes Service) gehostet wird, erhalten Sie die Fehlermeldung "Timeout". Dieser Fehler kann auch auftreten, wenn die Anwendung ausgeführt wird und der Rest der Konfiguration korrekt zu sein scheint.
Voraussetzungen
Das Kubernetes kubectl-Tool oder ein ähnliches Tool, um eine Verbindung mit dem Cluster herzustellen. Um kubectl mithilfe der Azure CLI zu installieren, führen Sie den Befehl az aks install-cli aus.
Das Client-URL-Tool (cURL) oder ein ähnliches Befehlszeilentool.
Das Befehlszeilentool apt-get zum Verarbeiten von Paketen.
Problembeschreibung
Wenn Sie die folgenden kubectl get- und cURL-Befehle ausführen, treten Timeoutfehler auf, die der folgenden Konsolenausgabe ähneln:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-deployment-66648877fc-v78jm 1/1 Running 0 5m53s
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-loadbalancer-service LoadBalancer 10.0.107.79 10.81.x.x 80:31048/TCP 4m14s
$ curl -Iv http://10.81.124.39 # Use an IP address that fits the "EXTERNAL-IP" pattern.
* Trying 10.81.x.x:80...
* connect to 10.81.x.x port 80 failed: Timed out
* Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out
* Closing connection 0
curl: (28) Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out
Ursache
Wenn jedes Mal derselbe Timeoutfehler auftritt, deutet dies normalerweise darauf hin, dass eine Netzwerkkomponente den Datenverkehr blockiert.
Um dieses Problem zu beheben, können Sie zunächst den Zugriff auf den Pod überprüfen und dann mit einem Insider-Ansatz zum Client fortfahren.
Führen Sie zum Überprüfen des Pods die folgenden kubectl get
Befehle und kubectl describe aus:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-deployment-66648877fc-v78jm 1/1 Running 0 53s 172.25.0.93 aks-agentpool-42617579-vmss000000
$ kubectl describe pod my-deployment-66648877fc-v78jm # Specify the pod name from the previous command.
...
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 117s default-scheduler Successfully assigned default/my-deployment-66648877fc-v78jm to aks-agentpool-42617579-vmss000000
Normal Pulling 116s kubelet Pulling image "httpd"
Normal Pulled 116s kubelet Successfully pulled image "httpd" in 183.532816ms
Normal Created 116s kubelet Created container webserver
Normal Started 116s kubelet Started container webserver
Basierend auf dieser Ausgabe scheint der Pod ohne Neustarts ordnungsgemäß ausgeführt zu werden.
Öffnen Sie einen Testpod, um den Zugriff auf den Anwendungspod zu überprüfen. Führen Sie die folgenden kubectl get
Befehle , kubectl run, apt-get
und cURL aus:
$ kubectl get pods -o wide # Get the pod IP address.
NAME READY STATUS RESTARTS AGE IP NODE
my-deployment-66648877fc-v78jm 1/1 Running 0 7m45s 172.25.0.93 aks-agentpool-42617579-vmss000000
$ kubectl run -it --rm aks-ssh --image=debian:stable # Launch the test pod.
If you don't see a command prompt, try pressing enter.
$ root@aks-ssh:
$ # Install packages inside the test pod.
$ root@aks-ssh: apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://deb.debian.org/debian bullseye-updates InRelease [39.4 kB]
...
...
Running hooks in /etc/ca-certificates/update.d...
done.
$ # Try to check access to the pod using the pod IP address from the "kubectl get" output.
$ curl -Iv http://172.25.0.93
* Trying 172.25.0.93:80...
* Connected to 172.25.0.93 (172.25.0.93) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 172.25.0.93 left intact
Auf den Pod kann direkt zugegriffen werden. Daher wird die Anwendung ausgeführt.
Der definierte Dienst ist ein LoadBalancer
Typ. Dies bedeutet, dass der Anforderungsfluss vom Endclient zum Pod wie folgt lautet:
Client >> Load Balancer >> AKS-Knoten >> Anwendungspod
In diesem Anforderungsfluss können wir den Datenverkehr über die folgenden Komponenten blockieren:
- Netzwerkrichtlinien im Cluster
- Die Netzwerksicherheitsgruppe (NSG) für das AKS-Subnetz und den AKS-Knoten
Führen Sie den folgenden kubectl get
Befehl aus, um die Netzwerkrichtlinie zu überprüfen:
$ kubectl get networkpolicy --all-namespaces
NAMESPACE NAME POD-SELECTOR AGE
kube-system konnectivity-agent app=konnectivity-agent 3h8m
Es ist nur die AKS-Standardrichtlinie vorhanden. Daher scheint die Netzwerkrichtlinie den Datenverkehr nicht zu blockieren.
Führen Sie die folgenden Schritte aus, um die NSGs und die zugehörigen Regeln mithilfe von AKS zu überprüfen:
Suchen Sie im Azure-Portal nach VM-Skalierungsgruppen, und wählen Sie diese Option aus.
Wählen Sie in der Liste der Skalierungsgruppeninstanzen die von Ihnen verwendete Instanz aus.
Wählen Sie
Networking
im Menübereich Ihrer Skalierungsgruppe instance aus.
Die Seite Netzwerk für die Skalierungsgruppe instance wird angezeigt. Auf der Registerkarte Eingehende Portregeln werden zwei Regelsätze angezeigt, die auf den beiden NSGs basieren, die auf der Skalierungsgruppe instance:
Der erste Satz besteht aus NSG-Regeln auf Subnetzebene. Diese Regeln werden unter der folgenden Hinweisüberschrift angezeigt:
Netzwerksicherheitsgruppe <my-aks-nsg> (angefügt an subnetz: <my-aks-subnet>)
Diese Anordnung ist üblich, wenn ein benutzerdefiniertes virtuelles Netzwerk und ein benutzerdefiniertes Subnetz für den AKS-Cluster verwendet werden. Der Regelsatz auf Subnetzebene könnte der folgenden Tabelle ähneln.
Priorität Name Port Protokoll Quelle Ziel Aktion 65000 AllowVnetInBound Beliebig Beliebig VirtualNetwork VirtualNetwork Zulassen 65001 AllowAzureLoadBalancerInBound Beliebig Beliebig AzureLoadBalancer Beliebig Zulassen 65500 DenyAllInBound Beliebig Beliebig Beliebig Beliebig Deny Der zweite Satz besteht aus NSG-Regeln auf Netzwerkadapterebene. Diese Regeln werden unter der folgenden Hinweisüberschrift angezeigt:
Netzwerksicherheitsgruppe aks-agentpool-agentpool-number-nsg<> (angefügt an die Netzwerkschnittstelle: aks-agentpool-vm-scale-set-number-vmss<>)
Diese NSG wird vom AKS-Cluster angewendet und von AKS verwaltet. Der entsprechende Regelsatz könnte der folgenden Tabelle ähneln.
Priorität Name Port Protokoll Quelle Ziel Aktion 500 <guid-TCP-80-Internet> 80 TCP Internet 10.81.x.X Zulassen 65000 AllowVnetInBound Beliebig Beliebig VirtualNetwork VirtualNetwork Zulassen 65001 AllowAzureLoadBalancerInBound Beliebig Beliebig AzureLoadBalancer Beliebig Zulassen 65500 DenyAllInBound Beliebig Beliebig Beliebig Beliebig Deny
Auf Netzwerkadapterebene gibt es eine NSG-Eingangsregel für TCP unter DER IP-Adresse 10.81. x. x an Port 80 (in der Tabelle hervorgehoben). In den Regeln für die NSG auf Subnetzebene fehlt jedoch eine entsprechende Regel.
Warum hat AKS die Regel nicht auf die benutzerdefinierte NSG angewendet? Da AKS keine NSGs auf sein Subnetz anwendet und keine der NSGs ändert, die diesem Subnetz zugeordnet sind. AKS ändert die NSGs nur auf Netzwerkadapterebene. Weitere Informationen finden Sie unter Kann ich NSGs mit AKS konfigurieren?.
Lösung
Wenn die Anwendung für den Zugriff auf einen bestimmten Port aktiviert ist, müssen Sie sicherstellen, dass die benutzerdefinierte NSG diesen Port als Inbound
Regel zulässt. Nachdem die entsprechende Regel in der benutzerdefinierten NSG auf Subnetzebene hinzugefügt wurde, kann auf die Anwendung zugegriffen werden.
$ curl -Iv http://10.81.x.x
* Trying 10.81.x.x:80...
* Connected to 10.81.x.x (10.81.x.x) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 10.81.x.x left intact
Kontaktieren Sie uns für Hilfe
Wenn Sie Fragen haben oder Hilfe mit Ihren Azure-Gutschriften benötigen, dann erstellen Sie beim Azure-Support eine Support-Anforderung oder fragen Sie den Azure Community-Support. Sie können auch Produktfeedback an die Azure Feedback Community senden.