NetworkPolicy 的 default-deny 到底拒绝了什么?from 里 podSelector 和 namespaceSelector 写在一起和分开写有什么区别?为什么加了 egress 限制之后域名解析就坏了?这篇用 3 个客户端、2 个命名空间的连通性矩阵一项项验证。
连通性:{'同命名空间 role=frontend': 'ok', '同命名空间 role=other': 'ok', 'k69b 命名空间 role=frontend': 'ok'}kind 默认的 CNI kindnet 自带 NetworkPolicy 实现。server(命名空间 k69,label team=blue)没有任何策略时,同命名空间的 role=frontend、role=other 和另一个命名空间 k69b(team=red)的 role=frontend 都能连上。NetworkPolicy 是由 CNI 插件执行的,没有支持它的 CNI 就是一个没有效果的对象。
应用策略后,第一次探测到 frontend 连不上用了 1.1 秒(探测本身每次最多等 1 秒)
连通性:{'同命名空间 role=frontend': '超时', '同命名空间 role=other': '超时', 'k69b 命名空间 role=frontend': '超时'}
被拒的连接表现为“超时”(wget -T 3 用时 3.1 秒)——包被 DROP,没有 RST,客户端只能等超时
default-deny ingress 只管进来的:front 自己往外查 DNS 仍然成功(退出码 0)→ 'Address: 10.96.0.1'应用 podSelector: {} + policyTypes: [Ingress] 且不写任何 ingress 规则:第一次探测到 frontend 连不上用了 1.1 秒;三个客户端全部超时。被拒的连接不是 Connection refused 而是 wget 等了 3.1 秒超时——包被直接 DROP,没有 RST。这条策略只管进来的方向:front 自己往外查 DNS 仍然成功。
只写 podSelector(role=frontend):{'同命名空间 role=frontend': 'ok', '同命名空间 role=other': '超时', 'k69b 命名空间 role=frontend': '超时'}(podSelector 不带 namespaceSelector 时只匹配策略所在命名空间的 Pod)
同一个 from 条目里 namespaceSelector(team=red)+ podSelector(role=frontend)= 且:{'同命名空间 role=frontend': '超时', '同命名空间 role=other': '超时', 'k69b 命名空间 role=frontend': 'ok'}
拆成两个 from 条目(多了一个短横线)= 或:{'同命名空间 role=frontend': 'ok', '同命名空间 role=other': '超时', 'k69b 命名空间 role=frontend': 'ok'}(team=red 的所有 Pod + 本命名空间的 frontend)放行规则的写法决定结果。只写 podSelector: {role: frontend}:只匹配策略所在命名空间的 Pod,同命名空间 frontend 通,k69b 的 frontend 超时。同一个 from 条目里同时写 namespaceSelector: {team: red} 和 podSelector: {role: frontend} 是“且”,只有 k69b 的 frontend 能连。拆成两个条目(两个短横线)就是“或”:同命名空间 frontend 和 k69b 的 frontend 都能连,role=other 始终不行。少写一个短横线,放行范围就完全不同。
再加一条 allow-other(放行 role=other):{'同命名空间 role=frontend': 'ok', '同命名空间 role=other': 'ok', 'k69b 命名空间 role=frontend': 'ok'}(多条策略取并集,没有“拒绝”规则)
先删掉所有策略,front 用 Service 名访问:ok
对 role=frontend 加 default-deny egress:用 IP 访问 超时;用 Service 名访问 超时(DNS 查询也走 egress,被一起拦了)
nslookup server:;; connection timed out; no servers could be reached
放行到 kube-system:53 和到 server:80 之后:用 IP ok;用 Service 名 ok再加一条放行 role=other 的策略,三个客户端全部变成 ok:多条策略取并集,只能“放行”,不存在“拒绝”规则。对 role=frontend 设 egress 的 default-deny 后,用 IP 访问 server 超时,用 Service 名访问也超时,nslookup server 报 connection timed out——DNS 查询同样走 egress。放行到 kube-system 的 53(UDP 和 TCP)以及到 server 的 80 之后,两种访问方式都恢复。