目录

核心总比喻:一个大城市(Kubernetes 集群)的邮政系统​

​1. Docker 的默认网络:老式单位大院​

​2. Kubernetes 网络模型目标:给每户人家一个标准门牌号​

​3. 网络方案之争:如何实现这个“城市邮政系统”?​​

​方案A:Flannel - “建立城市邮政专线系统”(Overlay)​​

​方案B:Calico (BGP) - “改造城市路牌系统”(Underlay)​​

对比补充

​核心差异:信件本身有没有被“重新包装”​​

​场景对比:信件的“出厂设置”​​

​方案A: Flannel VXLAN - “信件被装进一个更大的标准快递箱”​​

​方案B: Calico BGP - “信件直接被寄出,但全城路牌已更新”​​

对比表格:一目了然​

​结论

​4. CNI:邮政系统的“接口标准”​​

​5. Service:小区的“公共收发室”和“114查号台”​​

​6. Ingress:城市的“高速公路出入口管理局”​​


核心总比喻:一个大城市(Kubernetes 集群)的邮政系统

  • 城市​ = 一个 Kubernetes 集群
  • 小区/街道​ = 一个节点(Node)
  • 小区里的每户人家​ = 一个 Pod
  • 每户人家的门牌号​ = Pod IP
  • 小区的总门牌号​ = Node IP
  • 邮递员​ = 各种网络组件

我们的目标是:让这座城市里的任何一户人家,都能高效、准确地把信(数据包)送给另一户人家,无论他们是否在同一个小区。


1. Docker 的默认网络:老式单位大院

  • 原理​:就像一个封闭的单位大院(一台宿主机)。所有住户(容器)都住在这个大院里,共享一个大门(同一个网络命名空间)。每户人家没有独立的门牌号,他们通过端口号来区分彼此,就像“叫门房老王转接302室的小张”。
  • 通信​:
    • 院内通信​:直接喊一嗓子或者走几步就到了(通过localhost或内部网络)。
    • 院外通信​:必须统一从单位大门进出(通过端口映射-p),非常麻烦,而且容易造成端口冲突。
  • 问题​:容器们没有独立的、可路由的IP地址,无法直接与“大院”外的世界沟通。

2. Kubernetes 网络模型目标:给每户人家一个标准门牌号

K8s 定了一个“城市宪法”:

每个 Pod 都必须拥有一个唯一的、可路由的 IP 地址(独立门牌号),并且任何 Pod 都可以用这个 IP 直接与任何其他 Pod 通信,无需进行网络地址转换(NAT)。​

这就意味着,我们要把整个城市的所有“小区”(节点)和“住户”(Pod)都纳入一个统一的、巨大的“城市邮政系统”中。


3. 网络方案之争:如何实现这个“城市邮政系统”?​

方案A:Flannel - “建立城市邮政专线系统”(Overlay)​

Flannel 的做法是,在城市上空建立一个专用的邮政空中缆车系统(Overlay 网络)​

  • VXLAN 模式(智能缆车)​​:

    1. 打包​:当“小区A”的“住户Pod A”要寄信给“小区C”的“住户Pod B”时,小区A的邮局(Flannel)会把信(原始数据包)装进一个标准的缆车运输箱(VXLAN 封装)​。箱子上写着“寄往小区C”(目标 Node IP)。
    2. 运输​:缆车沿着专用线路(底层网络)直达小区C。城市的普通公路系统(底层网络)只负责运输这些标准缆车箱,根本不关心箱子里的信是写给谁的。
    3. 拆包​:小区C的邮局拆开运输箱,取出原始的信件,根据信上的原始地址(Pod IP)准确投递到 Pod B 家中。
    • 优点​:与底层公路系统解耦,能在任何基础上运行。
    • 缺点​:打包/拆包(封装/解封装)有轻微性能开销。

  • UDP 模式(原始人力传递)​​:非常低效。需要把信的内容念给一个邮差(flanneld进程)听,邮差跑过去再口述给收件人。​基本已被淘汰。​

方案B:Calico (BGP) - “改造城市路牌系统”(Underlay)​

