
Cilium Service Mesh 实战Ingress 接入 CiliumNetworkPolicy 的完整网络策略示例【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium本文基于 Cilium 仓库中的 Ingress and Network Policy Example 示例文档完整还原“Cilium Ingress 网络策略”的实战路径先部署 Istio 经典的bookinfo演示应用与基础 HTTP Ingress再在其之上叠加CiliumNetworkPolicy实现外部流量锁定lock-down与默认拒绝default deny两种安全基线并通过 Hubble 观测被丢弃的流量。读完后你可以掌握Cilium Ingress 的两种负载均衡模式、reserved:ingress实体身份在策略中的用法、CiliumClusterwideNetworkPolicy中fromEntities、fromCIDRSet、toEntities等字段的实际语义以及策略生效与否的验证手段curl返回码 hubble observe流日志。一、部署 bookinfo 演示应用无 Sidecar 前提示例复用了 Istio 项目的bookinfo演示微服务应用作为被保护的业务$ kubectl apply -f bookinfo.yaml # Istio release-1.11 的 samples/bookinfo/platform/kube/bookinfo.yaml应用部署完成后各微服务 Pod 为单容器形态。这一点是理解 Cilium Service Mesh 与 sidecar 方案差异的关键$ kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-5498c86cf5-kjzkj 1/1 Running 0 2m39s productpage-v1-65b75f6885-ff59g 1/1 Running 0 2m39s ratings-v1-b477cf6cf-kv7bh 1/1 Running 0 2m39s reviews-v1-79d546878f-r5bjz 1/1 Running 0 2m39s reviews-v3-6dd79655b9-nhrnh 1/1 Running 0 2m39s原文档特别指出这里只是部署演示应用没有引入任何 Istio 组件每个微服务旁边不会创建 Envoy sidecarPod 的 READY 状态是1/1而在 sidecar 实现中会显示2/2一个微服务容器 一个 Envoy sidecar 容器。也就是说后续的流量入口由 Cilium 托管的 Ingress 网关承担而非 sidecar 注入模式。二、部署基础 Ingress 并验证入口仓库中的 basic-ingress.yaml 定义了本例的 IngressapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: basic-ingress namespace: default spec: ingressClassName: cilium rules: - http: paths: - backend: service: name: details port: number: 9080 path: /details pathType: Prefix - backend: service: name: productpage port: number: 9080 path: / pathType: Prefix要点说明ingressClassName: cilium声明该 Ingress 由 Cilium Ingress 控制器处理/details前缀路由到details:9080服务/前缀路由到productpage:9080服务路径匹配类型为Prefix。应用方式$ kubectl apply -f examples/kubernetes/servicemesh/basic-ingress.yaml应用后Cilium 会为该 Ingress 自动创建一个 LoadBalancer 类型的 Service云提供商会自动分配外部 IP约需 30 秒。两种负载均衡模式下的表现不同# 独占dedicated负载均衡模式每个 Ingress 对应一个 Service $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress-basic-ingress LoadBalancer 10.98.169.125 10.98.169.125 80:32478/TCP 2m11s details ClusterIP 10.102.131.226 none 9080/TCP 2m15s productpage ClusterIP 10.97.231.139 none 9080/TCP 2m15s ratings ClusterIP 10.108.152.42 none 9080/TCP 2m15s reviews ClusterIP 10.111.145.160 none 9080/TCP 2m15s # 共享shared负载均衡模式所有 Ingress 共用一个 cilium-ingress Service $ kubectl get services -n kube-system cilium-ingress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress LoadBalancer 10.98.169.125 10.98.169.125 80:32690/TCP,443:31566/TCP 18m外部 IP 同时会回填到 Ingress 资源上$ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE basic-ingress cilium * 10.98.169.125 80 97s注意部分云厂商如 EKS回填的是完全限定域名FQDN而非 IP。确认入口工作$ HTTP_INGRESS$(kubectl get ingress basic-ingress -o jsonpath{.status.loadBalancer.ingress[0].ip}) $ curl --fail -s http://$HTTP_INGRESS/details/1 | jq { id: 1, author: William Shakespeare, year: 1595, type: paperback, pages: 200, publisher: PublisherA, language: English, ISBN-10: 1234567890, ISBN-13: 123-1234567890 }三、外部锁定策略只允许集群内部访问 Ingress默认情况下所有外部流量都是被允许的。为了收紧边界仓库提供了 external-lockdown.yamlapiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: external-lockdown spec: description: Block all the traffic originating from outside of the cluster endpointSelector: {} ingress: - fromEntities: - cluster$ kubectl apply -f examples/kubernetes/servicemesh/policy/external-lockdown.yaml策略语义endpointSelector: {}空选择器匹配集群内所有受管端点ingress中仅允许fromEntities: [cluster]即只放行来自集群内部的流量。应用后来自集群外部的请求被 Envoy 直接拒绝为403 Forbidden$ curl --fail -v http://$HTTP_INGRESS/details/1 * Trying 172.18.255.194:80... * Connected to 172.18.255.194 (172.18.255.194) port 80 GET /details/1 HTTP/1.1 Host: 172.18.255.194 HTTP/1.1 403 Forbidden content-length: 15 content-type: text/plain server: envoy * The requested URL returned error: 403用 Hubble 可在另一终端确认策略层的行为——请求在数据面被DROPPED而 403 响应则是策略拒绝后的正常回包FORWARDED$ kubectl --namespacekube-system exec -i -t cilium-xjl4x -- hubble observe -f --identity ingress Feb 29 13:00:29.389: 172.18.0.1:53866 (ingress) - kube-system/cilium-ingress:80 (world) http-request DROPPED (HTTP/1.1 GET http://172.18.255.194/details/1) Feb 29 13:00:29.389: 172.18.0.1:53866 (ingress) - kube-system/cilium-ingress:80 (world) http-response FORWARDED (HTTP/1.1 403 0ms (GET http://172.18.255.194/details/1))验证集群内部流量不受影响。仓库中的 test-application.yaml 提供了一个内置curl的客户端 Deploymentdeployment/client$ kubectl apply -f examples/kubernetes/servicemesh/envoy/test-application.yaml $ kubectl exec -it deployment/client -- curl -s http://$HTTP_INGRESS/details/1 {id:1,author:William Shakespeare,year:1595,type:paperback,pages:200,publisher:PublisherA,language:English,ISBN-10:1234567890,ISBN-13:123-1234567890}变体仅放行特定 CIDR 的外部流量如果需求是“只允许特定来源 IP 访问 Ingress”可以用 allow-ingress-cidr.yamlapiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: allow-cidr spec: description: Allow all the traffic originating from a specific CIDR endpointSelector: matchExpressions: - key: reserved:ingress operator: Exists ingress: - fromCIDRSet: # 请改成你环境中实际的外部网段 - cidr: 172.18.0.1/32这里的选择器reserved:ingress是 Cilium 的保留实体标签专门选中 Cilium Ingress 网关本身从源码结构看Cilium 为 Ingress 网关端点打上reserved:ingress身份策略引擎据此把策略只约束在入口网关上fromCIDRSet则按来源 CIDR 放行。应用后该 CIDR 内的来源可以正常访问$ kubectl apply -f examples/kubernetes/servicemesh/policy/allow-ingress-cidr.yaml $ curl -s --fail http://$HTTP_INGRESS/details/1 {id:1,author:William Shakespeare,year:1595,type:paperback,pages:200,publisher:PublisherA,language:English,ISBN-10:1234567890,ISBN-13:123-1234567890}四、默认拒绝策略deny-by-default 与放行恢复更强硬的安全基线是“默认拒绝所有流量”。default-deny.yaml 给出了一条全集群级策略--- apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: default-deny spec: description: Block all the traffic (except DNS) by default egress: - toEndpoints: - matchLabels: io.kubernetes.pod.namespace: kube-system k8s-app: kube-dns toPorts: - ports: - port: 53 protocol: UDP rules: dns: - matchPattern: * endpointSelector: matchExpressions: - key: io.kubernetes.pod.namespace operator: NotIn values: - kube-system策略解析作用范围所有非kube-system命名空间的端点endpointSelector使用NotIn排除 kube-system一旦该策略存在被选中端点的入站和出站默认全部拒绝这是 Cilium 网络策略“存在即拒绝”的语义唯一显式放行的是DNS 查询UDP 53、matchPattern: *到kube-system中k8s-app: kube-dns的端点。保留 DNS 放行是这类默认拒绝策略的常见做法避免把集群的域名解析一并打挂。$ kubectl apply -f examples/kubernetes/servicemesh/policy/default-deny.yaml现象外部与内部流量双双被拒外部请求$ curl --fail -v http://$HTTP_INGRESS/details/1 GET /details/1 HTTP/1.1 HTTP/1.1 403 Forbidden server: envoyHubble 侧的流日志同样显示请求被丢弃Mar 17 13:56:00.709: 172.19.0.1:34104 (ingress) - default/cilium-ingress-basic-ingress:80 (world) http-request DROPPED (HTTP/1.1 GET http://172.19.255.194/details/1) Mar 17 13:56:00.709: 172.19.0.1:34104 (ingress) - default/cilium-ingress-basic-ingress:80 (world) http-response FORWARDED (HTTP/1.1 403 0ms (GET http://172.19.255.194/details/1))内部请求也被拒$ kubectl exec -it deployment/client -- curl -s http://$HTTP_INGRESS/details/1 Access denied根因Ingress 网关自身的出站被默认拒绝挡住了注意此时集群内部流量同样失败。原因在于 Cilium Ingress 的流量模型入口网关带reserved:ingress身份的端点位于kube-system它作为代理进程收到外部/内部请求后还要以自身身份发起对后端服务如details、productpage的出站请求。而上面的default-deny策略中endpointSelector排除了kube-system但策略是CiliumClusterwideNetworkPolicy其“存在即拒绝”的语义会影响全部端点之间的通信判定——网关到后端的 egress 没有被任何显式规则放行因此整条链路断裂。原文档给出的结论很明确Cilium Ingress 属于网络基础设施的一部分最稳妥的做法是放行reserved:ingress身份到所有cluster身份的出站流量即 allow-ingress-cluster.yaml--- apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: allow-ingress-egress spec: description: Allow all the egress traffic from reserved ingress identity to any endpoints in the cluster endpointSelector: matchExpressions: - key: reserved:ingress operator: Exists egress: - toEntities: - cluster$ kubectl apply -f examples/kubernetes/servicemesh/policy/allow-ingress-cluster.yaml应用后外部与内部访问都恢复正常且仍保持“默认拒绝”的其他部分不被放宽$ curl -s --fail http://$HTTP_INGRESS/details/1 {id:1,author:William Shakespeare,year:1595,type:paperback,pages:200,publisher:PublisherA,language:English,ISBN-10:1234567890,ISBN-13:123-1234567890} $ kubectl exec -it deployment/client -- curl -s http://$HTTP_INGRESS/details/1 {id:1,author:William Shakespeare,year:1595,type:paperback,pages:200,publisher:PublisherA,language:English,ISBN-10:1234567890,ISBN-13:123-1234567890}原文档还补充了一条替代思路也可以为reserved:ingress选择器逐条允许它到各个具体身份identity的出站但原文档认为“允许reserved:ingress身份到所有cluster身份”更可靠理由正是 Ingress 网关是网络基础设施组件其需要访问的后端集合随 Ingress 规则动态变化逐条枚举容易漏放。五、验证手段小结本例全程使用了两类可验证的观测手段值得作为排查模板应用层返回码策略拒绝时 Envoy 返回403 Forbidden外部或Access denied内部客户端放行后返回正常的 JSON 业务数据Hubble 流日志hubble observe -f --identity ingress能区分DROPPED数据面按策略丢弃与FORWARDED正常转发包括拒绝后的 403 回包并直接展示带身份标签的端点例如kube-system/cilium-ingress:80 (world)、default/cilium-ingress-basic-ingress:80便于确认策略命中在哪一侧。从本示例可以提炼出部署 Cilium Service Mesh Ingress 场景下的策略编写模式场景策略类型关键选择器/字段只允许集群内访问入口CiliumClusterwideNetworkPolicyendpointSelector: {}ingress.fromEntities: [cluster]只允许特定来源 CIDRCiliumClusterwideNetworkPolicyreserved:ingress选择器 ingress.fromCIDRSet默认拒绝基线CiliumClusterwideNetworkPolicy非 kube-system 端点 仅放行 DNS egress修复 Ingress 网关出站CiliumClusterwideNetworkPolicyreserved:ingress选择器 egress.toEntities: [cluster]完整文档脉络可继续参考 ingress-and-network-policy.rst 及其引用的 demo-app.rst、basic-ingress.rst、external-ingress-policy.rst、default-deny-ingress-policy.rst策略 YAML 均位于 examples/kubernetes/servicemesh/policy/ 目录Ingress 定义见 examples/kubernetes/servicemesh/basic-ingress.yaml客户端验证 Pod 见 examples/kubernetes/servicemesh/envoy/test-application.yaml。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考