§ 7.3 · Section

容器网络

Container Network · Bridge · Overlay · Service · Ingress

上一节你的服务器在云里安了家:一台一台地开机、配置、接入子网。但今天的互联网公司早就不这么玩了——他们的应用被打包成成千上万个"箱子",每天在机房里被创建、销毁、搬来搬去,一个箱子的寿命可能只有几个小时。这种箱子叫"容器",而怎么给这些朝生暮死的箱子发门牌、通网络、让外面找得到它们,就是本节的主角:容器网络。一句话概括:容器网络干的事,就是给一座每天装卸几万只集装箱的码头,配一套永远不乱的门牌系统。

生活场景
🚢 一个码头工人的消失,和一场软件业的复刻

1960 年代之前,全世界的港口都挤满码头工人:货物用桶装、袋装、散装,一艘船装卸要几个星期,偷窃和损耗是家常便饭。后来标准集装箱普及,一切改变:货物在工厂就装进统一尺寸的铁箱子,吊车装卸,一艘船的装卸时间从几周缩到一天,码头工人这个职业随之消失。

六十年后,软件业原样复刻了这一幕:2013 年,一家叫 Docker 的公司把"集装箱"思想搬进了机房——把程序连同它需要的全部环境打包成标准"箱子"。从此程序员那句祖传借口"在我电脑上是好的啊",永远失去了辩解力:箱子里连"电脑"都一起搬过去了。这一节讲的,就是这些箱子住进机房之后,怎么解决"通网络"这件事。

先把这一节的术语翻译成人话

照例,先把本节的核心名词全部翻译成"人话",每个都能在生活里找到对应物。读完全文回来重看这张表,会有第二次收获。

术语换成大白话生活里对应的东西
容器(Container)说白了就是"把程序连同全部家当装进一只标准箱子"海运集装箱
镜像(Image)说白了就是"照着就能复制出箱子的图纸模板"菜谱 / 铸件的模具
宿主机(Host)说白了就是"箱子停靠的那台真实机器"堆放集装箱的堆场
bridge 网络说白了就是"每台机器内部自建的一个小虚拟网,箱子们接进去互通"小区内部的楼道网
端口映射说白了就是"打总机报分机号,前台帮你转接"公司前台转接电话
overlay 网络说白了就是"跨机器的空中连廊,让不同堆场的箱子像在同一个院子"厂区之间的连天桥
K8s(Kubernetes)说白了就是"整个码头的调度公司:哪只箱子放哪、坏了补几只,全归它管"码头调度中心
Pod说白了就是"绑在一起搬运的一小组箱子,共用一个门牌"捆在同一托盘上的几件货
Service说白了就是"一个永远不变的虚拟总机号,背后分机随便换"永不占线的公司总机
Ingress说白了就是"整座大厦对外的统一正门和总服务台"写字楼大堂前台
东西流量说白了就是"机器和机器之间的内部互访"同小区住户串门
南北流量说白了就是"外部用户和机房之间的进出流量"快递进出小区大门

一句话串起整节:容器是箱子,宿主机是堆场,bridge 是楼道网,端口映射是前台转接,overlay 是跨场连廊,K8s 是调度公司,Pod 是同牌托盘,Service 是总机,Ingress 是大厦正门。下面一样一样说。

先讲箱子本身:为什么会有容器

网络之前,先花三分钟弄清箱子解决了什么,否则后面的网络设计会显得无厘头。程序这东西,出了名地难伺候:同一个网站程序,在你机器上跑得好好的,搬到服务器上就报错——因为服务器上的 Python 版本差了一个小数点、某个系统库不存在、配置文件路径不同。传统部署时代,工程师一半的深夜加班,都是在伺候这种"水土不服"。

虚拟机是最早的解法:干脆连操作系统一起搬。但一台虚拟机要占用好几个 GB 的内存、开机要几十秒——好比为了送一份外卖,连厨师、灶台、整个厨房一起打包快递过去,能吃,但蠢得明显。容器则是更聪明的折中:不搬整个厨房,只把"这道菜 + 它专属的锅碗瓢盆"装进一只箱子。箱子共享宿主机的操作系统内核(厨房和水电),只隔离自己的那一摊。结果就是:一只箱子只占几十 MB、一秒钟就能启动——从"搬厨房"降到"搬便当",这就是容器能席卷行业的原因。

