LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

用 NetworkPolicy 把通路收窄

在 LabHub 中继续学习

目标

从默认拒绝开始,将 NetworkPolicy 逐步收紧为六种形式,尤其要亲手区分 from 项中的 AND/OR 结构。

为什么这很重要

首先需要明确:本实验环境没有能够执行策略的 CNI 数据平面。因此无法确认流量是否真的被阻断,评分只检查对象 spec。 这一限制反而与考试很相似,CKA 大多数题目同样检查清单是否准确。

NetworkPolicy 的思考方式与防火墙不同。一旦有任何一个策略选中了某个 Pod,该 Pod 对应方向(Ingress/Egress)的流量就会变成默认拒绝,只允许策略明确放行的流量通过。策略之间只会叠加,不存在拒绝规则。因此,“一个默认拒绝策略 + 所需数量的允许策略”是标准模式。

阻止 egress 时顺带把 DNS 也阻断,是另一个常见事故。Pod 无法解析 Service 名称时,症状不会表现为网络阻断,而是应用超时,导致诊断耗时更长。

步骤

  1. 创建 namespace cka-netpol(标签 tier=app)和 cka-netpol-client(标签 tier=client)。在 cka-netpol 中创建 Deployment web(副本数 2,镜像 nginx:1.27,Pod 标签 app=web)。
  2. cka-netpol 中创建 NetworkPolicy default-deny-ingress。podSelector 是空对象,policyTypes 为 [Ingress],没有 ingress 规则。
  3. 创建 NetworkPolicy allow-frontend。podSelector 为 app=web,ingress 的 from 仅包含一个 podSelector app=frontend,端口为 TCP 80。
  4. 创建 NetworkPolicy allow-client-ns。podSelector 为 app=web,ingress 的 from 仅包含一个 namespaceSelector tier=client(不要同时加入 podSelector)。
  5. 创建 NetworkPolicy egress-dns-only。podSelector 为 app=web,policyTypes 为 [Egress],egress 的 to 是 namespaceSelector kubernetes.io/metadata.name=kube-system,端口包含 UDP 53 和 TCP 53 两项。
  6. 创建 NetworkPolicy allow-cidr。podSelector 为 app=web,ingress 的 from 是 ipBlock cidr 10.0.0.0/16,except 中加入 10.0.5.0/24
  7. 创建 NetworkPolicy web-final。podSelector 为 app=web,policyTypes 为 [Ingress, Egress]。ingress 的 from 要在同一个条目中同时设置 namespaceSelector tier=client 和 podSelector app=frontend,端口为 TCP 8080。egress 的 to 是 ipBlock cidr 0.0.0.0/0,except 为 169.254.169.254/32,端口为 TCP 443。

参考

准备目标与流量来源

创建 namespace cka-netpol(标签 tier=app)和 cka-netpol-client(标签 tier=client)。在 cka-netpol 中创建 Deployment web(副本数 2,镜像 nginx:1.27,Pod 标签 app=web)。

namespace 标签是后续 namespaceSelector 用来选择对象的键。Pod 标签也必须准确设置。

默认拒绝策略

cka-netpol 中创建 NetworkPolicy default-deny-ingress。podSelector 是空对象,policyTypes 为 [Ingress],没有 ingress 规则。

将 podSelector 设为空对象,就会选中该 namespace 中的所有 Pod。不写任何规则,意味着全部拒绝。

只允许同一 namespace 中的 Pod

创建 NetworkPolicy allow-frontend。podSelector 为 app=web,ingress 的 from 仅包含一个 podSelector app=frontend,端口为 TCP 80。

from 条目中只使用 podSelector 时,范围会限定在策略所在的 namespace 内。还必须指定端口。

允许另一个 namespace 中的全部 Pod

创建 NetworkPolicy allow-client-ns。podSelector 为 app=web,ingress 的 from 仅包含一个 namespaceSelector tier=client(不要同时加入 podSelector)。

namespaceSelector 检查 namespace 上的标签。本步骤需要允许该 namespace 中的全部 Pod,因此不要同时加入 podSelector。

阻止出站流量,仅保留 DNS

创建 NetworkPolicy egress-dns-only。podSelector 为 app=web,policyTypes 为 [Egress],egress 的 to 是 namespaceSelector kubernetes.io/metadata.name=kube-system,端口包含 UDP 53 和 TCP 53 两项。

每个 namespace 都会自动带有一个值与其名称相同的标签。DNS 有时只允许 UDP 并不足够。

按 CIDR 允许并排除部分网段

创建 NetworkPolicy allow-cidr。podSelector 为 app=web,ingress 的 from 是 ipBlock cidr 10.0.0.0/16,except 中加入 10.0.5.0/24

ipBlock 包含 cidr 和 except。except 的网段必须位于 cidr 范围内。

综合:AND 条件与元数据网段阻断

创建 NetworkPolicy web-final。podSelector 为 app=web,policyTypes 为 [Ingress, Egress]。ingress 的 from 要在同一个条目中同时设置 namespaceSelector tier=client 和 podSelector app=frontend,端口为 TCP 8080。egress 的 to 是 ipBlock cidr 0.0.0.0/0,except 为 169.254.169.254/32,端口为 TCP 443。

将 from 拆成两个条目时是 OR,在同一条目中同时使用两个选择器时是 AND。一个连字符的位置就会改变含义。