[🛠] IT Operations #2: 公司服务专用Linux服务器,先于安装搭好运维结构
✨ GPT-5.6 Sol 的总结
记录我为专用Ubuntu Server配置磁盘、内网SSH和固定地址,拆分人员、AI Cell与业务自动化Runtime的权限,并把整个网络整理成可由Codex持续接手的运维基础。
终于,我搭好了公司服务专用的Linux服务器。
不过,这次做出来的并不只是一台能启动Ubuntu的电脑。它更像是一套运维基础:即使人员、AI和业务自动化服务同时运行在同一台服务器上,也不会相互侵入权限与状态。
刚拿到SSD时,我的想法还很简单。在Windows PC上安装Linux,再通过SSH连接,不就成服务器了吗?我马上又开始纠结GUI。要是只为了显得像一台“正经服务器”而坚持CLI,之后需要浏览器登录或Computer Use时,会不会反而吃苦头?
逐项梳理后我才发现,服务器是否需要GUI,和我是否需要使用GUI,完全是两个问题。需要OAuth或登录Codex时,可以把SSH画面显示的地址复制到MacBook浏览器中打开。需要Computer Use时,就在我的Mac或工作设备上运行,把Linux留作最终部署结果的Runtime。
服务器不是展示画面的机器,而是持续运行的环境。
保护Windows磁盘的UEFI、GPT与LVM配置
从安装U盘开始就让人困惑。我以为Ventoy U盘使用MBR,Ubuntu也会以MBR方式安装。启动菜单出现UEFI: USB, Partition 2时,我甚至不确定这是不是正确入口。
U盘的分区方式与安装Ubuntu的SSD分区方式互不相干。只要从UEFI项目启动安装程序,并准确选择目标SSD即可。我没有碰现有的Windows NVMe,只在新买的250GB SSD上创建EFI System Partition、/boot、LVM和root filesystem。
这个过程中最可怕的不是Linux难用,而是误删其他磁盘。看到Windows的系统保留分区时,它甚至显得像是可以删掉的东西。但我在安装程序中重新核对了磁盘型号与容量,只选择Ubuntu专用SSD。原有Windows磁盘完整保留了下来。
我选择了Ubuntu Server 24.04.4 LTS的标准配置,既不是minimized,也不是Desktop image。去掉GUI后,只留下以SSH和systemd为中心的管理基础,方便之后部署Docker Runtime。
固定地址之前更需要DHCP预约与内网SSH
安装期间,有线LAN通过DHCP立即拿到了地址。一开始我以为按下Create bond,SSH会更容易连接,或者地址就能固定下来。但bond是把多块NIC组合起来实现冗余或叠加带宽的功能,与固定单块有线NIC的地址无关。
我没有在服务器里硬编码一个随意的static IP,而是在主路由器中通过DHCP预约,把NIC的MAC地址与内网IP绑定起来。服务器仍然是DHCP client,但每次重启都会收到同一个地址,还可以从路由器端检查是否与其他预约设备冲突。
SSH也没有暴露到互联网。我为MacBook创建了专用Ed25519 key,在控制台核对服务器host key后,将它固定到内网地址。路由器没有设置外部22端口的forwarding。
安装后看到ssh.service显示为disabled时,我一度以为SSH装坏了。实际上,ssh.socket处于启用状态并监听22端口,重启后public-key login也反复成功。socket activation能在请求进入时启动相应service,因此不能只看一行service状态就判断故障。1
几天前,在修复公司路由器断网故障时学到的DHCP lease、reservation和IP–MAC binding的区别,这次直接用在了服务器基础建设上。拿到一个地址,和能够通过这个地址安全管理设备,是两回事。
没有混在同一个账号里的人员、AI Cell与服务
SSH连通后,我正想像往常一样,先装Oh My Zsh、Powerlevel10k和个人alias。到这里我又停了下来。
安装时创建的第一个账号,是公司所有、用于bootstrap与恢复的管理员账号。把我日常使用的shell、AI Runtime和Operations Automation全都塞进这一个账号,确实很方便。但这样无法区分谁以什么权限执行了什么,日后增加负责人或回收账号时,所有东西都会纠缠在一起。
因此,我先按以下规则拆分账号。
bootstrap管理员
└─ 仅用于安装与恢复
usr-<person>
└─ 人员用于SSH、sudo和开发工作的账号
aio-cell-<person>
└─ 个人AI Cell持续运行的账号
svc-<domain>-<purpose>
└─ 应用Runtime、数据importer、受限operation broker
username中不加入公司名称或岗位也是有意为之。即使所属组织和职责发生变化,人还是同一个人。Linux login只表示稳定身份,管理员、开发者、项目成员等权限则更适合通过group与RBAC独立调整。
我决定只在人类账号中保留惯用的OMZ、P10K与alias。AI Cell和service account不会读取interactive shell配置,而会通过固定的systemd unit、EnvironmentFile和绝对路径运行。漂亮的prompt能提高我的工作效率,却与服务稳定性毫无关系。
这些账号目前还没有全部急着创建。我先确定了命名、文件所有权、是否允许登录,以及sudo和Docker的访问范围。趁服务器还是空的先划清边界,远比等一切都混进同一账号后再拆分简单。
AI Cell的边界延伸到UID、HOME与OAuth
这次我理解变化最大的部分,是多用户系统。
如果只看Desktop GUI,很容易觉得当前显示在登录画面的用户占用了整台电脑。但在Linux中,可见的登录画面与正在运行的用户是两回事。多个用户可以同时通过SSH连接,没有登录的service account进程也能在systemd下持续运行。
这种结构在把曾以macOS用户为单位重新定义的AI Cell扩展到Linux时尤其重要。一个AI Cell并不只是一个process名称。
1个AI Cell
= 1套Linux UID与HOME
= 1套OAuth与CODEX_HOME
= 1套Gateway与Port
= 1套Session、Memory与Workspace
= 1套systemd unit与cgroup budget
每个人的Cell使用不同UID和HOME后,认证、记忆与工作空间自然分开。每个Cell运行在不同的port或Unix socket上,即使用户没有通过SSH登录,systemd也会在开机后持续运行它。一台服务器上可以同时存在多个Cell,而不会把某个Cell的OAuth或Memory当作另一个Cell的fallback。
反过来,我决定不给AI Cell提供sudo、整个NAS的mount、生产DB管理员credential或Docker socket。Docker官方文档也警告,docker group会授予用户root级权限。2 为了方便就把人员、AI和service account都加入这个group,等于实际抹掉了前面划分的边界。
Docker操作将由人类管理员明确使用sudo,或由root所有的受限helper与systemd unit仅执行预先定义的operation。AI可以协调部署,但不会直接拥有任意shell与全部Docker权限。
NAS负责ingress,Linux负责application Runtime
Linux服务器并不只用于AI Orchestration。Operations Automation的Web、API与DB也计划在同一设备上的Docker Runtime中运行。但这并不意味着所有东西都放进同一个账号、同一个Compose project或同一个network。
外部连接继续沿用现有NAS负责的HTTPS和reverse proxy。Linux负责运行真正的application。
外部用户
→ HTTPS 443
→ 公司路由器
→ NAS TLS与hostname reverse proxy
→ Linux frontend
→ Docker内部API
→ Docker内部DB
无需把NAS管理port、Linux SSH、API与DB port直接暴露到互联网。NAS继续作为处理hostname与证书的ingress,以及storage与backup节点;Linux负责application Runtime。这并不是废弃将休假自动化迁移到NAS时建立的外部HTTPS路径,而只是把最终backend迁移到专用服务器。
代码部署与从NAS导入HR信息也没有被绑成同一个操作。
代码
→ 验证release与artifact hash
→ 受限deploy helper
→ health check与rollback
HR数据
→ NAS中已批准的read-only文件夹
→ staging、validation与preview
→ 批准
→ DB transaction与audit
AI Orchestration可以分析变更并请求批准,但实际部署和数据导入由只接受规定operation的broker与importer分别执行。MacBook可以用于开发、dry-run、preview确认以及启动已批准的任务,但不会作为生产DB的canonical mutation节点。
目前Linux服务器上还没有Docker与application DB。因此,我没有因为DHCP预约和SSH成功,就把它称为production backend。只有准备好准确的frontend port、health check、backup与restore以及rollback后,才能更改NAS reverse proxy的target。
由Codex Skill记住的完整网络topology
与服务器配置同样重要的,是如何连接到下一次对话。
我把路由器、两台NAS、现有Mac Runtime、新Linux服务器、外部HTTPS与内网SSH之间的关系,更新到公司网络专用Codex Skill及详细inventory中。它不只是IP清单,而是区分每台设备的职责,以及traffic的起点、中间hop和最终Runtime。
Skill也没有混淆已经完成的事实与未来计划中的结构。
- Ubuntu安装、重启和内网SSH已经完成。
- 多用户identity与权限边界已经决定,但账号尚未创建。
- Linux上的Docker、AI Cell和Operations Automation尚未部署。
- 只有在health与rollback就绪后,NAS reverse proxy才会切换到Linux。
现在,即使打开新的Codex session,也不必从“服务器IP是什么来着?”“NAS是在运行application吗?”“SSH service为什么是disabled?”重新解释。Skill会把真实topology、安全边界、已验证状态与未完成状态一起传递过去。
所以,现在这台服务器还不是完成的production server,却也不只是一块装有Ubuntu的空SSD。下一步是在已经确定的边界内,真正部署人员账号、AI Cell与Operations Automation Runtime。
今后每安装一样东西,我大概都会先问:“由哪个账号运行?”“它拥有哪些HOME与credential?”“只允许哪些port与data flow?”与其说是做出了一台服务器,不如说我先制定了让服务器持续扩展而不至于不断损坏的标准。
参考资料
-
systemd的socket unit可以监视socket,并在incoming traffic到达时激活相应service。systemd.socket官方手册 ↩
-
能够访问Docker daemon Unix socket的
dockergroup会授予root级权限。Docker Engine Linux安装后步骤 ↩
留下评论