想象一个新建成的小区——A 小区。物业管理处图省事,决定不装门禁、不设围墙,所有住户的大门常年敞开。起初大家相安无事,直到某天小偷溜进一户人家,顺走财物后,又轻轻松松串到隔壁几户——这时业主们才发现,敞开的门不叫便利,叫做隐患。这正是 Kubernetes 集群的默认写照。集群里的每个 Pod 就像一户人家,默认位于同一个扁平网络中,任意两个 Pod 之间都能直接通信,没有任何隔离。 要让小区安全,物业需要一套门禁系统:给每家贴上标签(如“业主”“租客”“快递员”),再写清楚“哪些人能进哪户人家”“哪户人家能拜访谁”。这套规则,就是 Kubernetes 里的 Network Policy(网络策略)。它用标签选择器锁定目标 Pod,用入站(ingress)/出站(egress)规则定义白名单,再交给 Calico、Cilium 这类 CNI 插件翻译成底层网络的“门卫指令”,最终实现零信任的微隔离——只有被明确允许的流量,才能通行。
掌握 NetworkPolicy 是云原生安全与零信任架构的必修课。无论你是运维工程师还是安全架构师,学会它就能精准管控集群东西向流量,抵御横向渗透,让“默认拒绝、最小授权”从口号变成可落地的配置。
目录
可视化演示
展示Kubernetes Network Policy的Pod间流量控制机制,可视化网络拓扑与策略规则,演示允许/拒绝流量如何通过标签选择器实现零信任网络隔离。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+modeCaptions.topo+'
默认全互通:敞开大门的隐患
A 小区刚交付时,物业没有装任何门禁,住户之间可以随意串门。今天你去邻居家借酱油,明天邻居来你家看球赛,大家觉得挺方便。可等到小偷光顾后,警方发现他盗窃的几户人家之间根本没有阻碍——小偷正是顺着“全通”的便利,一路偷了五家。Kubernetes 集群默认就是这个状态:所有 Pod 通过 CNI 网络插件接入一个扁平、全连通的虚拟网络,彼此之间不需要任何授权即可通信。
这种设计在 K8s 诞生之初是为了降低网络复杂度:每个 Pod 有独立 IP,应用之间仿佛在一台物理机上互访。但代价是,攻击者只要攻破任意一个 Pod,就能像小偷一样横向移动,轻易访问数据库、缓存、内部服务等所有目标,攻击面被无限放大。安全团队由此意识到:默认全通是便利,更是无法接受的敞口风险。
用集合论的语言说,集群的默认可达关系是一个完全图——任意两点之间都有一条边:
既然“完全图”不安全,物业(运维团队)决定引入门禁系统——这就是 NetworkPolicy 登场的背景。它不是为了打开通路,而是为了在默认全通的世界里,一点点剪出安全的形状。
- 全称量词与任意组合P_i 和 P_j 表示集群里任意两个 Pod,i 和 j 只是区分“源”与“目标”的下标,不限制具体数量。
- 可达箭头P_i → P_j 表示“从 Pod i 到 Pod j 的流量被默认允许”,这就是默认全通的直接体现。
- 完全可达边集E_cluster 是集群所有可达关系的集合,任意点对都属于它,数学上等价于完全图。
核心对象解析:门禁制度怎么写
物业要给小区装门禁,先得印一张“门禁制度表”。表格上写清楚:这条规则管哪几户(适用范围)、管进门还是出门(管控方向)、具体放行谁(细则)。NetworkPolicy 就是 Kubernetes 里的这张“制度表”,它本身是一份声明式 API 对象,不会自己执行任何拦截,只负责描述意图。
一个标准的 NetworkPolicy 长这样:
逐字段看:spec.podSelector 用标签挑选“本策略管哪批 Pod”,相当于门禁表上填的“适用房号”;policyTypes 声明策略管理的流量方向(Ingress 进、Egress 出);ingress 和 egress 是具体的放行细则。注意,如果 policyTypes 写了 Ingress 但 ingress 为空,就等于“没有放行任何入站流量”——这成为默认拒绝的机制来源。
策略的作用范围不是整个集群,而是被两层条件精确框定:
门禁制度的“适用范围”终于清晰了。但制度不能只约束一小部分人——它还得配合全小区的标准化设计。物业很快发现,要精准地“指认”每一户,光写房号不够,最靠谱的方式是给每户贴标签。
- 策略作用域Scope(P) 是策略 P 实际管理的 Pod 集合,所有后续规则都只在这个集合内生效。
- 命名空间边界N_P 是策略所在的命名空间,Pod 必须属于同一命名空间才会被纳入治理范围。
- 标签匹配集花括号内的集合表示“标签匹配选择器 S_P 的所有 Pod”,Match 函数返回真代表命中。
- 交集收窄两个条件取交集,命名空间不符或标签不匹配都会被排除在策略范围之外。
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: db-policy namespace: prodspec: podSelector: matchLabels: app: db policyTypes: [Ingress] ingress: - from: - podSelector: matchLabels: tier: fe ports: - protocol: TCP port: 5432
标签选择器术:门禁怎么认人
小区物业在每户门口贴了不同颜色的贴纸:红色是“业主”、蓝色是“租客”、黄色是“快递员”。门禁识别一个人的身份,不是看脸,而是读贴纸。K8s 的标签(Label)就是贴纸,标签选择器(Selector)就是读贴纸的规矩。NetworkPolicy 提供三种认人方式:podSelector 按 Pod 的标签选人,namespaceSelector 按命名空间的标签选区域,ipBlock 则直接按 IP 网段认人。
podSelector 是最常用的方式。它写在 ingress.from 或 egress.to 里,表示“来源/目标的标签长这样才算数”。namespaceSelector 则用于跨命名空间场景,比如只允许“监控命名空间”的 Pod 来访问本空间的数据库。ipBlock 是最后的硬核手段,通常用于放行集群外的固定 IP,比如办公室出口 IP。
这里最关键的是 matchLabels 的匹配语义:里面多个键值对是逻辑与(AND)关系,必须全部满足才命中。用数学表示:
标签贴纸设计好后,门禁不仅能“认人”,还能知道“这个人从哪来、到哪去”。接下来要做的是梳理每户的出入规则——入站管谁进来,出站管谁能出去。
- 遍历选择器条目S 是选择器包含的键值对集合,先逐个取出每一对 (k,v)。
- 单个标签比对p.labels_k = v 表示“Pod p 的 labels 字典中,键 k 的值必须正好等于 v”,只要有一个不符合,整个匹配失败。
- 逻辑与合并大写的和符号表示把所有条件的真假值做“与”运算,一票否决——这就是 matchLabels 多条件必须全中的原因。
入站出站规则:两张门禁登记表
物业给每户发了两张登记表:一张贴在门口,写下“允许哪些人进我屋”(入站规则);另一张放在玄关,写下“我可以去谁家”(出站规则)。人不能既当“进门者”又当“外出者”——流量也一样,必须分开管。NetworkPolicy 用 ingress 管理入站,egress 管理出站,policyTypes 决定本次策略管哪几张表。
入站规则的匹配逻辑用一句话概括:来源匹配,且端口匹配,才放行。这里的来源可以是 Pod 标签、命名空间标签、ipBlock 三者之一;端口则是 protocol + port 的组合。多条规则之间是或(OR)关系——只要命中任意一条规则就放行。出站规则同理,只是方向反过来了。
入站决策可以形式化地写成:
入站出站规则把“谁能访问谁”定义清楚了,但这套制度能不能运行,还取决于小区装的是哪家厂商的门禁设备。没有设备,制度就是废纸。CNI 插件就是那套门禁设备。
- 遍历入站规则集R_in 是策略里所有入站规则的集合,从第一条开始逐一评估。
- 来源匹配判断srcMatch(r, s) 检查来源 Pod s 是否满足规则 r 的 from 条件(标签、命名空间、IP 段三选一)。
- 端口匹配判断portMatch(r, port) 检查访问端口是否落在规则 r 的 ports 列表里,协议和端口号都要一致。
- 或逻辑合并大或号把所有规则的判断结果做“或”运算,只要出现一个真值,整体就是放行。
CNI 兼容差异:门禁设备选哪家
物业开招标会,三家厂商来投标。A 厂商(Calico)的方案是成熟的人脸识别闸机:将门禁制度逐条翻译成底层名单,社区公认稳定;B 厂商(Cilium)的方案是新一代指纹+虹膜识别:性能更强,还自带行为监控大屏;C 厂商(Flannel)的方案最便宜——但它根本没有门禁模块,只是把小区围墙修好了而已。K8s 的 NetworkPolicy 只是声明,真正落地必须靠 CNI 插件。
- Calico:网络插件中的老牌厂商,核心基于 iptables。将 NetworkPolicy 翻译成一套 Felix 规则写入 iptables 链,可靠且应用最广,适合对 eBPF 有顾虑的传统集群。
- Cilium:基于 eBPF 技术的新锐方案。策略查询用哈希表实现 O(1) 匹配,性能远超 iptables 的线性扫描,还提供 Hubble 可视化流量洞察,适合大规模和高性能场景。
- Flannel:仅提供扁平网络(overlay),不支持 NetworkPolicy。如果集群装了 Flannel,创建再多的 NetworkPolicy 也不会产生任何拦截效果。
策略声明到数据面的翻译过程,可以抽象成一个数学映射:
设备选好后,物业开始研究一套更先进的管理理念——不再相信任何人。哪怕对方是业主,也要每次验证身份。这就是零信任。
- 声明式策略NP 指 YAML 形式的 NetworkPolicy 对象,描述意图但不会自我执行。
- 翻译函数T_CNI 是 CNI 插件的翻译引擎——Calico 编译为 iptables 规则,Cilium 编译为 eBPF 字节码。
- 数据面规则R_datapath 是最终写入内核的底层规则,只有这些规则成立,网络流量才会被真正拦截或放行。
零信任微隔离:全员验证的时代
传统安全模型像小区旧规矩:“业主免检”。但物业复盘盗窃案后发现,小偷就是混在业主里的。于是新制度规定:任何人都不能被默认信任,每次访问必须出示有效凭证,凭白名单放行。这就是零信任网络的核心——永不信任,始终验证。NetworkPolicy 正是这套理念在 Kubernetes 中的承载者。
零信任落地时,最关键的一步是微隔离:不再按“集群边界”做一道大墙,而是把安全边界缩小到每个工作负载。每个 Pod 都是一个小小的安全域,默认拒绝所有流量,只对显式白名单放行。这样即使攻击者攻破了一个 Pod,本应横向移动的空间也被大幅压缩。
零信任的判决逻辑很简单,可以用分段函数表达:
理念执行起来需要落地模板。物业把“全验证”的门禁制度固化成几套标准化图纸,任何楼栋拿来就能用。NetworkPolicy 社区也沉淀了类似的策略模板库。
- 判决函数D(s,t) 对每一个源到目的连接返回决策结果,1 放行、0 拒绝。
- 白名单集合R+ 是所有显式策略允许的流量对的集合,它由多条 NetworkPolicy 叠加而成。
- 默认拒绝分支不在白名单里的流量一律落到 otherwise 分支,返回 0——这就是零信任的数学本质。
策略模板库:物业的标准化图纸
物业把门禁方案整理成三张标准图纸:图纸 A 是“本户全封闭”,图纸 B 是“只让同标签的人进”,图纸 C 是“隔离不同楼栋”。遇到类似情况,直接套图纸,不用每次重新设计。K8s 运维中,NetworkPolicy 也有几个高频复用模板。
图纸 A:拒绝全部入站——这是零信任的起点。将 policyTypes 设为 Ingress,且不写任何 ingress 规则:
这条策略一经创建,所有访问 app: web Pod 的入站流量全部被拒绝。它单独存在时几乎没有意义,但放在应用的最外层,就能先“一刀切”,再逐条加白名单。
图纸 B:同标签白名单放行——在拒绝全部的基础上,允许前端访问后端:
图纸 C:命名空间隔离——利用 namespaceSelector 只允许“监控”命名空间访问,其余流量全部拒绝,实现不同团队之间的网络隔离。
拒绝全部模板的数学本质是空规则集必然导出拒绝:
标准图纸减少了重复设计,但门禁系统运行久了,偶尔也会出故障:明明装了闸机,为什么有人还能自由进出?物业开始排查,这就到了运维排错和性能调优的环节。
- 空规则集R_in 为空说明策略没有配置任何放行规则,白名单是空白状态。
- 全称限定对集群中任意来源 Pod s,该结论都成立,不因命名空间或节点位置改变。
- 必然拒绝推导结论是对所有入站流量执行 Deny,这就是“不写规则就是拒绝全部”的机制原理。
spec: podSelector: matchLabels: app: web policyTypes: [Ingress]
spec: podSelector: matchLabels: app: api policyTypes: [Ingress] ingress: - from: - podSelector: matchLabels: tier: fe
排错性能调优:门禁失灵怎么办
物业接到投诉:B 栋的门禁形同虚设。排查顺序往往是:先看闸机有没有通电(CNI 是否支持),再看登记表是否贴错门牌(选择器是否命中),最后看是不是两套制度互相覆盖(多策略叠加)。这套方法论同样适用于 NetworkPolicy 排错。
第一步:确认 CNI 支持。如果集群用的是 Flannel,策略根本不会执行。检查 kubectl get networkpolicy 能看到对象,但数据面无感,这是最隐蔽的坑。第二步:核对选择器标签。用 kubectl get pods --show-labels 确认目标 Pod 的标签是否与 podSelector 完全匹配,多一个空格、少一个键都会导致范围错误。第三步:检查规则覆盖。由于多策略是“或”逻辑,当一个 Pod 被多条策略命中时,只要有一条放行就通了,需要逐一检查所有相关策略。
关于性能,iptables 实现有一个先天短板——规则按顺序线性匹配。规则越多,每个数据包需要检查的条目就越多,延迟随之线性上升:
排查有方法论、性能有量化公式——门禁系统总算可以稳定运转了。从 A 小区到 K8s 集群,用一套门禁制度收编了默认全通的混乱,这正是 NetworkPolicy 的价值。
- 单条规则耗时t_i 是内核针对第 i 条 iptables 规则的匹配时间,通常与规则复杂度有关。
- 累加求和总耗时是 1 到 n 条规则耗时的总和,逐条顺序匹配决定了它必然随规则数增长。
- 线性复杂度O(n) 表示规则数翻倍,匹配时间大致翻倍。这就是大规模集群推荐 Cilium(哈希查表 O(1))的原因。
AI 应用场景
多租户 SaaS 平台网络隔离
阶段:基础设施安全管控
解决的问题:SaaS 平台常把不同客户(租户)的工作负载部署在同一个 K8s 集群中,传统方式依赖网络防火墙或 VLAN 划分,配置分散、与 Pod 生命周期脱节;一旦某个租户的 Pod 被攻破,威胁可能蔓延到其他租户。
具体案例:某 SaaS 厂商在共享集群中为每个租户建立独立命名空间,并用 Namespace 标签(如 tenant=a、tenant=b)标记。运维团队创建一组模板化 NetworkPolicy,在“拒绝全部入站”的基础上,只放行同租户命名空间内 tier: fe 到 tier: be 的流量,并结合 egress 限制 Pod 只能访问允许的外部 API 网关。租户间被彻底微隔离,横向移动路径被切断。
金融行业零信任合规建设
阶段:安全架构设计与合规
解决的问题:金融行业监管要求“最小权限、访问可控”,传统方式依赖人工维护防火墙策略,无法追踪工作负载级别的访问关系,审计时难以自证合规。
具体案例:某银行容器平台上线 Cilium 作为 CNI,将每项业务按标签(app=payment、app=ledger)建模。安全团队在默认拒绝策略之上,仅放行支付网关访问核心账务系统的 8080 端口,并开启 Hubble 采集全量通信日志。审计人员可随时导出“谁在什么时间访问了账务 Pod”的完整链路,顺利通过等保测评。
大规模集群东西向流量可观测
阶段:可观测性与故障诊断
解决的问题:集群规模超过千节点后,iptables 规则膨胀带来性能衰减,且策略出错时很难定位“哪条规则放行了预期外的流量”。
具体案例:某互联网公司使用 Calico 时频繁出现服务间访问超时,SRE 用 kubectl describe networkpolicy 比对策略,再用 calicoctl get policy 核查数据面下发状态;后来切换 Cilium,借助 Hubble 的 Flow 视图,在 10 分钟内定位到一条多余的宽松 egress 规则,并借助 cilium policy trace 精确预测策略变更的影响面。
Python 演示
#!/usr/bin/env python3"""用 Python 模拟 K8s NetworkPolicy 的入站决策过程。 场景:微服务应用包含 web/api/db/cache 四个 Pod,加上一条 NetworkPolicy 后,逐个判断任意两个 Pod 之间的 8080 端口访问是否放行。""" class Pod: def __init__(self, name, labels, namespace="default"): self.name = name self.labels = labels self.namespace = namespace def __repr__(self): return "%s/%s" % (self.namespace, self.name) def labels_match(actual, selector): """selector 是 {key: value} 字典,全部键值都要命中(AND 语义)。""" if not selector: return True return all(actual.get(k) == v for k, v in selector.items()) def ingress_allowed(source, target, port, ingresses): """按 NetworkPolicy 的 ingress 语义判断:来源匹配 AND 端口匹配才放行。""" for rule in ingresses: src_ok = False if not rule.get("from"): src_ok = True for item in rule.get("from", []): if "podSelector" in item: src_ok |= labels_match(source.labels, item["podSelector"].get("matchLabels")) if "namespaceSelector" in item: src_ok |= labels_match({"ns": source.namespace}, item["namespaceSelector"].get("matchLabels")) port_ok = False if not rule.get("ports"): port_ok = True for p in rule.get("ports", []): if p.get("port") == port: port_ok = True if src_ok and port_ok: return True return False def main(): pods = [ Pod("web", {"app": "web", "tier": "fe"}), Pod("api", {"app": "api", "tier": "be"}), Pod("db", {"app": "db", "tier": "be"}), Pod("cache", {"app": "cache", "tier": "be"}), Pod("monitor", {"app": "monitor"}, namespace="ops"), ] policy = { "spec": { "podSelector": {"matchLabels": {"tier": "be"}}, "ingress": [ { "from": [{"podSelector": {"matchLabels": {"tier": "fe"}}}], "ports": [{"port": 8080}], } ], } } targets = [p for p in pods if labels_match(p.labels, policy["spec"]["podSelector"]["matchLabels"])] print("NetworkPolicy 命中的目标 Pod:", targets) print("模拟入站流量 8080 端口判决(来源 -> 目标 : 结果)") for target in targets: for source in pods: if source is target: continue result = ingress_allowed(source, target, 8080, policy["spec"].get("ingress", [])) print(" %-8s -> %-8s : %s" % (source.name, target.name, "ALLOW" if result else "DENY")) if __name__ == "__main__": main()
class Pod定义网络策略中的“房屋”:包含名称、标签、命名空间,等价于 K8s Pod 的核心属性。labels_match(actual, selector)实现 matchLabels 的 AND 语义:选择器里所有键值对必须全部命中。ingress_allowed(...)实现 K8s ingress 引擎:先用 from 判断来源,再用 ports 判断端口,两者同时满足才放行。policy = {...}声明式 NetworkPolicy:podSelector 选目标,ingress 定义白名单规则。targets = [p for p in pods if ...]用选择器筛选策略管理的目标 Pod 集合。if __name__ == "__main__":提供可执行入口,直接运行即可观察每对 Pod 的判决结果。
常见误区
误区创建一条 NetworkPolicy 就自动实现安全防护,相当于给 Pod 装上了防火墙,恶意流量会被拦截。
正解NetworkPolicy 只是一份声明式“规则单”,本身不执行任何拦截。真正落地必须靠 CNI:Calico 翻译成 iptables,Cilium 翻译成 eBPF。如果集群用的是 Flannel,策略写再多也不会生效。这就像物业贴了门禁制度,但闸机没有安装,制度就是一张废纸。
为何常见:看到"NetworkPolicy"这个名字,直觉认为它是 K8s 自带的防火墙组件,忽略了它在架构上只是 API 声明、由插件执行的事实。
误区多个 NetworkPolicy 同时命中一个 Pod 时,流量必须通过所有策略的检查才能放行,多策略叠加会让网络越来越严格。
正解多个 NetworkPolicy 取的是并集,只要任意一条策略放行了该流量,它就能通行;只有所有策略都拒绝,流量才真正被拒绝。这是“或”逻辑,而不是“与”逻辑。实际排查时经常发现:预期拒绝的流量被另一条宽松策略放行了。
为何常见:把策略类比成防火墙规则链,认为必须逐个通过;实际上 K8s 的语义是“有一条允许则放行”。
误区没有配置 NetworkPolicy 的 Pod 会自动被集群隔离,外部无法访问。
正解K8s 集群默认所有 Pod 全互通。只有当一个 Pod 被 NetworkPolicy 选中后,它才进入“受管理”状态,对应 policyTypes 的流量才默认拒绝。没有策略的 Pod 依然暴露在完全图之中。
为何常见:零信任理念深入人心,容易让人误以为集群默认是封锁的,而 K8s 的真实初始态是“默认全通、显式隔离”。
误区Flannel 是 CNI 插件,而 NetworkPolicy 是 K8s 标准 API,所以装了 Flannel 就能直接使用网络策略。
正解Flannel 只负责提供扁平 overlay 网络,内部没有策略执行引擎。K8s 的 API 层可以接受 NetworkPolicy 对象,但数据面不会产生任何规则。要获得策略能力,需要叠加 Calico 的策略组件或整体更换 CNI。
为何常见:混淆了“网络连通”和“策略执行”两个不同层次,未验证 CNI 的能力边界就误判策略已生效。
误区`matchLabels` 里同时写了 app=web 和 tier=fe,只要满足其中一个标签就能选中。
正解matchLabels 的所有键值对是逻辑与关系,必须全部满足才会选中目标 Pod。如果要表达“任一”的语义,需要拆成多条规则或利用 matchExpressions 的 In 操作符。
为何常见:把 YAML 的列表语义(多条 ingress 规则之间是 OR)错误迁移到 matchLabels 的字段内部,混淆了两套不同的逻辑。
面试题
Q1. K8s 集群中 Pod 之间默认的网络联通性是?
- A.默认隔离,需建策略才互通
- B.默认全通,需建策略才隔离← 正确答案
- C.默认拒绝所有外部流量
- D.取决于节点位置与网段
答案:B。K8s 的 CNI 网络插件把 Pod 放进扁平网络,默认完全双向可达,隔离不存在。NetworkPolicy 的唯一使命就是打破全通、创造隔离,选项 B 正确,A/C/D 都与默认行为不符。
Q2. NetworkPolicy 的 spec.podSelector 作用是什么?
- A.选择策略作用的 Pod← 正确答案
- B.选择集群的 Node
- C.选择命名空间
- D.选择外部 IP 段
答案:A。podSelector 用标签筛选本策略管理的目标 Pod,是策略作用域的第一层。Node、命名空间和外部 IP 都是由其他字段(namespaceSelector、ipBlock)负责,均不符合。
Q3. 一条 NetworkPolicy 的 policyTypes 包含 Ingress 但没有写任何 ingress 规则,入站流量会怎样?
- A.全部放行
- B.全部拒绝← 正确答案
- C.只放行同空间流量
- D.只放行集群外流量
答案:B。policyTypes 声明管理 Ingress 后,若对应规则为空,相当于空规则集,默认拒绝所有入站流量。这正是“拒绝全部”模板的机制来源,B 正确。
Q4. 以下哪些 CNI 插件支持 NetworkPolicy?
- A.Flannel
- B.Calico← 正确答案
- C.Cilium← 正确答案
- D.Docker bridge
答案:BC。Calico 用 iptables/Felix 翻译策略,Cilium 用 eBPF 实现高性能策略,两者原生支持。Flannel 是纯 overlay 网络不带策略引擎,Docker bridge 网络也不参与 K8s 集群的网络策略执行。
Q5. spec.ingress 里配置了 from 和 ports 都非空,流量要放行必须满足什么?
- A.来源匹配且端口匹配← 正确答案
- B.来源匹配或端口匹配
- C.端口必须全部匹配
- D.来源必须是 Pod
答案:A。一条 ingress 规则内部,from 与 ports 是 AND 关系,来源和端口都命中才放行;多条规则之间才是 OR 关系。A 正确,B/C/D 的表述不完整或不准确。
Q6. 关于多个 NetworkPolicy 同时匹配同一个 Pod,行为正确的是?
- A.多条策略取并集← 正确答案
- B.任一策略允许即放行← 正确答案
- C.全部策略拒绝才拒绝← 正确答案
- D.后创建的策略覆盖前者
答案:ABC。K8s 多策略叠加的语义是“或”:存在一条允许就放行,只有全部拒绝才拒绝,A/B/C 正确。策略之间不存在先后覆盖关系,D 错误。
Q7. namespaceSelector 匹配的对象是?
- A.Pod 的标签
- B.Node 的标签
- C.命名空间的标签← 正确答案
- D.集群的标签
答案:C。namespaceSelector 读取命名空间对象上的标签,用来限制跨命名空间的来源或目标。它不匹配 Pod、Node 或集群级标签,C 正确。
Q8. 要让 Pod 能够访问公网上的一个固定 IP 服务,应该定义?
- A.ingress 的 ipBlock
- B.egress 的 ipBlock← 正确答案
- C.namespaceSelector 匹配
- D.无需任何策略
答案:B。访问公网属于出站流量,需要在 egress 规则中用 to + ipBlock 指定目的网段(如特定 CIDR)。ingress 管的是入站,namespaceSelector 管的是命名空间范围,答案 B 正确。
Q9. matchLabels 里同时有 app=web 和 tier=fe,选中目标 Pod 的条件是?
- A.满足任意一个即可
- B.两个都满足才选中← 正确答案
- C.满足 app=web 优先
- D.满足 tier=fe 优先
答案:B。matchLabels 内多个键值对语义是逻辑与,所有标签必须全部命中才选中。选项 A 混淆了“规则之间是或”与“标签之间是与”两套逻辑,C/D 不存在优先级概念。
Q10. 关于 NetworkPolicy 的性能与排错,正确的说法是?
- A.iptables 规则越多匹配越慢← 正确答案
- B.Cilium 的 eBPF 性能更优← 正确答案
- C.策略越多对性能零影响
- D.必须用流量镜像才能排错
答案:AB。iptables 按链顺序线性匹配,复杂度 O(n),规则越多时延越大,A 正确;Cilium 用哈希表近似 O(1) 查表,B 正确。策略不可能零开销,C 错误;排错可以用 kubectl describe、calicoctl 或 cilium policy trace 等工具,D 错误。