Calico 的做法更硬核:它不去建空中缆车,而是去改造城市里每一个路口的路牌(节点的路由表)​

  • 原理​:Calico 的“路政管理员”(BGP Speaker)会跑到每个小区(节点),告诉它:“记住,除了本小区的住户,你还要认识其他所有小区的住户地址(Pod IP)。想去‘小区C的住户B’,直接往‘小区C’的方向走就行。”
  • 通信​:现在,Pod A 要给 Pod B 寄信,信被送到小区A的邮局。邮局一看路牌(路由表):“哦,地址是小区C的,直接往那边送。” 信件(原始数据包)就通过城市的普通公路系统(底层网络)​直接、原封不动地送到了小区C,中间没有任何打包拆包的过程。
    • 优点​:​性能极高,没有封装开销。
    • 缺点​:对“城市公路系统”(底层网络)有要求,节点之间必须能直接路由。
对比补充

核心差异:信件本身有没有被“重新包装”​

让我们回到“Pod A 给 Pod B 寄信”这个场景。我们对比一下信件在离开“小区A”时的最终形态

场景对比:信件的“出厂设置”​
  • 原始信件(Pod A 想寄出的数据包)​​:
    • 信封[外层]​​:收件人:​Pod B的IP,寄件人:Pod A的IP
    • 信封[内层]​​:HTTP请求内容(比如“GET /index.html”)
    • 这封信的格式是标准邮政格式

现在,我们看两种方案如何处理这封信。


方案A: Flannel VXLAN - “信件被装进一个更大的标准快递箱”​
  1. 打包(封装)​​:

    • 小区A的邮局(Flannel)​没有直接寄出原始信件
    • 它拿了一个更大、更厚的VXLAN标准快递箱
    • 它把整个原始信件​(包括外层信封)原封不动地塞进这个快递箱里。
    • 然后,它在这个新快递箱的外面,贴上一张新的快递单​:
      • 收件人:小区C的地址(目标 Node IP)​
      • 寄件人:小区A的地址(源 Node IP)​
      • 备注:内装Pod间信件(VXLAN头,包含VNI等)​

    ​**✅ 关键点:原始信件完好无损,但被套了一个新外壳。​**​

  2. 运输​:

    • 这个VXLAN大快递箱被扔进城市的普通物流车(底层网络)。
    • 物流车司机(底层网络的路由器/交换机)​只认大箱子外面的新快递单。他的任务就是把箱子从“小区A”运到“小区C”。他完全不知道、也不关心大箱子里面还套着一个小信封。
  3. 拆包(解封装)​​:

    • 箱子运到小区C后,邮局拆开VXLAN大快递箱,取出里面完好无损的原始信件
    • 然后根据原始信件上的收件人地址(Pod B IP),送达给Pod B。

总结:VXLAN是“套娃”运输。原始数据包被完整封装在一个新数据包里。底层网络运输的是“新箱子”。​


方案B: Calico BGP - “信件直接被寄出,但全城路牌已更新”​
  1. 无需打包​:

    • 小区A的邮局(Calico)​直接寄出了原始信件,没有任何包装!
    • 信件的形态和Pod A写的一模一样:
      • 信封[外层]​​:收件人:​Pod B的IP,寄件人:Pod A的IP
      • 信封[内层]​​:HTTP请求内容

    ​**✅ 关键点:信件就是原始形态,没有被套上任何新外壳。​**​

  2. 运输​:

    • 这封原始信件被扔进城市的普通物流车(底层网络)。
    • 物流车司机(底层网络的路由器/交换机)拿起信一看收件地址是 Pod B IP(比如 10.244.2.10)。
    • 在Calico部署好后,​司机手上已经有一张由BGP协议更新的、全城统一的路牌表。他查表发现:“地址 10.244.2.10?这个地址不属于任何传统小区,但路牌上写着,这个地址段(10.244.2.0/24)归‘小区C’管理。所以,把这封信送到小区C就行了。”
    • 于是,物流车将信件直接运往小区C。
  3. 送达​:

    • 信件到达小区C,邮局一看收件地址 10.244.2.10 正是本小区的Pod B,直接送达。

总结:Calico BGP是“原信”运输。原始数据包直接被发送。底层网络之所以能识别Pod IP,是因为它的“路牌”(路由表)被BGP提前教育过了。​

