Netzwerk & IP-Versionen
Hopplas Monitoring-Worker bauen Verbindungen von innerhalb deines Clusters auf. Ein Monitor kann nur prüfen, was das Pod-Netzwerk deines Clusters tatsächlich erreicht. Dieser eine Satz erklärt die meisten Überraschungen auf dieser Seite.
Für eine normale Installation brauchst du hier nichts zu tun. Lies weiter, wenn du IPv6-Monitoring willst oder wenn sich Checks in einem Overlay-Netzwerk merkwürdig verhalten.
Was Hoppla braucht
| Anforderung | Wofür |
|---|---|
| Ausgehend TCP 80/443 ins Internet | HTTP-/Uptime-, SSL-, Redirect-, Sitemap- und Crawl-Checks |
| Ausgehend TCP/UDP 53 | DNS-Checks fragen die autoritativen Nameserver direkt ab |
| Ausgehend TCP 43 | Domain-Ablauf-Checks (WHOIS) |
| Ausgehend TCP 587 | Benachrichtigungs-Mails, falls du eigenes SMTP nutzt |
| Ausgehend ICMP | Ping-Checks |
Mit den mitgelieferten Network Policies (networkPolicy.enabled=true) ist das alles bereits erlaubt. Setze networkPolicy.backend auf cilium, wenn du Cilium betreibst, sonst auf standard.
IPv4-only-Cluster: nichts zu tun
Das ist der Standardfall und wird voll unterstützt. Die meisten Cluster sind IPv4-only -- ein Standard-GKE-Cluster, ein EKS-Cluster im IPv4-Modus und ein Standard-kind-Cluster ebenfalls.
Hoppla erkennt, dass es keinen IPv6-Ausgang hat, und geht ehrlich damit um:
- Monitore auf IPv4-erreichbaren Hosts laufen normal -- also die überwältigende Mehrheit.
- Ein Monitor, dessen Host IPv6-only ist, wird als nicht prüfbar erfasst, nicht als down. Das heißt: in den Ergebnissen sichtbar, aus der Uptime-Berechnung ausgeschlossen und kein Alarm.
Der letzte Punkt ist Absicht. Einen Host als "down" zu melden, wenn die Wahrheit "wir konnten ihn von hier aus nicht prüfen" lautet, wäre ein Fehlalarm -- und ein IPv6-only-Monitor würde sonst bei jedem einzelnen Check für immer alarmieren.
IPv6-Monitoring aktivieren
Lohnt sich nur, wenn du IPv6-only-Hosts überwachst oder einen Fehler erkennen willst, der nur einen Stack eines Dual-Stack-Hosts betrifft. Der zweite Fall ist der interessante: Ein Host kann über IPv6 einwandfrei und über IPv4 kaputt sein. Ein Browser verbirgt das (er wechselt still auf den funktionierenden Pfad) -- echte Besucher auf dem kaputten Pfad nicht.
Das Pod-Netzwerk deines Clusters braucht funktionierenden IPv6-Ausgang. Das Verhalten pro Monitor steuerst du dann über die Einstellung IP-Version am jeweiligen Uptime-Check:
| Einstellung | Verhalten |
|---|---|
Automatisch (Standard) | Prüft jede Adressfamilie, die DNS anbietet. Single-Stack-Hosts bekommen einen Check, Dual-Stack-Hosts beide -- ein Ausfall auf nur einem Stack wird als Teilausfall mit Angabe des betroffenen Stacks gemeldet. |
Nur IPv4 | Prüft ausschließlich über IPv4. |
Nur IPv6 | Prüft ausschließlich über IPv6. |
Automatisch kostet nur bei Dual-Stack-Hosts einen zusätzlichen Request. Die Mehrlast skaliert also mit dem Anteil deiner überwachten Hosts, die AAAA-Records veröffentlichen -- nicht mit der Gesamtzahl deiner Monitore.
Plattform-Hinweise
Bei GKE und EKS wird die IP-Familie beim Anlegen des Clusters festgelegt und ist danach nicht mehr änderbar. Wenn du IPv6-Monitoring willst, entscheide das, bevor du den Cluster erstellst.
GKE -- Dual-Stack gibt es für neue Standard-Cluster (1.24+) und Autopilot (1.25+) und setzt VPC-natives Networking (Alias-IPs) plus GKE Dataplane V2 voraus. Anlegen mit --stack-type=ipv4-ipv6 und --ipv6-access-type in einem Dual-Stack-Subnetz. Für einen bestehenden Cluster lässt sich das nicht nachrüsten.
Amazon EKS -- wird beim Anlegen über --ip-family gesetzt und ist danach unveränderlich. Wichtig: EKS unterstützt überhaupt keine Dual-Stack-Pods -- ein Cluster ist entweder IPv4 oder IPv6, niemals beides. Im IPv6-Modus sind Pods reine IPv6-Pods und erreichen IPv4-Ziele über NAT64/DNS64-Übersetzung -- siehe Bekannte Einschränkung unten, die Hoppla direkt betrifft.
kind (lokal) -- ergänze networking: {ipFamily: dual} in deiner Cluster-Konfiguration. Beachte: IPv6 innerhalb des Clusters bedeutet nicht IPv6-Ausgang ins Internet. Der hängt davon ab, dass der Docker-Host funktionierendes IPv6 hat, was häufig nicht konfiguriert ist. Gut, um die Einstellung zu testen -- nicht, um daraus zu schließen, dass dein IPv6-Monitoring funktioniert.
Eigene Infrastruktur -- du brauchst drei Dinge: Nodes mit routbarer IPv6-Adresse und Default-Route, ein für IPv6 konfiguriertes CNI und Network Policies, die IPv6-Ausgang erlauben. Alle drei -- sonst scheitert IPv6 stillschweigend, siehe Fehlersuche unten.
Prüfen, was dein Cluster erreicht
Führe das in einem Worker-Pod aus. Schneller kommst du nicht zur Antwort:
POD=$(kubectl get pods -n hoppla -l app.kubernetes.io/component=worker-uptime -o name | head -1)
# Hat der Pod überhaupt eine IPv6-Adresse?
kubectl get $POD -n hoppla -o jsonpath='{.status.podIPs}{"\n"}'
# Erreicht er IPv6 und IPv4 auch wirklich?
kubectl exec -n hoppla $POD -c worker -- sh -c '
curl -6 -sS -o /dev/null -w "IPv6: %{http_code} via %{remote_ip}\n" --max-time 10 https://ipv6.google.com/
curl -4 -sS -o /dev/null -w "IPv4: %{http_code} via %{remote_ip}\n" --max-time 10 https://www.google.com/'
# Zu welchem Schluss Hoppla selbst kommt
kubectl exec -n hoppla $POD -c worker -- php artisan tinker --execute='
echo app(\App\Services\IpFamilyEgress::class)->supports("v6") ? "IPv6 erkannt" : "kein IPv6";'Gefährlich ist der Widerspruch: Hoppla meldet "IPv6 erkannt", während curl -6 fehlschlägt. Hoppla entscheidet anhand einer global gültigen IPv6-Adresse am Pod -- ein Cluster, der Adressen ohne funktionierenden Ausgang vergibt, bringt Hoppla also dazu, IPv6 zu versuchen und echte Fehlschläge zu erfassen. Aus einem harmlosen "nicht prüfbar" werden dann Fehlalarme. Wenn du das siehst, setze PROBE_IPV6_EGRESS=false auf den Uptime-Workern und erzwinge IPv6 aus, bis der Cluster in Ordnung ist.
Fehlersuche
IPv6-Checks scheitern, obwohl Pods IPv6-Adressen haben
Fast immer eine von zwei Ursachen -- und aus Sicht der Anwendung sehen beide identisch aus. Wenn du Cilium betreibst, sagen dir dessen Drop-Zähler, welche es ist. Lies den Grund, nicht die Gesamtzahl:
CILIUM=$(kubectl get pods -n kube-system -l k8s-app=cilium -o name | head -1)
kubectl exec -n kube-system $CILIUM -c cilium-agent -- \
sh -c 'cilium-dbg metrics list | grep drop_count'Unsupported L3 protocol-- das CNI hat gar keinen IPv6-Datenpfad (bei Cilium:enable-ipv6=false). Es verwirft IPv6 in beide Richtungen, was auch die IPv6-Nachbarschaftserkennung erledigt -- der Node kann dann nicht einmal sein Gateway auflösen. Prüfen mitip -6 neigh show dev eth0: ein Gateway, das aufINCOMPLETEoderFAILEDhängt, ist genau das.Policy denied-- der Datenpfad funktioniert, aber eine Network Policy erlaubt nur IPv4. Das ist der tückische Fall: Adressen, Routing und Nachbarschaftserkennung sehen bis zum ersten Request völlig gesund aus. Wenn du eigene Policies geschrieben hast: Egress-Regeln, die auf0.0.0.0/0beschränkt sind, brauchen zusätzlich::/0.
Geh bei jedem CNI genauso in zwei Schritten vor: erst bestätigen, dass der Datenpfad IPv6 überhaupt transportiert, dann, dass die Policy es erlaubt.
Langsame oder hängende Übertragungen im Overlay-Netzwerk
Symptom: Es funktioniert, fühlt sich aber langsam an, große Antworten hängen gelegentlich, und die Nodes fragmentieren Pakete. Zähler auf einem Node prüfen:
kubectl exec -n kube-system $CILIUM -c cilium-agent -- awk '
/^Ip: Forwarding/ { for (i=1;i<=NF;i++) x[$i]=i; getline;
print "FragCreates", $x["FragCreates"], "ReasmFails", $x["ReasmFails"] }' /proc/net/snmpZweimal messen, eine Minute Abstand. Steigende FragCreates heißen: Pakete werden zerlegt. Steigende ReasmFails heißen: einige gehen dabei verloren und müssen neu gesendet werden. In einem gesunden Overlay bleiben beide flach.
Die Ursache ist eine MTU, die die Kapselung nicht berücksichtigt. Wenn dein CNI ein Overlay nutzt (VXLAN, Geneve, IP-in-IP), wird jedes Pod-Paket eingepackt -- und die Verpackung braucht Platz:
Pod-MTU = MTU der Schnittstelle, über die das Overlay tatsächlich läuft − Kapselungs-OverheadVXLAN und Geneve kosten je 50 Byte, IP-in-IP 20, WireGuard mehr.
Die Falle ist der erste Term. Das Overlay nutzt nicht zwangsläufig deine primäre Schnittstelle. Wenn Nodes über ein separates oder privates Netz tunneln, zählt die MTU dieser Schnittstelle -- und die liegt oft unter 1500. Prüfe alle Kandidaten, statt zu raten:
kubectl exec -n kube-system $CILIUM -c cilium-agent -- \
sh -c 'for d in /sys/class/net/*/mtu; do echo "$(dirname $d | xargs basename): $(cat $d)"; done'Nützliche Referenzwerte: Google Cloud VPC nutzt standardmäßig 1460 (VXLAN-Pod-MTU also 1410), AWS VPC erlaubt 9001 innerhalb der VPC, fällt aber über VPN auf 1500 und über Inter-Region-Peering auf 8500 -- und mehrere Angebote für private Netze laufen mit 1450. Nach einer MTU-Änderung die Pods neu starten: Der Wert wird beim Anlegen der Pod-Schnittstelle gesetzt, laufende Pods behalten den alten.
Bekannte Einschränkung: NAT64/DNS64-Cluster
Hopplas Prüfung pro Adressfamilie setzt natives Dual-Stack voraus. NAT64/DNS64-Übersetzung versteht sie derzeit nicht -- also genau den Weg, über den ein IPv6-only-Cluster IPv4-Ziele erreicht, insbesondere EKS im IPv6-Modus.
In so einem Cluster löst ein IPv4-only-Ziel sowohl zu einem echten A-Record als auch zu einem synthetisierten NAT64-AAAA auf. Hoppla plant daraufhin beide Zweige: Der IPv4-Zweig scheitert, weil der Pod keinen IPv4-Stack hat, während der IPv6-Zweig über den Übersetzer erfolgreich ist. Ergebnis: ein gemeldeter Teilausfall für einen Host, der völlig in Ordnung ist.
Abhilfe: Setze in einem IPv6-only-Cluster die IP-Version deiner Uptime-Checks auf Nur IPv6. Dann läuft alles wie vorgesehen über den Übersetzer und die Ergebnisse stimmen.
Native Dual-Stack-Cluster und IPv4-only-Cluster sind nicht betroffen.