Incus 脚本审阅与验收SWES · 技术记录

Incus 审阅 04|端口不是越多越好,让每个公开入口都有归属

Incus 脚本审阅与验收 · 第 4 / 8 篇 容器能出网以后,下一个需求通常是“把里面的服务开放出来”。如果一开始就给六台容器各开放一大片 TCP 和 UDP 端口,配置虽然省事,后续却很难回答哪个端口属于谁、里面是否真的有服务、删除一段会不会切断 SSH。端口管理器要解决的是可维护的映射关系

Incus 脚本审阅与验收 · 第 4 / 8 篇

容器能出网以后,下一个需求通常是“把里面的服务开放出来”。如果一开始就给六台容器各开放一大片 TCP 和 UDP 端口,配置虽然省事,后续却很难回答哪个端口属于谁、里面是否真的有服务、删除一段会不会切断 SSH。端口管理器要解决的是可维护的映射关系。

管理端口与业务端口的分离

SSH 与业务端口为什么分开

部署脚本预期建立 ssh2201—ssh2206。业务管理器则创建 pm_tcp_22030、pm_udp_22030 一类设备,并仅把符合其命名格式的本地 proxy 设备列为可删除对象。清晰的命名约定使管理入口与业务入口可以分开处理。

这是一种操作约束,不是密码学意义上的所有权证明。用户如果手工创建同名 pm_ 设备,管理器仍可能把它视为可管理对象;未来可增加受控的分配清单,并核对设备内容,而不只认名字。

这份脚本采用普通 proxy,而不是 nat=true

例如,选择 vps3 并添加 TCP 22030,代码会生成下面的等价映射:

# 会公开监听 IPv4 的业务端口;先确认端口归属与防火墙范围
incus config device add vps3 pm_tcp_22030 proxy \
  listen=tcp:0.0.0.0:22030 \
  connect=tcp:127.0.0.1:22030

此处的连接目标是实例一侧的回环地址,不是让业务请求回到宿主机的回环服务。程序仍需在容器内相应地址和端口监听。普通 proxy 与 NAT 模式有不同的数据路径和客户端地址处理方式;不能把上面命令直接宣传为“保留真实客户端 IP 的 NAT”。Incus proxy 官方说明

原文档的 22010—22019、22020—22029 等段只是提示。脚本没有强制把某段锁给某台实例,而是每次检查冲突。TCP 和 UDP 是两个独立的协议端口;选择一个端口、两种协议,会生成两个设备。单次最多输入 50 个端口,选择 TCP+UDP 时最多创建 100 个设备,不能把这个限制误写成“最多 50 个设备”。

冲突检查解决了什么,还漏了什么

代码先读取已识别的 vps数字 实例及其展开设备,再扫描 ss -H -lntu 的本机监听。发现问题就停止;批量添加中途失败时,尝试逆序移除本轮已经成功添加的设备。这是有价值的失败收尾,但不是数据库事务,回滚也可能失败。

检查范围不覆盖任意名字的 Incus 实例、所有项目和远程宿主机,也不一定能发现没有本机监听进程的 Docker DNAT、手写防火墙映射或未来才启动的服务。检查与真正创建之间仍有竞争窗口。生产版本应记录分配结果,核对所有相关资源,并把 Incus 的创建错误作为最终裁决。

为什么菜单一出现就退出

这份实现把 Python 程序通过文件描述符 3 传入,交互输入则专门打开 /dev/tty。它把“程序代码从哪里来”和“用户回答从哪里来”分开,避免脚本来源、重定向或管道把标准输入用完后,菜单立刻读到 EOF。

因此它要求真正的交互终端。它适合 SSH 终端,不适合直接当作无终端计划任务。自动化接口应使用明确参数、退出码与日志,不能依赖一个会等待人工输入的菜单。

删除确认也要以代码为准

手册和提示文字写“须输入 yes”,但当前实现实际接受 y 或 yes,回车取消。这是文案与行为不一致,不能在教程里继续写成“只有完整 yes 才删除”。删除前仍应查看列出的设备,确认它们是本次要移除的业务映射。

端口完成配置后怎样证明可用

incus config device show vps3
incus exec vps3 -- ss -lntup
ss -lntup

然后从另一台机器访问宿主机的目标端口,并在容器服务日志中确认请求抵达。TCP 端口握手只能证明连接;HTTP 服务还应验证状态码与内容,UDP 服务应使用其应用协议发请求并观察响应或日志,不能用 TCPing 证明 UDP 正常。

理想结果:设备有归属、协议匹配、容器服务真实响应、外部请求可验证、移除映射后 SSH 不受影响。当前代码具备部分防误操作机制;上述完整链路仍需在测试实例验收。

系列阅读目录

  1. 01|一台 VPS 拆成六台“小鸡”,到底拆出了什么

  2. 02|部署之前先算清楚,3GiB 根盘与 12GiB 存储池如何配合

  3. 03|容器能启动却不能联网,为什么要查 Docker 的转发规则

  4. 04|端口不是越多越好,让每个公开入口都有归属

  5. 05|只重装一台小鸡,保住的究竟是配置还是数据

  6. 06|菜单不再秒退之后,为什么还要检查 YAML 缩进和密码记录

  7. 07|Komari 显示在线以后,还要验证什么

  8. 08|怎样才算真正做好,把“完美结果”写成可复查的验收单

感谢阅读 · 保持好奇,认真记录。浏览更多文章 ↗