文档 / Cloud-init 与机器镜像

Cloud-init 与机器镜像

跳过手动安装的两种方式:在创建 VPS 时粘贴一份 cloud-init 模板, 或者构建一个已经装好一切的 机器镜像。

Cloud-init(一次一台服务器)

panel/deploy/cloud-init.yaml 是一个 user-data 模板。编辑 顶部那几项设置,在创建服务器时把它粘贴进你服务商的 “user data” 框, 服务器启动完成时面板就已就绪。进度和任何失败都会记录到 /var/log/nimbopanel-provision.log。

不要把 user data 当作机密存储

这是值得读两遍的部分。在每一家主流服务商上,user data 都可以 从运行中的实例内部 通过 169.254.169.254 上的 HTTP 取回—— 而该地址可被机器上的 任何 进程访问,包括一个主机 客户的 PHP 脚本。

因此,粘贴进 user data 的一个许可证密钥,会被你托管的每一个客户读到, 除非有东西阻止它。模板分两步阻止它,按此顺序:

  1. 它在密钥落盘 之前 把元数据服务对除 root 以外的所有人 关闭;
  2. 在安装器把密钥存入仅 root 可读的配置之后,它会粉碎 user data 在磁盘上的副本。

如果你宁愿根本不把密钥放在那里,就把它留空,稍后从 面板输入。在你输入之前服务器以未授权状态运行,这是一种受支持的 状态。

机器镜像(一次构建,多台服务器)

panel/deploy/packer/nimbopanel.pkr.hcl 构建一个已装好整套栈的 镜像。时间就花在那里——软件包、PHP、邮件、DNS、数据库—— 而这一切在各台服务器之间毫无差别。

那个会让每个克隆都变成同一台服务器的错误

镜像必须 不含任何身份。如果它含有,那么由它构建出的每一台服务器都会共享 那个身份:

被错误地烘焙进去的东西 在每个克隆上会发生什么
SSH 主机密钥 它们全都出示相同的密钥。任何处于客户与其服务器之间的人都能冒充它,在所有克隆上,且不显示任何警告
Nimbopanel 的 instance-id 许可证指纹 由它派生,而安装器绝不会重新播种一个已存在的 id——于是一千台服务器看上去像一次激活
/etc/machine-id systemd、DHCP 租约和 journald 身份会发生冲突
面板数据库和配置 管理员密码、许可证密钥和每一个账户都装在一个陌生人下载的文件里
DKIM 密钥、TLS 证书 是为构建机器签发的;在克隆上毫无意义,且泄露给拿到该镜像的每一个人

这些都不会自己声张。它们是后来被别人发现的。

panel/deploy/image-deidentify.sh 会把这一切全部移除,Packer 构建把它作为 最后 一步运行,然后再以 --check 重跑一次,因此构建会失败, 而不是产出一个只是看起来干净的快照。被移除的一切都会在 克隆首次启动时被重建:sshd 生成新的主机密钥,systemd 写入新的 machine-id,安装器播种一个全新的 instance-id。

/etc/machine-id 被留为 空,而不是删除——systemd 把一个空文件读作 “启动时生成一个”,而缺失的文件会让某些镜像根本无法启动。

发布之前先验证

sudo ./image-deidentify.sh          # remove
sudo ./image-deidentify.sh --check  # confirm, exits non-zero if anything survives

也要在一个已启动的克隆上运行这项检查,而不只是在构建时。如果它报告了任何东西, 就不要发布该镜像。

应用市场上架

服务商的 “一键应用” 项目(Vultr、DigitalOcean、Linode、Contabo)各自有 各自的提交格式和审核。上面的镜像正是他们所要的 产物;那些文书工作是各服务商特有的,不是这套工具能替你完成的。