KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
01 · 内网隔离 — keel 龙骨
类型:衍生概念(服务于「交付包」) · 应用课对应:03 章 · 没有外网,怎么把制品搬进去
类型:衍生概念(服务于「交付包」) · 应用课对应:03 章 · 没有外网,怎么把制品搬进去
这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。它不讲怎么配防火墙。
一、它为什么会出现
构建镜像时遇到过这样一次失败:
unexpected status from HEAD request to http://hub-mirror.c.163.com/v2/library/python/manifests/3.12-slim: 502 Bad Gateway
重试一次就成了。在能上外网的机器上,这件事的结论只是"网络抖了一下"。
同一个故障放到客户机房里,它就不再是"抖一下"——那里连"重试"这个动作都不存在,因为那条出口本来就不通。
需求一句话:在那台机器上,"需要的时候去取一下"这个动作永远不可能成立,所以任何依赖它的设计都不成立。
二、它是什么
一句话:内网隔离指的是那台机器到外面没有一条可走的路——不是慢,是没有。
它的可观察形态很硬:内核直接拒绝,而不是超时。
连不上: OSError [Errno 101] Network is unreachable
这句话的形状比内容更重要,因为它把两类完全不同的处境分开了:
| 报错 | 意味着 | 现场该做什么 |
|---|---|---|
timed out |
包发出去了,没人应答——这是网络故障 | 重试、换 DNS、加代理都可能有用 |
Network is unreachable |
根本没有路由可走——这是配置事实 | 再重试也是同一个结果 |
它不是下面这三样东西:
- 不是"网络慢"。 慢和不通的区别是:慢可以等,不通等多久都一样。
- 不是"加个白名单就能通"。 白名单意味着有一条路;这里是没有路,两者不是同一件事。
- 不是一条安全设置。 它是一条能力前提——从它出发,交付形态里的每一条设计都被倒逼出来。
三、它长什么样
它落成编排文件里的两行声明,读出来是两组不同的值:
networks:
data:
internal: true # 数据面:内部网络,没有通往宿主机的出口
edge: {} # 接入面:只有需要被访问的服务挂在这里
docker network inspect board_data --format '{{.Name}}: internal={{.Internal}} driver={{.Driver}}'
docker network inspect board_edge --format '{{.Name}}: internal={{.Internal}} driver={{.Driver}}'
data: internal=true driver=bridge
edge: internal=false driver=bridge
internal: true 不是一句注释,它是一条内核层面的规则。它的后果可以在一个只挂在 data 网络上的 worker 容器里量出来——上面那句 Network is unreachable 就是它。
四、它怎么工作
隔离怎样一层层成立,四步:
① 声明 编排文件把网络分成两份:data 标 internal,edge 不标
↓
② 落网 每个服务只挂自己需要的那一个:db 与 worker 只在 data,只有 web 多挂一个 edge
↓
③ 判定 容器起来的这一刻,内核按这个归属给出路由表:data 上的容器没有默认网关
↓
④ 显形 任何"出去取点什么"的尝试都停在第一步,报的是 unreachable,而不是超时
第 ③ 步是这一页最该带走的一步:**隔离不是被检查出来的,是容器一启动就已经成立的事实。**后半句才是它的分量——凡是需要一个服务"出去拿点什么"的设计,在这个形态里都不成立。
五、它会带出哪些概念
- 交付包:因为对面没有出口,镜像、脚本、哈希清单才必须一次性带齐。→ 00 页
- 实例:数据面不对外,正是同一台机器能装下多套部署的前提之一。→ 02 页
- 迁移与结构版本:装和升都要在对面本地完成,库结构也只能由包里那份代码来推进。→ 03 页
六、回到应用课
| 应用课里的那句话 | 现在你知道它为什么成立 |
|---|---|
"internal: true 不是一句注释,它是一条内核层面的规则" |
它在容器创建时就写进了路由表,所以它的表现是"没有路",不是"路不通" |
| "「从仓库拉」这个动作本身有前提" | 仓库要活着、镜像源要能解析、链路上每一跳都不能挂;这三条在内网里一条都不成立 |
| "它不报「没有网络」,它挂在那里等超时" | 那是一次会超时的取用动作,而不是一句网络诊断——所以报错指向的不是根因 |
| "凡是需要一个服务「出去拿点什么」的设计,在这个形态里都不成立" | 唯一能谈的对象是同一个网络里的那些容器,别的都在这条边界之外 |
这一页改变了你的哪个判断:看到一条失败信息时,你先分流——"这是没有路,还是路不通";前者要改的是设计,后者才值得去查网络。
→ 这一页的展开在应用课 03 章 · 没有外网,怎么把制品搬进去。
自测题
Network is unreachable与timed out的区别是什么?为什么这个区别决定了现场下一步该查什么?- 为什么说"内网隔离不是被检查出来的,而是容器一启动就已经成立的事实"?