From 7da87bf3979a77dfbfa62495bc7e0ece91cb1e9a Mon Sep 17 00:00:00 2001 From: Konstantin Renner Date: Wed, 20 May 2026 11:00:25 +0200 Subject: [PATCH] =?UTF-8?q?network-policies:=20drop=20egress=20section=20f?= =?UTF-8?q?rom=20ICMP=20CCNP=20=E2=80=94=20was=20breaking=20DNS/apiserver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The egress section transitioned namespaces that previously had ingress-only CNPs (velero, monitoring, rook-ceph CSI) into egress-policy-enforced mode with only ICMP egress allowed — breaking DNS lookups to coredns, kube-apiserver access, and world egress. The user-facing ICMP problem was coredns→HA ICMP DU drops, which is ingress on HA's side. The ingress rule alone is sufficient. ICMP egress in the per-namespace egress-enforced CNPs already flows via the broad toEntities rules (host/remote-node/world don't constrain protocol so ICMP is included). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../network-policies/allow-icmp.yaml | 100 +++--------------- 1 file changed, 14 insertions(+), 86 deletions(-) diff --git a/kubernetes/infrastructure/network-policies/allow-icmp.yaml b/kubernetes/infrastructure/network-policies/allow-icmp.yaml index 2edaf534..2d39757d 100644 --- a/kubernetes/infrastructure/network-policies/allow-icmp.yaml +++ b/kubernetes/infrastructure/network-policies/allow-icmp.yaml @@ -1,4 +1,4 @@ -# All ICMP types, in/out of every namespace that has a default-deny. +# All ICMP types ingress into every namespace that has a default-deny. # # Scoped via `matchExpressions In` to the explicit list of namespaces # that already opted into policy enforcement, so this CCNP only widens @@ -6,6 +6,19 @@ # other unmanaged namespace into policy-enforced mode (which is what # broke metrics-server when I previously used `Exists`). # +# INGRESS ONLY by design: a few of these namespaces (notably velero, +# monitoring, parts of rook-ceph) had per-namespace CNPs with an +# ingress section but NO egress section, so their pods were +# ingress-policy-enforced + egress-default-allow. Adding an egress +# section here transitions them into egress-policy-enforced mode too, +# and the CCNP would then deny everything except ICMP egress — which +# broke DNS, kube-apiserver, and world egress cluster-wide. +# +# The user-impacting drops were all ICMP errors landing on pods that +# had ingress-enforced policies; their reply ICMP egress already flows +# through the per-namespace egress rules (toEntities host/remote-node/ +# world/etc), or via default-allow where no egress section exists. +# # Enumerates every assigned ICMPv4 type (0-30) and ICMPv6 type # (1-4, 128-153). Cilium's policy schema requires an explicit `type` # per ICMPField — there is no wildcard. @@ -118,88 +131,3 @@ spec: family: IPv6 - type: 153 # Multicast Router Termination family: IPv6 - egress: - - toEndpoints: - - matchExpressions: - - key: io.kubernetes.pod.namespace - operator: Exists - icmps: - - fields: - - type: 0 - family: IPv4 - - type: 3 - family: IPv4 - - type: 4 - family: IPv4 - - type: 5 - family: IPv4 - - type: 8 - family: IPv4 - - type: 9 - family: IPv4 - - type: 10 - family: IPv4 - - type: 11 - family: IPv4 - - type: 12 - family: IPv4 - - type: 13 - family: IPv4 - - type: 14 - family: IPv4 - - type: 15 - family: IPv4 - - type: 16 - family: IPv4 - - type: 17 - family: IPv4 - - type: 18 - family: IPv4 - - type: 30 - family: IPv4 - - type: 1 - family: IPv6 - - type: 2 - family: IPv6 - - type: 3 - family: IPv6 - - type: 4 - family: IPv6 - - type: 128 - family: IPv6 - - type: 129 - family: IPv6 - - type: 130 - family: IPv6 - - type: 131 - family: IPv6 - - type: 132 - family: IPv6 - - type: 133 - family: IPv6 - - type: 134 - family: IPv6 - - type: 135 - family: IPv6 - - type: 136 - family: IPv6 - - type: 137 - family: IPv6 - - type: 138 - family: IPv6 - - type: 141 - family: IPv6 - - type: 142 - family: IPv6 - - type: 143 - family: IPv6 - - type: 148 - family: IPv6 - - type: 149 - family: IPv6 - - type: 151 - family: IPv6 - - type: 152 - family: IPv6 - - type: 153 - family: IPv6