IPv6 Health Endpoint Unreachable from Host Network Namespace
IPv6 Health Endpoint Unreachable from Host Network Namespace
Summary
Cilium health checks fail for IPv6 secondary addresses when probing from the host network namespace. IPv4 health checks work fine, and pod-to-health-endpoint IPv6 connectivity works perfectly. Only host-to-health-endpoint IPv6 fails.
Environment
- Cilium Version: 1.18.3
- Kubernetes Version: v1.34.1
- Kernel: 6.17.7-300.fc43.x86_64
-
Datapath Mode: Both
vethandnetkit(issue occurs in both) - Routing Mode: native
- Cluster: Single-node, dual-stack
Minimal Configuration to Reproduce
helm install cilium cilium/cilium --version 1.18.3 \
--namespace kube-system \
--set ipv4.enabled=true \
--set ipv6.enabled=true \
--set routingMode=native \
--set ipv4NativeRoutingCIDR=10.244.0.0/16 \
--set ipv6NativeRoutingCIDR=fd00:10:244::/48 \
--set kubeProxyReplacement=true
Node configuration:
# /var/lib/kubelet/kubeadm-flags.env
--node-ip=<NODE_IPV4>,<NODE_IPV6>
Expected Behavior
Cluster health: 1/1 reachable
node (localhost) <NODE_IPV4>,<NODE_IPV6> 2/2
Actual Behavior
$ cilium-health status
Cluster health: 0/1 reachable
node (localhost) <NODE_IPV4>,<NODE_IPV6> 2/2 1/2
$ cilium-health status -o json | jq '.nodes[0]."health-endpoint"."secondary-addresses"'
[{
"http": { "status": "context deadline exceeded" },
"icmp": { "status": "Connection timed out" },
"ip": "fd00:10:244::36e8"
}]
Test Results
| Test | Result |
|---|---|
| IPv4 health check (host → health endpoint) |
|
| IPv6 health check (host → health endpoint) |
|
| IPv6 connectivity (pod → health endpoint) |
|
# From host - FAILS
$ ping6 -c 3 fd00:10:244::36e8
3 packets transmitted, 0 received, 100% packet loss
# From pod - WORKS
$ kubectl exec -n cilium-test-1 <pod> -- ping6 -c 3 fd00:10:244::36e8
3 packets transmitted, 3 received, 0% packet loss
Diagnostic Evidence
Health endpoint is correctly configured:
$ nsenter -t <health-pid> -n ip -6 addr show
inet6 fd00:10:244::36e8/128 scope global
$ nsenter -t <health-pid> -n ss -tln | grep 4240
LISTEN 0 4096 *:4240 *:*
TCP handshake never completes:
# tcpdump on lxc_health interface
SYN fd00:10:244::441e.54560 > fd00:10:244::36e8.4240
SYN-ACK fd00:10:244::36e8.4240 > fd00:10:244::441e.54560 ← Reply sent
SYN-ACK fd00:10:244::36e8.4240 > fd00:10:244::441e.54560 ← Duplicate
# ACK never sent - handshake incomplete
# Host socket stuck in SYN-SENT
$ ss -6 -tan | grep 36e8
SYN-SENT 0 1 [fd00:10:244::441e]:55576 [fd00:10:244::36e8]:4240
No packet drops detected:
$ cilium monitor --type drop
# No drops related to IPv6 health endpoint
Connection tracking shows entries but zero packets delivered:
$ cilium bpf ct list global | grep 36e8
TCP IN fd00:10:244::441e:54560 -> fd00:10:244::36e8:4240
Packets=0 Bytes=0 RxFlagsSeen=0x02 TxFlagsSeen=0x12
Root Cause
SYN-ACK packets from the health endpoint reach the lxc_health/netkit interface but are not delivered to the host network stack socket layer. The issue appears specific to IPv6 packet handling in the cilium_host ingress path.
Reproducibility
-
✅ Reproduces with veth mode (default) -
✅ Reproduces with netkit mode -
✅ Reproduces with minimal configuration (above) -
✅ Reproduces with advanced features (BIGTCP, BBR, etc.)
Created by Claude Code model claude-sonnet-4-5-20250929