10 | 容器网络:CNI、Service 与 Ingress 系列专栏《深入剖析 Kubernetes》· 基于张磊极客时间专栏思想整理 · 适合 CSDN 发布10 | 容器网络CNI、Service 与 IngressK8s 网络是整个体系里最容易被劝退的一块但抓住主线就清晰了每个 Pod 一个独立 IP所有 Pod 扁平互通Service 解决服务发现与负载均衡Ingress 解决七层路由。本文从模型到组件逐层拆解。一、容器网络模型每个 Pod 独立 IP、扁平互通K8s 对网络有一条硬性约定“网络模型”任意 Pod 可以不经 NAT 直接访问任意其他 Pod无论是否在同节点。任意节点可以不经 NAT 访问其上的任意 Pod。Pod 看到的自己 IP和别人看到的它 IP一致。实现方式是每个 Pod 拥有独立网络命名空间netns和独立 IP同一个 Pod 内多个容器共享这个 netns通过pause容器兜底所以容器内用localhost即可互访。节点上通常有一个虚拟网桥如 cni0Pod 的 veth 一端在 Pod 内、一端插在网桥上从而实现同节点 Pod 二层互通跨节点则交给 CNI 插件打通路由。---------------------------------- ---------------------------------- | Node A (10.0.0.11) | | Node B (10.0.0.12) | | | | | | --------- --------- | | --------- --------- | | | Pod-1 | | Pod-2 | | | | Pod-3 | | Pod-4 | | | | 10.244 | | 10.244 | | | | 10.244 | | 10.244 | | | -------- -------- | | -------- -------- | | | | | | | | | | ---- ---- | | ---- ---- | | |veth | |veth | | | |veth | |veth | | | ---- ---- | | ---- ---- | | | | | | | | | | ------------------ | | ------------------ | | | cni0 网桥 | | | | cni0 网桥 | | | ----------------- | | ----------------- | -------------------------------------------------------------------------- | 跨节点路由/Overlay (CNI 负责) | --------------------------------------------二、CNI 接口与常见插件CNIContainer Network Interface是 K8s 定义的一套网络插件标准接口kubelet 在创建 Pod 时调用插件的ADD给它配 IP、建 veth删除时调用DEL。只要实现这套接口任何网络方案都能接入 K8s——这就是可插拔网络。两个主流插件对比插件模式原理优点缺点FlannelVXLAN跨节点封装 UDP 隧道Overlay 网络简单、易部署有封包开销Flannelhost-gw靠节点路由表直连无封装性能接近原生要求节点二层互通CalicoBGP节点间用 BGP 协议同步路由高性能、策略丰富NetworkPolicy配置较复杂取舍经验同机房二层互通、追求性能 → host-gw 或 Calico BGP无封装跨网段/云上多子网 → Flannel VXLAN 或 Calico IPIPOverlay 封装。Calico 还额外支持网络策略NetworkPolicy能做 Pod 间访问控制这是 Flannel 不具备的。三、K8s Service稳定的访问入口Pod 会漂移、会重启、IP 会变所以永远不要直接拿 Pod IP 当服务地址。Service 就是给一组 Pod 一个稳定的虚拟 IPClusterIP和 DNS 名并做负载均衡。三种主要类型ClusterIP默认集群内部虚拟 IP仅在集群内可达。NodePort在每个节点上开一个固定端口30000-32767外部节点IP:NodePort可访问。LoadBalancer向云厂商申请一个外部负载均衡器把流量引入集群云环境常用。kube-proxy 维护转发规则 | Client Pod v | ---------- | 访问 | Service | | clusterIP | ClusterIP| |------------| 10.96.x | | -------- | | 负载均衡 (iptables/ipvs) | -------------- | | | | v v v v Pod-1 Pod-2 Pod-3 Pod-4 (Endpoint 集合)kube-proxy是怎么把 Service IP 转到 Pod 的两种模式iptables 模式kube-proxy 监听 Service/Endpoint 变化生成一堆 iptables 规则做 DNAT 转发。简单稳定但规则多时成千上万 Service线性匹配有性能瓶颈。ipvs 模式基于内核 LVS用哈希表做转发支持更多调度算法rr/wrr/lc…大规模下性能远优于 iptables。生产推荐 ipvs。可用kubectl get endpoints svc查看 Service 背后实际 Pod 列表Endpoints 对象。四、CoreDNS服务发现Pod 之间怎么通过名字找到 Service靠CoreDNS。它作为集群内置 DNS通常是个 Deployment ClusterIP Service把service.namespace.svc.cluster.local解析成 ClusterIP。K8s 会把 CoreDNS 的地址通过kubelet --cluster-dns注入每个 Pod 的/etc/resolv.conf于是你在容器里nslookup mysql.default就能直接发现服务无需硬编码 IP。五、Ingress七层路由入口Service包括 NodePort/LoadBalancer是四层L4IP端口转发无法根据域名/路径分流。要把api.example.com转给服务 A、web.example.com/path转给服务 B就要Ingress七层 / L7 路由。Ingress 本身只是路由规则对象真正干活的是Ingress Controller比如 nginx-ingress它常以 DaemonSet/Deployment 部署对外暴露一个 LoadBalancer 或 hostNetwork 端口读取 Ingress 规则并生成 nginx 配置。浏览器 | v Ingress Controller (nginx, 对外 80/443) | 根据域名/路径路由 ----------------------------- | Host: api.example.com |--- Service api-svc --- Pod | Host: web.example.com |--- Service web-svc --- Pod | Path: /blog |--- Service blog-svc -- Pod -----------------------------示例 Ingressnginx-ingressapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:example-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target:/# 路径重写spec:ingressClassName:nginxrules:-host:api.example.com# 按域名分流http:paths:-path:/v1pathType:Prefixbackend:service:name:api-svcport:number:80-host:web.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:web-svcport:number:80参数解释ingressClassName指定用哪个 Ingress Controller集群可能装多个。host基于 HTTP Host 头做虚拟主机路由实现一个入口多站点。pathType: Prefix前缀匹配另有Exact精确、ImplementationSpecific。rewrite-target把请求路径重写后再转发给后端常用于路径前缀剥离。小结 / 核心要点K8s 网络模型每 Pod 独立 IP、扁平互通、无 NAT由 CNI 插件落地。CNI 是网络插件标准接口FlannelVXLAN/host-gw简单、CalicoBGP高性能且支持 NetworkPolicy。Service 提供稳定 ClusterIP 负载均衡类型有 ClusterIP/NodePort/LoadBalancerkube-proxy 用 iptables小规模或 ipvs大规模推荐做转发。CoreDNS 实现服务名 → ClusterIP的服务发现是集群内互相访问的基石。Ingress 在 Service 之上做七层域名/路径路由由 Ingress Controller 实际执行是集群统一对外入口。