再补一个词:镜像。它是制造箱子的模具——一份只读的模板,里面冻结了程序和全部家当。要十个实例就照模具浇十个箱子,好比乐高说明书:同一套图纸,今天拼三份、明天拼三十份,拼出来的每一份分毫不差。"一次打包,处处相同"——集装箱的口号原样适用于软件。

一只箱子的网络生活:bridge 模式

箱子造出来了,问题接踵而至:它要不要 IP 地址?要不要上网?箱子之间要不要互相访问?先看最常见、也是默认的解法——bridge 模式,它的思路你在上一节其实已经全学过了:

每台宿主机在内部用软件造一个虚拟交换机(默认名字就叫 docker0),这台机器上的所有箱子都接进这个小网络,各自分一个内网 IP(比如 172.17.x.x)。箱子要访问外网?通过宿主机做一层 NAT 转换出去。看出眼熟了吗——虚拟交换机 + 私有网段 + NAT 出门,这正是上一节 VPC 的三件套,只是从"云厂商给整块领地用"缩小成了"一台机器给箱子们用"。你在云上租的那台服务器,对它肚子里的容器来说,本身就是一个小号的"云厂商":划网段、发门牌、开收发室,一个不少。

说白了,网络世界的思想是彻底复用的:家用路由器如此,VPC 如此,容器网络的第一课还是如此——"私有网段 + 统一网关 NAT"这套组合拳,从你家客厅一直打到了云上机房的每一台机器里。学会认这个套路,你再看到任何新名词的"组网方案",先找它的虚拟交换机和 NAT 在哪,八成就看懂了一大半。

外面怎么找到箱子:端口映射

bridge 网络有个天生的短板:箱子的 IP 是内网地址,外网用户够不着。解法你也能秒懂——端口映射:把宿主机的某个端口,"转接"给某只箱子。比如宿主机宣布"打我 8080 端口的,都转给 3 号箱子"。外部用户访问宿主机 IP 加 8080,流量被前台转进箱子。好比公司只有一部对外总机,员工没有直拨号:找销售部?前台转 8080 分机;找财务部?转 8081 分机。箱子永远躲在宿主机身后,对外通信一律"总机转分机"。

这个小机制顺便解释了两个日常困惑。其一:为什么同一台服务器上能同时跑十个网站容器互不打架?因为它们各占一个分机号(8080、8081、8082……),前台按号转接,各回各家。其二:为什么新手第一次跑容器,网页死活打不开?九成是把"箱子里的端口"和"宿主机的端口"搞混了——箱子里的 80 是箱子的内线,不映射出来,外面永远打不进来。记住这句话能省掉你未来某次两小时的抓瞎排查:内线不通外网,要么转接,要么换直拨。

箱子之间怎么互相找:名字比门牌好使

解决了"外面找箱子",还有"箱子找箱子"。同一个 bridge 网里的网站箱和数据库箱要互相访问,写 IP 行不行?行,但蠢——箱子一重启,内网 IP 重新分配,配置又作废。所以容器世界从第一天起就内置了一个聪明的约定:同一个网络里的箱子,可以直接用"名字"互相喊人。启动箱子时给它起个名(比如 db),网站箱的配置里写的就是"连 db",不是"连 172.17.0.3"。谁在监听名字、名字当前指向哪只箱子,由 bridge 网里内置的小型域名解析服务自动维护——箱子换号了,名字的指向自动跟着刷新。

说白了,这就是 § 4.2 讲过的 DNS 思想(名字是编制,地址是临时工)在单机内部的复刻。请把这个观念现在就焊进脑子:容器世界里,凡是配置,一律写名字、绝不写 IP——这条纪律稍后会升级成整个 K8s 世界的地基。顺带一个常见的新手坑也源于此:两只箱子互相喊不应,先检查它们是不是接在同一个网络里——名字解析只在同一个 bridge 网内生效,一个箱子接"楼道网 A"、另一个接"楼道网 B",就算物理上同一台机器,也互相是个聋子。

