如果你是新读者:在上一篇交换机到底在干嘛 里,我承认自己在网络这事上"嘴上有功底",然后认真补课,终于理解了:为什么一个监听在 127.0.0.1 的服务,会对那个通过 10.88.0.1 过来的容器完全隐身。
对老朋友们:这篇是一次有意为之的小小"岔路"。
小尴尬
写第一篇的中途,我试图把新学的东西讲给一个不写代码的朋友听。晚餐时她礼貌地问:你这周在发什么技术疯?
我说了大概三句话,她的眼睛就开始出现那种神奇的微光。
你懂的——那种"我爱你我在场,但我已经听不懂中文了"的微光。我已经说出了 TCP, 内核, bridge interface,下一步就要爆出 MAC address,幸好我及时刹车。
这时我发现一个问题:我现在会解释交换机了;我能解释虚拟桥;我能解释为什么 Portainer 容器看不见我的 SSH 隧道。可如果她问我——从她在网站上点下"购买"的那一刻起,到页面回个"下单成功"为止,整件事到底一秒不落地发生了什么? ——我会直接开摆。我有很多零件,但没有一个完整的故事。
于是我决定写一个。一个真的故事。有角色,有场景,有戏剧冲突。尽量不说术语。甚至要做到能在餐桌上讲完的那种。
“解码环”(每个角色在计算机世界里到底是谁)在文末。请先看故事。尤其是你从没认真想过网站"到底怎么工作"的话,更要先看。
出场人物
先认识一下小小的演员表,他们出场快,退场也快。
- Jack。一个在家网购的男人。他只想买台烤面包机。这就是他全部的人设。
- 浏览器小助手(Browser-Bot)。住在 Jack 的笔记本里。写便条, 打包包裹, 交给快递。忠诚, 龟毛。
- 信使之海(The Sea of Couriers)。一整片在 Jack 家和商店之间的接力快递大军。每个人只知道"下一个该交给谁"。他们不看信,只转运。
- 前门(The Front Gate)。遥远写字楼门口冷静的小门童。只接收投递到"这栋楼"的包裹,其他一律拒收。不会读书。
- 内核妈妈(Mama Kernel)。办公室经理。知道每个门, 每张桌, 每位住户。她桌上有三样法宝:整栋楼的分机黄页, 一本改地址的规则书, 和一大本"今天收了啥我怎么处理的"的流水账。冷静, 稳重, 百战成精。
- 前置文员与后置文员(Pre-Clerk & Post-Clerk)。成对上班的小助理。前置文员负责每个入站包裹,有时会改改包裹外面的地址;后置文员管出站的包裹——并且手抄了一份前置文员做过的所有修改,好在出门前把地址"改回去"。
- 走廊礼宾(The Hallway Concierge)。管楼内走廊。认得每位住户的脸。他的唯一超能力:把包裹沿着走廊"横着"送到对的门口——不上不下,只走平面。
- 前端弗里达(Frieda the Frontend)。住在走廊里,10 号。脾气好,像个前台:接到访客的包裹,看看要求,要么自己处理,要么礼貌地转交给能处理的人。
- 后端布鲁图(Brutus the Backend)。10 号隔壁,11 号。粗声粗气的账房先生。不和外人说话。只接弗里达递过来的包裹。真正干活的——开账本, 扣库存, 记订单。
- 包裹(The Parcels)。故事里的每条消息都是俄罗斯套娃:一封信装进一个信封,塞进一个小包裹,再塞进一个大邮袋。每一层都写给不同的人,走不同的路。我们会看它们一层层拆开, 又一层层重新包好。
齐活儿,开戏。
第一幕——点击
Jack 想要一台烤面包机。
其实他已经惦记了好几周。旧的上周日伴着一缕青烟英勇就义,吓得猫当场换了个房间。他一直在拖,因为网购总感觉比它应有的"更郑重"。但今天,他下定决心。
他滑啊滑。挑中一个。点下"购买"。
Jack 电脑角落里,浏览器小助手噌地弹起,打着领结,手持小夹板。他写下一张短短的便条:这位顾客想买一台烤面包机。然后开始为它披挂远行。
先把便条装进一个小信封,上面写好小助手一手好字的地址。再把这个信封装进一个更大的包裹,写上"商店"的远方地址。然后整个包裹再塞进一个外层邮袋,这一层写的,是门口第一位接力快递的地址。
三层。三个地址。每一层负责一段路。小助手今天已经这么干了一千遍。他把邮袋递出门外。
第二幕——穿越信使之海
第一位接力员早就等着。她接过邮袋,看一眼最外层的地址,撒腿就跑。
她跑到下一位,撕掉外层邮袋——这一层使命已毕——看内层的地址,再用"她自己"的新邮袋包上,写上下一位接力的地址,交棒。
如此往复。
每位接力员都做同样的事:撕掉只用于上一段路的外层,看看里面的地址,再为下一段路重新打包。那个内层包裹——写着商店真正地址的那个——从不被打开。它是神圣的。它是被指定要"端到端旅行"的。
如果你能把时间快进,从高空俯瞰,你会看到一个光点在接力员之间跳跃,穿越半个大陆,身后落满被丢弃的邮袋。最里面的信,相对它的信封没有移动;内层包裹也没有改变。只有最外面的那层,不断地重生。
最终,在人类时间里只是眨眼一瞬,包裹抵达它命定的那栋写字楼。最后一名接力把它交到前门手里,敬个礼,转身继续夜色中的奔波。
第三幕——剥洋葱
前门对邮袋内容不感兴趣。它只关心最外层写的是不是"这栋楼的名字"。确认无误,收下。它的使命完成。
包裹被送进后勤办公室,内核妈妈正等着。
她轻轻拾起,撕下外层邮袋——那只服务于最后一段路。她把里面的包裹放在桌上。这一层的地址的确是写给这栋楼的,而且是"更正式"的写法。对我们有利。
她正要再拆一层,前置文员出现在她身边。
“这件是 10 号公寓的,“他说,“销售咨询。弗里达管。”
内核妈妈点点头。前置文员拿起铅笔,轻轻在包裹外面动了两笔——把"整栋楼"的收件名,改成了"10 号公寓"的具体门牌。他翻开账本认真记下:包裹 #8472,原送达大楼,重定向至 10 号。回程记得改回。记得二字他画了三道杠。他对工作极其较真。
内核妈妈拿着改好抬头的包裹,翻目录。10 号——在走廊那边,礼宾的地盘。她又加了一层小小的"楼内快递套”,直接写明"收:弗里达”,从窗口递给走廊礼宾。
第四幕——走廊
礼宾早已把走廊住户的脸背得滚瓜烂熟。前端弗里达,10 号——稳。三步并作两步,唰地把包裹从她门缝塞入。
弗里达心情一如既往地阳光。她拆套——楼内快递套, 楼层那层, 一路上的原始旅行包裹——最后打开小信封,读到里面的便条。
“这位顾客想买一台烤面包机。”
“好嘞! “弗里达自言自语。“这是布鲁图的活儿。”
她抽出一张白纸,写下"有顾客想买一台烤面包机——请处理”。装进她自己的小信封,抬头写"11 号”,再套上她自己的小快递套,从门缝推出去给礼宾。
这点很关键。弗里达没有把"原包裹"转发给布鲁图;她是写了"一份新的"包裹,代表她自己向布鲁图提出同一请求。原包裹就像一张凭据,被她留在桌上。待会儿还要用。
礼宾接过弗里达的新包裹——沿走廊三步——塞入布鲁图的门缝。
11 号屋里,布鲁图没抬头,听见包裹落地,叹了口气。拆。读。嘟囔:“烤面包机。顾客。行吧。”
他翻开大账本。扣掉一台烤面包机库存。在 Jack 的名下记一笔。砸上一个鲜红的大章"CONFIRMED"。再写一小条回执——“已接单,将发货,ID #42”——装进写给弗里达的小信封,从门缝推回。
礼宾。三步。弗里达家门缝。
弗里达看完布鲁图的回信,笑了。她转回桌上那封"原包裹",提笔写好给"最初发件人——Jack"的回信:“订单已确认,烤面包机正在路上,感谢选购。“照来时的套娃法打包:信封里信封,外套里外套。门缝,递出。
第五幕——回家
回信按来时的路径"镜像"折返。礼宾到内核妈妈。内核妈妈翻目录:发件人在"楼外”,“得从前门出”。
但她正要为出站打包,后置文员来了,啪地翻到包裹 #8472 那页。
“别忘了,“他说,“这包裹进门时,我同事把抬头从大楼改成了 10 号。现在得改回。弗里达的门牌号不能出现在外发的包裹上——对外界来说,这封回信用的是’大楼’的地址,不是任何一个具体住户。”
他用铅笔把抬头改回,合上账本。
内核妈妈给改好抬头的包裹穿上全新的外邮袋,交给前门。前门转手给门口第一位接力。信使之海再次接力,邮袋一层层重生,直到最后一位快递员冲上 Jack 的小路,把包裹从他家门缝塞进来。
浏览器小助手郑重其事地拆开,抚平回信,朗读。
“订单已确认。你的烤面包机正在路上。感谢选购。”
Jack 的浏览器里,Buy 按钮静静变绿,写成”✓ 已下单”。某处,一只猫从阳光房里抬了抬眼。Jack 笑了。
他心想:也太顺了吧。
解码器
其实,一点也不顺。