对比表格:一目了然
特性 Calico (BGP) - “原信寄送”​ Flannel (VXLAN) - “套箱寄送”​
数据包形态 原始IP包
收件人:​Pod IP
原始IP包被封装在UDP/VXLAN包内
收件人:​Node IP​(内部才是Pod IP)
底层网络看到的是什么?​ 它看到的是一个目的是 ​**10.244.2.10 (Pod IP)​**​ 的包。它需要能理解这个IP。 它看到的是一个目的是 ​**192.168.1.12 (Node IP)​**​ 的包。它完全不知道10.244.2.10的存在。
核心工作 扩散路由​:让全世界(底层网络)都知道每个Pod IP该怎么走。 建立隧道​:在Pod IP世界之上建立一个虚拟网络,对底层隐藏Pod IP。
网络模型 Underlay(三层路由)​ Overlay(二层隧道)​
性能 更高​(无封装/解封装开销) 稍低(有封装/解封装开销)
要求 要求底层网络支持(节点间IP可达,且能学习路由) 对底层网络几乎无要求,适应性极强

结论


4. CNI:邮政系统的“接口标准”​

上面介绍的 Flannel 和 Calico 是两个不同的“邮政公司”。Kubernetes 怎么知道该聘请哪家公司呢?它需要一个标准合同。

  • CNI (Container Network Interface)​​ 就是这个标准合同。它规定了邮政公司(网络插件)必须实现哪些功能(比如:如何给新 Pod 分配 IP,如何清理网络接口等)。
  • K8s 的“城管”(kubelet)只认这份标准合同。当一个新的 Pod(住户)建成时,kubelet 就拿着合同去找已安装的网络插件(如 Flannel)说:“嘿,来给这户新人家通网(分配IP、设置路由)!”

5. Service:小区的“公共收发室”和“114查号台”​

现在,每户人家(Pod)都有了自己的门牌号(IP),但还有一个大问题:​Pod 是短暂的,今天住这里,明天可能就搬走了(IP会变)​。你怎么让外界稳定地找到一组提供相同服务的 Pod(比如一组前端实例)?

Service 就是这个问题的答案,它有两个核心作用:

  1. 稳定的“公共收发室”地址(VIP)​​:

    • Service 会有一个永远不会变的 IP 地址(ClusterIP),就像小区的“公共收发室”地址。
    • 外界(或其他服务)想访问这组 Pod,不需要知道每个 Pod 的具体地址,只需要把信寄到“收发室”即可。
    • “收发室管理员”(kube-proxy)负责把来信负载均衡地转发给背后健康的 Pod。
  2. ​“114查号台”(服务发现)​​:

    • Service 有一个域名,比如 my-frontend.default.svc.cluster.local
    • 城市里的其他住户(Pod)想联系前端服务,不需要记IP,只需要拨打“114”(CoreDNS)问:“帮我查一下 my-frontend 的收发室地址是多少?” DNS 就会返回 Service 的 ClusterIP。

实现“收发室”工作的“管理员” kube-proxy 有三种工作模式:​

  • userspace (旧式)​​:管理员在邮局外面来回跑腿,效率低。(基本不用)
  • iptables (标准)​​:管理员在邮局里设置了一套自动分拣规则。来信符合什么特征(目标端口是80),就自动扔进哪个筐(对应的Pod)。性能好,但规则多了会慢。
  • ipvs (高效)​​:管理员用上了工业级自动分拣机。无论规则再多,分拣速度都极快,性能最佳。

6. Ingress:城市的“高速公路出入口管理局”​

Service 解决了城市内部的通信问题。但外部世界(互联网)如何访问城市里的服务(比如一个官网)?

  • LoadBalancer (云服务商)​​:相当于直接雇一个顶级物流公司。你告诉云厂商(如AWS、GCP):“把我这个Service暴露出去。”云商就会直接给你分配一个公网IP(就像给公司分配一个专属的“XXX大厦”地址),所有外部流量都通过这个IP进来。​简单,但昂贵,每个Service都需要一个。​

  • Ingress (更聪明的方式)​​:相当于城市的​“高速公路出入口管理局”​

    • 你只需要一个公网IP(通过LoadBalancer或NodePort方式暴露一个入口)。
    • Ingress Controller(如Nginx Ingress, Traefik)就是这个“管理局”,它根据HTTP请求的域名(如 a.com)和路径(如 /api)​​ 这些“高级信息”,像交警一样,把不同目的的车流(请求)​智能地引导到城市内部对应的“小区收发室”(Service)去。
    • 优点​:一个入口管理所有基于HTTP/HTTPS的服务,成本低,功能强(支持SSL终止、路由等)。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