其他户型速览:host 模式与它的取舍

除了 bridge,容器还有一种值得认识的住法叫 host 模式:箱子不用内网、不搞转接,直接共用宿主机的网络身份——箱子里的 80 端口就是宿主机的 80 端口。好比摊位不租铺面了,直接把货摆到马路边:少一道转手、快一点,但也失去了独立门面——端口冲突了自己扛,箱子之间的隔离也薄了一层。网络方案从来是选择题:多一层转发多一分隔离,少一层转发多一分风险——工程上没有免费的快。这一节只需要知道两种户型各代表一个极端,真实系统里 bridge 系是绝对主流。

箱子搬进多栋楼之后:overlay 网络

到目前为止我们都假设箱子住在一台机器里。可真实的系统哪是一台机器装得下的——一个网站分身几十上百只箱子,分散在几十台宿主机上。每台宿主机内部都有自己的小 bridge 网(172.17.x.x),问题来了:一号楼的 3 号箱和二号楼的 3 号箱,内网地址撞车了,怎么互相访问?

解法叫 overlay 网络(覆盖网络):在每台宿主机之间打"加密隧道",把分散在几十台机器里的箱子,重新连成一张逻辑上统一的虚拟网——箱子们以为自己住在同一个大院里,实际上它们的通信被封装起来、借道宿主机之间的物理网络飞过去,落地再拆封。好比厂区里十几栋厂房之间架起连天桥和传送带:每栋楼内部有自己的门牌(bridge),楼与楼之间再修一套"空中走廊 + 统一外层门牌"(overlay),人在走廊里走,永远感觉不出脚下换过楼。你可能又眼熟了——这正是上一节 VPC 的"信封封装"思想,第三次出现:VXLAN 这类协议,本身就是云厂商和容器界共用的同一套隧道技术。

说白了,整个第七章其实在同讲一个母题:用软件在共享的物理网络上,"画"出一张张互不干扰的逻辑网。VPC 给租户画,bridge 给单机画,overlay 给跨机画——画法层层嵌套,思想只有一个。

有人会问:何必这么绕?让物理网络的交换机直接认识每只箱子、给每只箱子发一个"真 IP"不就完了?这条路真试过,撞上两堵墙。第一堵墙是数量:一个大机房动辄几万只箱子,还在每小时成百上千地生灭,地址分配和回收的速度跟不上,IPv4 地址更早就不够分。第二堵墙是设备:物理交换机靠查"门牌登记表"(MAC 地址表)转发,表的容量按"几百台服务器"设计,猛然塞进几万只箱子的登记记录,表一溢出,全网广播泛滥——好比小区门卫的本子只登记了一千户的车,突然每天进出一万辆共享单车,岗亭当场瘫痪。所以行业最终集体转向 overlay:让物理网络只认"楼",楼里住谁、怎么编排,全部交给软件另建一套账本——物理层保持简单,逻辑层随便折腾。

问题升级:朝生暮死的箱子,没法记门牌

网络通了,新的烦恼却更致命。容器最大的美德是"随开随关":流量涨了,调度系统五分钟内开出五十只新箱子;流量落了,又默默销掉四十只。箱子的 IP 地址因此成了全机房最不可靠的东西——今天这只箱子的门牌,明天可能就挂到了另一只箱子上。

想象你开餐厅,后厨的厨师是按小时雇的临时工,今天张三、明天李四,工号天天变——而前台的点菜单上写的全是工号。点单系统等于每天重写一遍。更糟的是连锁反应:数据库连接配置里写了应用服务器的 IP,应用一扩容,配置全作废;前端写了后端的 IP,后端一换机器,前端跟着挂。当"地址"变得朝不保夕,任何直接使用地址的设计,都是在沙滩上盖楼。这个矛盾不解开,容器革命就只能停在玩具阶段。

码头调度公司登场:K8s 在概念层是什么