以下是每位角色"真实身份"的演职员表。像看谢幕后名单一样看它,然后意识到:刚刚那场戏,比你以为的精巧多了。
- Jack 与他的浏览器小助手:一位用户和他电脑上的浏览器。浏览器把"我点了购买"这种人类意图,翻译成服务器必须收到的那串消息。
- 小助手写的"便条"与那一层层套娃:这才是整出戏的灵魂,得多说两句。
- 每条穿越互联网的消息,都是层层嵌套的套娃。最里面那张便条是实际内容——在我们这里是"买一台烤面包机”。它叫 HTTP 请求,是浏览器和网站说话的语言。
- 其外是一层 TCP segment——加上可靠性功能(序列号, 重传, 确认回执),万一路上有丢件,能发现并补发。TCP 让互联网"像回事儿";没有它,打开网页就像抛硬币。
- 再外是一层 IP packet——写着端到端"谁发给谁"的地址。它说"这是发往商店公网地址的"。按故事设定,这一层基本不会在中途被打开或修改,它从端到端"穿越"。
- 最外是一层 Ethernet frame——最大号的邮袋。它只认识"下一跳是谁"。每一跳上路前,这一层都会被撕掉, 重写,再交给下一位。
这套嵌套——HTTP 信里,TCP 外套,IP 再外套,以太网最外套——正是学校里讲的"OSI 模型"在人话里的模样:一个给不同受众的"包里包"。
- 信使之海:互联网上的路由器。每台只知道"下一跳",合在一起便能接力跨洲。那只"IP 包端到端不变,只有以太网帧每跳重写"的事实,才是互联网能跑起来的关键:里层能活到终点,外层随时换新。
- 前门:面向外网的网卡(NIC)。在 Linux 主机上通常叫 eth0。职责如故事所述:收下发给我们的帧,丢掉其余,递给内核。
- 内核妈妈:Linux 内核本尊。她拥有所有接口, 所有路由决定, 所有地址改写, 所有在飞行中的连接。她查的"黄页"是内核路由表(routing table),身边那本"改地址规则书"是 iptables/netfilter,她记的大账本是 conntrack 表。
- 前置文员与后置文员:iptables 的 PREROUTING 与 POSTROUTING 挂钩。它们做的是 NAT(网络地址转换)。故事里的"进站改目的地到内部门牌"是 DNAT(目的地址转换)。后置文员要在出站"改回"的原因,是让外界只看见大楼的公网地址,而不是任何内部门牌。
- 走廊礼宾:内核里的虚拟桥(virtual bridge)。在跑容器的 Linux 主机上,常叫 docker0 或 podman0。它的行为和我们在上一篇里研究的"交换机"一模一样:按名字在同一走廊里把包裹送到对应住户;至于它是软件不是铁盒子,只是实现细节。
- 前端弗里达与后端布鲁图:两只容器(containers),各自住在隔离的"小公寓"里。弗里达可能跑着 nginx 这样的前端;布鲁图可能是数据库或订单处理 API。它们都插在同一条内部走廊(bridge)上,但彼此——以及对整栋楼以外——都有严格隔离,细节我们后面还会聊。
- 弗里达"重写一份新包裹给布鲁图"而不是"简单转发原包裹"的那个瞬间,正是反向代理的真实工作方式:它把一个对外会话,拆成了两个独立的会话,中间用应用层"粘"起来;不是一根管子直通。这个区别比听上去重要,我们后面会展开。
- 10 号与 11 号, 走廊与大楼:这些就是你在上一篇和本文里反复看到的 IP。弗里达的门牌是 10.88.0.10,布鲁图是 10.88.0.11,走廊网段是 10.88.0.0/16,主机(内核妈妈在走廊上的座位)是 10.88.0.1。大楼的公网地址,则取决于外界怎么看到这台主机。
- 那段"外界看不见"的弗里达与布鲁图的对话:这就是桥上的容器间通信。注意它没过 NAT,没走什么复杂路由,没碰外部接口。两间公寓,一条走廊,礼宾横向递包。便宜, 快, 对外隐形。这也是为什么 bridge 上容器互通飞快——内核几乎没离开底层。
- 两本"对上暗号"的账本:连接跟踪(conntrack)。内核记住每条活动连接以及为它做过的改写,让回复流量能完美"反解"回去,尽管改写当初是"单边"的。没有它,地球上没有任何 NAT 能工作;有了它,现代互联网(你家路由器每天为家里每台设备干的事)就能悄无声息地运转。
啊哈时刻
我那位饭搭子一听"互联网",脑海里大概飘过一根气动管道:这头塞东西,那头吐出来,中间是魔法。
可中间不是魔法。中间是一串小而笨而相同的角色,每个包裹只做一件小事情,彼此并不知情,也不关心内容。所谓"聪明",全在两端——浏览器小助手把每层地址写对,接收方把层层包裹拆开并回信。中间只是好心路人传纸条。
在写字楼里,这种"接力"继续。内核妈妈比任何一个接力员都复杂——她能改地址, 能路由, 能记账——但她本质上仍是一串小机器:门口收件,撕最外层,看地址,必要时改地址,查下一跳,重新包好,从正确的内门送出去。这是条流水线,不是魔法阵。只要你别把它想象成"一大步",就能把它整个装进脑子里。
在我脑中,第一声"咔哒"是交换机那一刻——它让我看清"一瞬间, 一地点发生了什么"。第二声"咔哒"是这台烤面包机的旅程——让我看清"一整段路上发生了什么"。两者拼在一起,就顺了。
我还没想明白的
故事里有个地方我悄悄糊弄过去了。
包裹到了弗里达那里时,我说"她的本地内核"剥了外衣,“她的门缝"收了快递,“她的桌上"放着原始包裹。看起来,弗里达似乎有她自己的小宇宙:自己的大门, 自己的 loopback, 自己的门牌, 自己的一切。
可弗里达不是一台单独的电脑。她只是跑在和内核妈妈同一台主机上的一个进程。整栋楼只有一个内核,只有一套硬件。
那弗里达的"公寓"究竟怎么"存在"的? 她如何拥有自己的内部地址, 自己的 loopback, 自己看见的走廊,却又互不踩到隔壁布鲁图的地盘? 同一个内核,怎么能并排跑出多套"平行网络世界”,而每一套都以为"世界里只有我”?
答案就是我在上一篇挥手路过, 这篇终于要扣的那枚扣子:network namespace(网络命名空间)。一旦它"咔哒"落位,你就会明白为什么容器"像是独立的小电脑"。它也是 VPN, 沙箱, 很多零信任网络的地基——也是我这整个系列慢慢铺垫的那个 bug 的底层缘由。
我会讲到的。我保证。
下回见——看我先掉进哪只兔子洞。
(人类撰写,必要处由 AI 协助润色)
