一、前言
最近我对自己的 Homelab 架构做了一次阶段性调整:将原本集中在 ser7 上的一部分服务迁移到 T630 上。
这次迁移涉及的服务主要包括:
- AdGuard Home
- Prometheus / Grafana
- 博客服务
- node_exporter 监控接入
- ECS 上的 Nginx Stream 和监控安全边界整理
这篇文章不是一篇纯教程,而是一次迁移实践记录。
我会主要记录:
1. 为什么要迁移;
2. 迁移前后的节点角色;
3. 实际迁移了哪些服务;
4. 迁移后如何验收;
5. 过程中踩到或意识到的坑;
6. 这次实践带来的工程经验。
我的目标不是简单地“把服务跑起来”,而是让这个 Homelab 架构逐步变得更加清晰、可维护、可监控,也更接近真实基础设施项目的管理方式。
二、为什么要做这次迁移
ser7 是我的主力 workstation,平时承担开发、Ansible 控制、Docker Registry 等角色。
一开始服务数量不多时,把很多东西都跑在 ser7 上确实很方便。但随着 Homelab 逐渐扩大,问题也开始出现:
1. ser7 的职责越来越杂;
2. workstation 和业务服务混在一起;
3. 开发环境、监控、DNS、博客等服务耦合在同一台机器上;
4. 后续迁移、维护和排障会越来越混乱;
5. 如果 ser7 重启或维护,会影响过多服务。
所以我开始重新思考节点角色。
ser7 作为主力 workstation,更适合承担:
- Ansible 控制端;
- Docker Registry;
- 项目开发机;
- node_exporter 被监控节点;
- 后续可能运行 GitLab、K8s 等较重的实验性服务。
而像 AdGuard Home、博客、Prometheus/Grafana 这类服务,更适合迁移到 T630 这种本地边缘节点上。
这次迁移的目标可以概括为一句话:
让各个节点各司其职,避免 ser7 变成什么都跑的“大杂烩节点”。
三、迁移后的当前节点角色
本次迁移后,我的 Homelab 节点角色大致如下。
1. ser7
ser7 当前主要作为控制端和开发端存在。
当前角色:
- Ansible 控制端;
- Docker Registry;
- 项目开发机;
- node_exporter 被监控节点。
迁移后,ser7 不再承担 AdGuard Home 主服务,也不再继续堆放过多边缘业务服务。
2. T630
T630 是本次迁移后的主要边缘业务节点。
当前角色:
- Prometheus / Grafana 监控端;
- AdGuard Home 运行节点;
- 博客服务运行节点;
- node_exporter 被监控节点;
- 本地边缘业务节点。
T630 接手了部分原本由 ser7 承担的服务,使 ser7 的职责更加清晰。
3. OnePlus 6
OnePlus 6 当前作为轻量备用节点使用。
当前角色:
- 边缘测试节点;
- AdGuard Home 备用运行节点;
- node_exporter 被监控节点。
它不是主业务节点,更多是作为备用 DNS 和轻量灾备节点存在。
4. Aliyun ECS
Aliyun ECS 继续作为公网入口节点。
当前角色:
- Nginx Stream 转发节点;
- 对外开放的公网入口;
- Tailscale 内网桥接节点;
- node_exporter 被监控节点。
ECS 上的 node_exporter 只对 Tailscale 内网开放,不对公网暴露 9100 端口。
除业务必须的公网入口端口外,监控和管理类端口尽量限制在 Tailscale 内网访问。
四、这次迁移了哪些服务
这次迁移主要包括三个部分:
1. AdGuard Home 从 ser7 迁移到 T630;
2. Prometheus / Grafana 从 ser7 迁移到 T630;
3. 博客服务迁移到 T630。
同时,我也顺手梳理了 ECS 上 node_exporter、Nginx Stream 和公网暴露边界。
1. AdGuard Home 迁移到 T630
AdGuard Home 原本运行在 ser7 上,迁移后由 T630 接手。
迁移完成后:
- T630 成为 AdGuard Home 当前运行节点;
- ser7 上旧的 AdGuard Home 已停止;
- T630 成为 AdGuard Home 的唯一真实数据源;
- DNS 服务已经稳定运行数日;
- 实际测试后,DNS 解析功能正常。
这里最重要的一点是:
AdGuard Home 是一个有状态服务。
它不仅有启动配置,还包含:
- 过滤规则;
- 证书;
- 查询日志;
- 统计数据;
- session;
- 运行时数据库;
- Web UI 中产生的配置变化。
这些数据都会随着服务运行持续变化。
所以我没有选择让 Ansible 反复从 ser7 覆盖这些运行时数据到 T630,而是采用了一次性迁移方式:
1. 使用 scp 将原有服务数据迁移到 T630;
2. 在 T630 上手动拉起服务;
3. 确认服务正常;
4. 停止 ser7 上旧的 AdGuard Home;
5. 将 T630 确认为唯一真实数据源。
这个过程让我意识到:有状态服务迁移最重要的不是“容器能不能跑起来”,而是要明确数据真实源。
2. Prometheus / Grafana 迁移到 T630
Prometheus / Grafana 也完成了从 ser7 到 T630 的迁移。
当前 Prometheus 可以抓取以下节点的 node_exporter 指标:
- ser7;
- T630;
- OnePlus 6;
- Aliyun ECS。
Prometheus targets 页面中,各节点状态均为 UP。
监控链路主要通过 Tailscale 内网完成,node_exporter 等监控端口不直接暴露到公网。
这样设计的原因是:
1. node_exporter 会暴露大量主机指标,不适合公网开放;
2. 通过 Tailscale 可以让跨地域节点组成一个安全内网;
3. Prometheus 可以通过 Tailscale 统一抓取各节点指标;
4. 监控面和公网业务入口可以尽量隔离。
这并不代表系统“绝对安全”,但确实减少了公网暴露面,降低了被扫描和未授权访问的风险。
3. 博客服务迁移到 T630
博客服务也迁移到了 T630 上。
这样做之后,T630 不只是一个 DNS 节点,也开始承担更多本地边缘业务服务。
对我来说,这也有一个额外意义:
博客不只是记录 Homelab 的地方,它本身也成为了 Homelab 架构中的一个真实业务服务。
五、迁移后的验收结果
服务迁移不是“能启动”就结束了。
迁移完成后,我对几个关键点做了验收。
1. AdGuard Home 验收
当前已确认:
- AdGuard Home 已完成从 ser7 到 T630 的迁移;
- T630 上的 AdGuard Home 已稳定运行数日;
- DNS 解析功能测试正常;
- ser7 上旧的 AdGuard Home 已停止;
- 当前 T630 是 AdGuard Home 的唯一真实数据源。
后续还需要补充:
- dig 测试记录;
- AdGuard Home 过滤规则测试记录;
- OnePlus 6 备用 DNS 测试记录。
2. Prometheus / Grafana 验收
当前已确认:
- Prometheus / Grafana 已迁移到 T630;
- Prometheus 可以抓取 ser7 的 node_exporter 指标;
- Prometheus 可以抓取 T630 的 node_exporter 指标;
- Prometheus 可以抓取 OnePlus 6 的 node_exporter 指标;
- Prometheus 可以抓取 Aliyun ECS 的 node_exporter 指标;
- Prometheus targets 中各节点状态均为 UP;
- node_exporter 监控端口不对公网开放,主要通过 Tailscale 内网访问。
后续还需要补充:
- Prometheus targets 截图;
- Grafana 节点监控截图;
- 服务级可用性探测,例如 AdGuard Home 和博客服务探测。
3. ECS 安全边界验收
当前已确认:
- ECS 仅开放业务所需的公网入口端口;
- node_exporter 的 9100 端口不对公网开放;
- Prometheus 通过 Tailscale 抓取 ECS 指标;
- 监控和管理类端口限制在 Tailscale 内网访问;
- Nginx Stream 配置由 Ansible 模板管理;
- Nginx 配置变更采用先测试再 reload 的方式生效。
ECS 作为公网入口节点,安全边界非常重要。
尤其是 node_exporter 这类组件,绝对不应该直接暴露到公网。
当前的设计是:
公网入口由 ECS 承担;
监控和管理通信通过 Tailscale 完成;
node_exporter 不暴露公网;
Nginx 配置变更先 nginx -t,再 reload。
这比简单地把端口全开在公网要安全得多。
六、这次迁移中的几个坑和思考
这次迁移过程中,真正有价值的并不是某一条命令怎么写,而是几个工程判断上的变化。
1. 坑一:ser7 不应该什么都跑
一开始,我很容易把 ser7 当成万能节点。
因为它性能更强、用起来方便,所以很多服务都会自然地堆到 ser7 上。
但这样时间久了会产生问题:
- 开发环境和业务服务混杂;
- 节点职责不清晰;
- 后续排障时很难判断哪个服务影响了哪个服务;
- ser7 一维护,很多服务都会受影响。
这次迁移后,我更加明确了 ser7 的定位:
ser7 应该更像控制端和开发端,而不是所有业务服务的集中运行点。
2. 坑二:有状态服务不能盲目 Ansible 化
我之前很容易有一种想法:
既然我要做基础设施即代码,那是不是所有东西都应该交给 Ansible 管?
这次迁移 AdGuard Home 后,我意识到这个想法并不完全正确。
AdGuard Home 这类服务有很多运行时状态:
- querylog;
- stats;
- session;
- 过滤规则;
- 运行时数据库;
- Web UI 修改产生的配置变化。
如果迁移完成后,还继续用 Ansible 从 ser7 覆盖 T630 上的运行数据,就可能导致:
- 查询日志回滚;
- 统计数据丢失;
- 过滤规则被旧版本覆盖;
- Web UI 修改失效;
- 新旧数据源混乱。
所以最终我选择:
一次性迁移数据;
T630 成为唯一真实源;
Ansible 不反复覆盖 AdGuard Home 运行时数据;
Ansible 只管理外围部署逻辑。
这次实践让我更清楚地认识到:
自动化不是把所有东西都强行纳入 Ansible。
自动化的前提是先判断清楚边界。
3. 坑三:迁移完成后必须明确唯一真实源
服务迁移最怕出现一种情况:
旧服务还在跑;
新服务也在跑;
两边都在产生数据;
最后不知道谁才是准的。
这次迁移 AdGuard Home 时,我明确做了几件事:
- 数据从 ser7 迁移到 T630;
- T630 拉起服务并验证;
- ser7 旧服务停止;
- 后续以 T630 数据为准。
这样可以避免“双主”和“状态分裂”。
这也是我这次最大的收获之一:
有状态服务迁移时,必须明确唯一真实源。
4. 坑四:node_exporter 不能暴露公网
node_exporter 是非常常见的监控组件,但它暴露的是主机指标。
这些指标虽然不是密码,但包含很多基础设施信息,例如:
- CPU;
- 内存;
- 磁盘;
- 文件系统;
- 网络;
- 系统负载;
- 运行状态。
如果直接把 9100 暴露到公网,很容易被扫描,也会泄露很多主机信息。
所以我在 ECS 上将 node_exporter 限制在 Tailscale 内网访问。
Prometheus 通过 Tailscale 抓取指标,而不是通过公网访问 9100。
这个设计在个人 Homelab 里非常实用。
5. 坑五:Nginx 配置不能直接粗暴重启
ECS 上的 Nginx Stream 配置由 Ansible 管理。
这里我采用的方式是:
1. Ansible 下发配置;
2. 执行 nginx -t;
3. 配置测试通过后再 reload。
而不是配置一改就直接 restart。
这样做的好处是:
- 可以提前发现配置错误;
- 避免错误配置导致入口服务中断;
- reload 比 restart 对现有连接影响更小;
- 变更过程更安全。
这个细节虽然不复杂,但非常重要。
6. 坑六:Tailscale 很方便,但网络路径仍需要关注
这次架构里,Tailscale 承担了很重要的作用:
- 内部通信;
- 管理面访问;
- Prometheus 抓取指标;
- 跨地域节点连接。
但目前我还没有自建中继节点,所以部分场景下网络路径和速度可能会受到影响。
后续如果对稳定性和延迟有更高要求,可以考虑建设自建节点,进一步优化访问体验。
七、这次迁移带来的收获
这次迁移让我对 Homelab 的理解更进了一步。
以前我更多关注:
服务能不能跑;
配置能不能生效;
容器能不能启动。
现在我开始更多关注:
节点职责是否清晰;
服务迁移后如何验收;
数据真实源是否明确;
端口是否暴露过多;
Ansible 该管什么,不该管什么;
出现问题后如何回滚和排查;
这些实践能不能沉淀成文档。
这对我来说是一个很重要的变化。
因为真正有价值的 Homelab,不应该只是“装过很多软件”。
更重要的是:
我能解释为什么这样设计;
我知道哪些东西该自动化,哪些不该;
我遇到过真实的迁移、监控、安全和状态数据问题;
我能把实践转化成文档、复盘和可展示的项目经验。
八、当前结论
本次 ser7 到 T630 的服务迁移已经完成主要目标。
当前结果如下:
- T630 接手了部分原本由 ser7 承担的业务服务;
- AdGuard Home 已迁移到 T630,并稳定运行;
- Prometheus / Grafana 已迁移到 T630;
- 博客服务已运行在 T630;
- ser7 旧 AdGuard Home 已停止;
- Prometheus 可以正常抓取多个节点的 node_exporter 指标;
- ECS 上的 node_exporter 不对公网开放;
- 节点之间的监控和管理通信主要通过 Tailscale 完成;
- AdGuard Home 迁移后以 T630 为唯一真实数据源;
- Nginx Stream 配置由 Ansible 管理,并采用检查后 reload 的方式降低风险;
- 本次迁移进一步明确了 Ansible 与有状态服务运行数据之间的边界。
整体来看,这次迁移让我的 Homelab 从“服务能跑”向“角色清晰、边界明确、可监控、可维护”迈进了一步。
九、后续计划
后续我准备继续补充和完善以下内容:
1. 补充 dig 测试记录;
2. 补充 AdGuard Home 过滤规则测试记录;
3. 补充 OnePlus 6 备用 DNS 测试记录;
4. 补充 Prometheus targets 截图;
5. 补充 Grafana 节点监控截图;
6. 补充当前 Homelab 架构图;
7. 补充 ECS 公网端口检查记录;
8. 将本次迁移整理为 Markdown 文档,放入 GitHub 仓库;
9. 后续继续完善 Traefik、服务级监控和 CI/CD 流程。
这次迁移只是 Homelab 长期建设中的一个阶段。
后续我希望继续围绕 Ansible、Docker、Prometheus、Tailscale、Go 和云原生方向,把这个 Homelab 打磨成一个可维护、可复现、可展示的长期工程项目。