解开矛盾的重锤,是 2014 年谷歌开源的 Kubernetes(行话缩写 K8s)。这一节按本站约定不碰它的配置细节,只讲它是什么、管什么——概念层的 K8s 就是上一节故事里的"码头调度公司":你把想要的状态告诉它("网站箱子保持五十只,挂了自动补"),剩下的装箱、摆放、补货、回收全由它包办。它和本节主题的交集只有一件事:K8s 接管了所有箱子的门牌,并顺手发明了一整套"让地址不再重要"的办法。

先认识它的一个基本单位:Pod。K8s 不按"一只箱子"调度,而是按"一组绑在一起的箱子"——典型如"应用箱 + 采集日志的小箱"绑成一个 Pod,共享同一个 IP、同一个门牌。好比仓库里用托盘把几件捆成一件搬运:吊车认托盘不认单件,调度公司认 Pod 不认单箱。绑在一起的箱子要么一起搬、要么一起扔——同生共死,就是 Pod 的全部设计哲学。

调度公司最有价值的本事,是自愈:你只申报"我要五十只网站箱子",K8s 就永远维持这个数目——哪只箱子卡死了,它几十秒内发现、销毁、照着模具再浇一只新的;哪台宿主机整个宕机了,它把损失的那些箱子全部转投到别的楼里重新开张。工程师半夜被电话叫醒救服务器的时代,就这样悄悄结束了。还有一个连带的甜头叫滚动更新:发新版本不是"停机、换件、重启"三连,而是每次只换两三只箱子、确认健康再换下一批——好比给行驶中的公交车换轮子:一轮一轮来,车不停。但这一切能成立有个前提:世界不能记挂着"具体某一只箱子"——又是那个地址问题,解药马上到。

Service:永不占线的总机

终于到本节最重要的一件发明。K8s 给每组做同类工作的 Pod(比如"所有的网站箱子")配一个 Service——一个固定不变的虚拟地址 + 名字。所有需要找"网站"的,一律访问这个总机号;总机背后接哪几只箱子、箱子怎么换来换去,外界完全不用关心。

【没有 Service vs 有 Service】

  没有 Service:                      有 Service:
                                      ┌──── Service "web"(总机号不变)────┐
  前端 → 10.0.1.7(某只Pod)           │      ↓ 随时按健康状况转接           │
         10.0.1.7 挂了 💥 前端全挂      │  Pod A ✔ 转接                     │
         扩容到 30 台 → 改 30 处配置    │  Pod B ✔ 转接      Pod C ✘ 摘除   │
                                      │  Pod D ✔ 转接   (新增 Pod E 自动入列)│
                                      └───────────────────────────────────┘
                                      前端永远只记总机号,后面爱怎么换怎么换

看出这套机制的 DNA 了吗?它就是上一节"内网 DNS:名字是编制,地址是临时工"的容器版加强升级。Service 不只是名字固定,还顺手干了三件重活:其一,负载均衡——总机把海量来电均匀转给各分机(§ 5.5 讲过的那套思想);其二,健康检查——某只箱子病了,总机自动把它从转接名单上摘掉,客户毫无感知;其三,自动收编——新箱子一开机,总机自动把它加进名单。从此"扩容"对使用者变成了一个完全透明的动作:机器从五台加到五十台,所有访问方一行配置都不用改。

说白了,Service 之于容器集群,就像公司总机之于流动的员工:人员天天换,总机号印在名片上十年不动。这就是"地址危机"的完整解药:把一切易变的东西藏在稳定的东西后面。

三种总机:内线、侧门与正规前台

Service 本身也分几种"接线方式",概念层认全这三种就够用了,它们恰好是同一件事的三个开放程度:

三种方式不是三选一的平行选项,更像同一扇门的三档开度:内部互访开内线,临时调试开侧门,正式营业配前台。开放程度永远跟着"谁需要找到我"走——这又是安全组的"最小权限"思想,换了个地方第三次登场。

Ingress:大厦的正门与总服务台

还剩最后一块拼图。LoadBalancer 给每个服务配一个前台,可一家公司几十个服务都配独立前台,既贵又乱。更好的做法学自现实中的写字楼:整栋楼只设一个气派的正门和大堂总服务台,访客报到后,前台按"找谁、去几层"指路。这就是 Ingress:整个容器集群对外的统一入口,它按请求里的域名和路径("api.xxx.com 的往这边,www.xxx.com 的往那边,/images 的去图片服务")把流量分发给各家的 Service。

