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,而不是超时

第 ③ 步是这一页最该带走的一步:**隔离不是被检查出来的,是容器一启动就已经成立的事实。**后半句才是它的分量——凡是需要一个服务"出去拿点什么"的设计,在这个形态里都不成立。

五、它会带出哪些概念

六、回到应用课

应用课里的那句话 现在你知道它为什么成立
"internal: true 不是一句注释,它是一条内核层面的规则" 它在容器创建时就写进了路由表,所以它的表现是"没有路",不是"路不通"
"「从仓库拉」这个动作本身有前提" 仓库要活着、镜像源要能解析、链路上每一跳都不能挂;这三条在内网里一条都不成立
"它不报「没有网络」,它挂在那里等超时" 那是一次会超时的取用动作,而不是一句网络诊断——所以报错指向的不是根因
"凡是需要一个服务「出去拿点什么」的设计,在这个形态里都不成立" 唯一能谈的对象是同一个网络里的那些容器,别的都在这条边界之外

这一页改变了你的哪个判断:看到一条失败信息时,你先分流——"这是没有路,还是路不通";前者要改的是设计,后者才值得去查网络。

→ 这一页的展开在应用课 03 章 · 没有外网,怎么把制品搬进去。

自测题

  1. Network is unreachable 与 timed out 的区别是什么?为什么这个区别决定了现场下一步该查什么?
  2. 为什么说"内网隔离不是被检查出来的,而是容器一启动就已经成立的事实"?

进入 keel 阅读