LabHub
学习 学习路径 课程

CCA — Cilium 认证助理

从默认拒绝一路垒到 L7

在 LabHub 中继续学习

目标

实际应用标准 NetworkPolicy,实现默认拒绝和基于选择器的允许规则;并以清单形式编写只有 CiliumNetworkPolicy 才能实现的 L7、FQDN 和显式拒绝规则。

为什么这很重要

网络策略 apply 成功,并不保证其行为符合预期。尤其有三点会悄无声息地误导人。

第一,各方向相互独立。如果只配置 ingress 策略就认为已经“隔离”,egress 仍然对整个互联网开放。数据泄露路径大多位于 egress 方向。

第二,选择器拼写错误不会报错,而是以“未选择任何对象”的方式静默失败。应用策略后,必须确认实际有多少端点处于强制执行状态。

第三,**toFQDNs 没有 DNS 规则就永远无法匹配。**这是 Cilium 策略中最常见的配置错误,也会在考试中反复出现。

标准 NetworkPolicy 需要实际 apply;CiliumNetworkPolicy 则写成 /root/cca-policy/ 下的文件。这是因为实验集群中没有安装 Cilium CRD,而考试要求的能力同样是准确编写清单。

步骤

  1. 创建 namespace cca-shopcca-mon,并为 cca-mon 添加标签 tier=monitoring
  2. 在 namespace cca-shop 中分别部署 1 个副本的 Deployment frontendbackend。Pod 标签分别为 app=frontendapp=backend,镜像为 nginx:1.27-alpine。然后创建 Service backend,端口为 8080
  3. 在 namespace cca-shop 中创建 NetworkPolicy default-denypodSelector 为空,policyTypes 同时填写 IngressEgress,且不设置任何允许规则。
  4. 在同一 namespace 中创建 NetworkPolicy allow-frontend-to-backendpodSelectorapp=backendpolicyTypes 仅为 Ingress;ingress 规则只允许来自 podSelectorapp=frontend 的来源访问端口 8080 / 协议 TCP
  5. 在同一 namespace 中创建 NetworkPolicy allow-monitoringpodSelectorapp=backend;ingress 规则的 from 项仅包含一个 namespaceSelector,选择 tier=monitoring 的 namespace,端口为 9090
  6. /root/cca-policy/cnp-l7.yaml 中编写 CiliumNetworkPolicy。apiVersioncilium.io/v2metadata.namespacecca-shopendpointSelectorapp: backend。ingress 规则的 fromEndpointsapp: frontend,并在 toPorts 的端口 8080/TCP 下为 rules.http 设置两个条目:第一个为 method GET / path /api/v1/orders,第二个为 method POST / path /api/v1/orders
  7. /root/cca-policy/cnp-fqdn.yaml 中编写 CiliumNetworkPolicy。endpointSelectorapp: frontend,egress 规则必须恰好有两条。第一条为 toEndpointsk8s-app: kube-dns 的目标开放端口 53/UDP,并在 rules.dns 中设置 matchPattern: "*"。第二条中,toFQDNsmatchNameapi.pgprovider.example,并开放端口 443/TCP。
  8. /root/cca-policy/cnp-deny.yaml 中编写名为 block-metadata 的 CiliumNetworkPolicy。endpointSelector 为空;在 egress 规则中通过 toCIDRSet 允许 cidr: 0.0.0.0/0,但在 except 中加入 169.254.169.254/32;此外,还要在 egressDenytoCIDR 中明确写入 169.254.169.254/32

参考

创建应用与监控 namespace

创建 namespace cca-shopcca-mon,并为 cca-mon 添加标签 tier=monitoring

namespaceSelector 只能查看 namespace 的标签,不能按名称选择,因此请事先添加标签。

部署前端和后端

在 namespace cca-shop 中分别部署 1 个副本的 Deployment frontendbackend。Pod 标签分别为 app=frontendapp=backend,镜像为 nginx:1.27-alpine。然后创建 Service backend,端口为 8080

策略通过标签选择对象。Pod 模板中的 app 标签必须准确,后续所有步骤才能正确衔接。

创建双向默认拒绝

在 namespace cca-shop 中创建 NetworkPolicy default-denypodSelector 为空,policyTypes 同时填写 IngressEgress,且不设置任何允许规则。

两个方向相互独立。只写一侧时,另一方向仍然完全开放。不要添加任何允许规则。

通过 Pod 选择器只开放一条路径

在同一 namespace 中创建 NetworkPolicy allow-frontend-to-backendpodSelectorapp=backendpolicyTypes 仅为 Ingress;ingress 规则只允许来自 podSelectorapp=frontend 的来源访问端口 8080 / 协议 TCP

策略中的 podSelector 选择接收流量的一方,from 中的 podSelector 选择发送流量的一方。此步骤只允许同一 namespace 内的来源,因此不要同时添加 namespaceSelector。

通过 namespace 选择器向其他 namespace 开放

在同一 namespace 中创建 NetworkPolicy allow-monitoringpodSelectorapp=backend;ingress 规则的 from 项仅包含一个 namespaceSelector,选择 tier=monitoring 的 namespace,端口为 9090

使用第 1 步添加的 namespace 标签。要开放的是指标端口,而不是应用端口。

按 HTTP 方法和路径进行限制

/root/cca-policy/cnp-l7.yaml 中编写 CiliumNetworkPolicy。apiVersioncilium.io/v2metadata.namespacecca-shopendpointSelectorapp: backend。ingress 规则的 fromEndpointsapp: frontend,并在 toPorts 的端口 8080/TCP 下为 rules.http 设置两个条目:第一个为 method GET / path /api/v1/orders,第二个为 method POST / path /api/v1/orders

这是标准 NetworkPolicy 无法实现的领域。请在 toPorts 下设置 rules.http,并列出方法和路径。不匹配的请求不会以连接中断的形式被阻止,而是返回 403。

按域名允许访问外部 API

/root/cca-policy/cnp-fqdn.yaml 中编写 CiliumNetworkPolicy。endpointSelectorapp: frontend,egress 规则必须恰好有两条。第一条为 toEndpointsk8s-app: kube-dns 的目标开放端口 53/UDP,并在 rules.dns 中设置 matchPattern: "*"。第二条中,toFQDNsmatchNameapi.pgprovider.example,并开放端口 443/TCP。

只使用 toFQDNs 绝对无法工作。DNS 代理必须获知响应,才能登记 IP,因此必须同时提供一条允许 DNS 查询并将其纳入观测的规则。

封锁元数据端点

/root/cca-policy/cnp-deny.yaml 中编写名为 block-metadata 的 CiliumNetworkPolicy。endpointSelector 为空;在 egress 规则中通过 toCIDRSet 允许 cidr: 0.0.0.0/0,但在 except 中加入 169.254.169.254/32;此外,还要在 egressDenytoCIDR 中明确写入 169.254.169.254/32

同时使用在允许规则中划出例外的方法,以及再叠加一层显式拒绝的方法。deny 优先于 allow,因此这两层并不相互矛盾。