它的好处立现:几十个服务共用一个公网门牌、一套证书、一份防护规则——好比写字楼里所有公司共用大门、保安和访客登记系统,每家公司不用各自雇门卫。门前的事集中管(加密、限流、防攻击都在正门做),门后的事各自管(每个服务自己的箱子随便折腾)。顺带看出它的层级:Ingress 管到"找谁"(第七层的域名和路径),Service 管到"转给哪台"(第四层的端口转发)——§ 5.5 讲过的四层与七层分工,在这里正好各就各位。

东西与南北:机房里的两大流域

讲到这,把全节流量归拢成两条河,行业黑话叫"东西流量"和"南北流量"。这两个词第一次见会觉得莫名其妙,图景其实朴素:把机房画成一张地图,外部用户在地图下方的"南边",机房间互访的箭头在地图上横向地"东西"乱穿。

拿一次最普通的网购下单,感受"串门"能有多疯。你在手机上点了一下"付款"——这一下进城流量只有几 KB,但机房内部立刻忙成庙会:订单服务先串门问用户服务核身份,再问库存服务锁货,再问营销服务算优惠,然后支付服务接手去找银行,成功后通知物流服务下单、通知短信服务发提醒,中间还要请风控服务把整个过程盯一遍。你在城门口递进去一句话,内巷里十几户人家挨家挨户跑了个遍。这就是为什么东西流量往往十倍于南北流量——也是为什么下一节要专门为"内巷"发明一整套治理体系:城门口丢一个包裹好发现,内巷里十几个接力棒哪一棒掉了,才是真正难查的事。

这个二分法是理解现代机房流量的总钥匙:城门和内巷是两套完全不同的交通系统——用治理城门的思路去治理内巷,或反过来,都是灾难。下一节的服务网格,正是为"东西流量"而生的整套治理体系,这里先埋个钩子。

容器网络全景图:一张图收束全部

把本节所有零件按"一次外部访问"的顺序装回一张图:

【一次访问在容器集群里的完整路线】

  外部用户
     │
     ▼
  Ingress(大厦正门:按域名/路径分发、统一证书与防护)
     │
     ▼
  Service "web"(总机:虚拟号不变 + 健康检查 + 均匀转接)
     │
     ├──→ Pod A(宿主机 1:bridge 网内的箱子)
     ├──→ Pod B(宿主机 2:经 overlay 连廊过来的箱子)
     └──→ Pod D(新扩容,自动入列)
              │
              ▼
     Service "db"(另一台总机:内线 ClusterIP,不见外客)
              │
              ▼
     数据库 Pod(绑定托盘:主容器 + 日志小容器,同生共死)

  城门(Ingress)→ 前台(Service)→ 托盘(Pod)→ 箱子(容器)
  外面只见门牌稳定,里面箱子如流水线般生生灭灭

从上往下读是"一次访问的旅程",从下往上看是"一层层的稳定壳":箱子易变,所以包进托盘;托盘易变,所以包进总机;总机林立,所以包进正门——每一层稳定的东西,都在替下面易变的东西挡住世界。这与 TCP 包 IP、IP 包以太网、HTTPS 包 HTTP 的分层套娃(§ 2.2),是同一个智慧在网络和应用之间的两次显形。

动手自检:用 tasklist 看一眼"没有集装箱的世界"

容器这东西概念太抽象,我们反过来体验:看看"没有容器"的世界长什么样。打开命令提示符(Windows 按 Win 键输入 cmd),运行:

屏幕上滚出来的每一行,都是一个正在运行的进程——你的电脑此刻正维持着上百个"干活的人"。传统世界里,这些进程挤在同一间"大通铺"(操作系统)里:共享同一套文件、同一个网络身份,谁闯祸全屋遭殃——这就是容器诞生前的机房日常:几十个程序挤在一台服务器上,一个程序的内存泄漏能把邻居全部拖死。容器做的事,就是把大通铺隔成一间间独立小屋:每个进程住进自己的箱子,带自己的行李,用自己的内网门牌。看完这张进程清单再回头看本节开头那张集装箱码头的画面——你电脑里这张"通铺名单",就是集装箱革命要革掉的旧世界。

排错小抄:容器"打不开"的四步排查

概念读完,留一套能带走的手艺。哪天你自己跑了个容器、浏览器却怎么也打不开,按这个顺序查,从命中概率高到低:

这套顺序的心法只有一句:从外往内、逐层缩小——先看门(映射),再看路(网络),最后看屋里(进程)。和第 4 章把"网页打不开"拆成七件事逐层排查的思路完全同源:分层的世界,排错也按层来。

常见误区:四条流传最广的容器迷信

Analogy · 一座现代化集装箱码头:把本节所有概念装进一个画面

如果你只记住这一节的一个画面,请记住这座码头:应用被打包成标准集装箱,一座现代化码头每天吞吐几万只,而一切井井有条。

① 集装箱是容器,堆场是宿主机。箱子自带全部家当,从工厂到码头到船上一字不开箱——"在我电脑上是好的"从此绝迹。

② 每个堆场内部有自己的小路网(bridge)。箱子们在场内互通、共用场门出门(NAT);外面的人找箱子,一律"打场部总机转分机"(端口映射)。

③ 堆场之间架连廊(overlay)。不同堆场的箱子像住在同一个大院,走廊之下箱子的真实位置无人关心。

④ 调度公司(K8s)管全部箱子。它按托盘(Pod)调度——几件货捆成一托盘、同进同出;托盘天天换,公司毫不在意。

⑤ 总机(Service)永不占线。名片上印的是总机号,背后分机随便换:新箱入列自动转接、病箱摘除客户无感——扩容从此对世界隐形。

⑥ 正门只有一个(Ingress)。全码头共用一个气派正门和总服务台:统一保安、统一登记,按"找谁"把访客分去各家;门内的串门(东西流量)和门外的车流(南北流量)是两套独立的交通系统。

这座码头记住了,本节所有名词就都挂在上面了:标准箱进场、场内小路网、总机转分机、跨场连廊、托盘调度、总机不换号、正门统一迎客。

一句话送给你:容器网络的三个心法

这一节零件繁多,但真正值得刻进脑子的就三条。第一,地址不可信,名字才可信——箱子朝生暮死,一切协作都该挂在 Service 这个"永不占线的总机"上,谁直接记容器 IP 谁排队返工。第二,开放分三档,默认选最小——内线(ClusterIP)够用就别开侧门(NodePort),临时调试才用的门,别把它当正门(LoadBalancer/Ingress)使。第三,城门与内巷分开治理——对外流量在正门集中做加密限流防护,对内流量重点做隔离和追踪,两套账千万别记混。好比经营一座码头:门面的事问保安部,场内的事问调度部——一个管面子,一个管里子,码头才能又体面又高效。

Recap · 收束

一句话总结:容器网络是给每天生灭成千上万只"应用集装箱"的机房,配一套门牌永不失效的交通系统——小到一台机器里的楼道网,大到跨机房的天空连廊,核心发明只有一件:让易变的地址,永远躲在稳定的名字后面。

机制上记住五件事
· 容器是便当,不是厨房:程序连家当装箱、秒级启停,"在我机器上是好的"就此绝迹。
· 单机组网用 bridge:虚拟交换机 + 私有网段 + NAT——和 VPC、家用路由器同一套组合拳,第三次登场。
· 跨机组网用 overlay:隧道封装画一张逻辑大网,箱子以为自己同院,物理上各在一方。
· Service 是总机:虚拟号固定、健康检查、均匀转接、新箱自动收编——扩容从此对世界透明。
· Ingress 是正门:全集群一个门面、一套证书、一份防护,按域名路径分发;城门与内巷(南北与东西),两套账分开记。

下一步:正门和总机解决了"找得到"的问题。可当一家公司拆出几百个微服务、内巷里的串门流量成了主战场,新的痛点浮现了——每次调用谁超时了、要不要重试、新版本敢不敢全量放出去?给"东西流量"配一套统一治理层的方案,就是 § 7.4 的主角:服务网格

☰ 主页
Xue Hai Wu Ya · Network · § 7.3 · 容器网络