这篇的状态(2026-08-20 补记):下面写的是 2026-02-28 那一版架构。之后有几处变动大到会让原文失真,先列在这里,正文细节我没有逐段回填:

  • CNI 和入口层换掉了:两个集群在 3 月初都从 Flannel 迁到了 Cilium;homelab 随后又启用 kube-proxy replacement,并用 Cilium Gateway API 顶掉了 K3s 自带的 Traefik。原文里凡是出现 Traefik 的地方(外部流量路径、ForwardAuth),只对 3 月之前的 homelab 成立。oracle-k3s 在迁移时刻意留着 Traefik 没动,后来只补上了 kube-proxy replacement。
  • 跨集群多了一层 ClusterMesh:Tailscale 仍是底层通道,但两个集群之间接上了 Cilium ClusterMesh(当时只用到节点发现和身份联邦,没用跨集群 Service)。
  • 节点的 Tailscale IP 换过,原文里的 100.107.254.112 早就不是当前值。
  • Kopia 备份和 KaraKeep 都已停用,相关内容已经从正文里去掉,当时的实现记录留在备份体系信息管道两篇里。
  • 服务清单只跟到 2026-02 那一批:Stirling-PDF 已经换成 BentoPDF(表里改过来了),后来上线的 Playgrounds、Jobs SG、Trends、Excalidraw、Open Notebook 还没补进去。

网络这一层的当前状态,以这三篇为准:homelab CNI 迁移oracle-k3s 迁移ClusterMesh

为什么写这篇文章#

从 2024 年用 Docker Compose 起步,到现在运行着两个 K3s 集群、十几个服务、完整的 GitOps 流水线——这个 Homelab 项目已经迭代了很多轮。每次新增功能都会写一篇专题博客,但一直缺少一篇把所有东西串起来的全景文章。

这篇文章更像是那张地图。它不会深入每个组件的部署细节(那些在各自的博客里),而是回答一个问题:这些东西现在是怎么组合在一起工作的?

整体架构#

整个 Homelab 分为五层:

┌─────────────────────────────────────────────────────────────────┐
│  Layer 5: GitOps                                                │
│  ArgoCD — 自动同步 Git → 集群,3 分钟轮询                         │
├─────────────────────────────────────────────────────────────────┤
│  Layer 4: External Access & Security                            │
│  Cloudflare Tunnel + DNS + WAF ← Terraform                      │
│  ZITADEL SSO + oauth2-proxy ForwardAuth                         │
├─────────────────────────────────────────────────────────────────┤
│  Layer 3: Applications                                          │
│  Helm Charts + Raw K8s Manifests                                │
│  十几个服务分布在两个集群                                         │
├─────────────────────────────────────────────────────────────────┤
│  Layer 2: Kubernetes                                            │
│  K3s 单节点集群 × 2(Ansible 安装)                                │
│  Tailscale 跨集群 Pod/Service 网络互通                             │
├─────────────────────────────────────────────────────────────────┤
│  Layer 1: Infrastructure                                        │
│  Proxmox VE (本地) + Oracle Cloud (远端) ← Terraform              │
└─────────────────────────────────────────────────────────────────┘

Layer 1: 基础设施#

Proxmox 虚拟机(本地集群)#

Homelab 的物理基础是一台旧 Laptop,运行 Proxmox VE 虚拟化平台。通过 Terraform 在上面创建一台 Ubuntu 虚拟机:

proxmox/
├── terraform/    # IaC: VM 规格、网络、磁盘
├── ansible/      # 下载 cloud image、生成 VM 模板
  • 节点 IP: 10.10.10.10(LAN)/ 100.107.254.112(Tailscale,这个值后来变过,见文首补记)
  • Proxmox 主机: 192.168.50.3
  • 存储: NFS 服务器 192.168.50.106:/export,通过 nfs-client StorageClass 提供 PV

Oracle Cloud(远端集群)#

利用 Oracle Cloud 的永久免费 ARM 实例,通过 Terraform 创建一台 VM:

cloud/oracle/
├── terraform/    # OCI VM 资源
├── ansible/      # 节点初始化
├── manifests/    # 工作负载 YAML
  • 节点 IP: 10.0.0.26(VCN)/ 100.107.166.37(Tailscale)

两个节点通过 Tailscale 互联,形成一个跨地域的虚拟网络。

Layer 2: Kubernetes#

两个集群都使用 K3s(轻量级 K8s 发行版),通过 Ansible 自动安装:

cd k8s/ansible && just setup-k8s       # homelab 集群
cd cloud/oracle/ansible && just setup   # oracle-k3s 集群

跨集群网络:Tailscale Subnet Routing#

这是这套架构里比较关键的一层网络设计。两个集群通过 Tailscale 的子网路由功能实现 Pod/Service 网络互通:

homelab 广播:     10.42.0.0/16 (Pod)    10.43.0.0/16 (Service)
oracle-k3s 广播:  10.52.0.0/16 (Pod)    10.53.0.0/16 (Service)

效果是:oracle-k3s 上的 Pod 可以直接访问 homelab 的 ClusterIP(如 10.43.158.192 — ArgoCD),反之亦然。延迟约 80ms,就我目前的使用场景看,这对监控和异步通信已经基本够用。

这使得很多有趣的架构成为可能:

  • Uptime Kuma(oracle-k3s)通过 ClusterIP 直接监控 homelab 的所有服务
  • 集中式 Vault(homelab)为两个集群的 ExternalSecret 提供密钥

Layer 3: 应用服务#

服务全景#

两个集群上的主要服务:

服务 集群 用途 URL
Grafana homelab 可观测性仪表盘 grafana.meirong.dev
ArgoCD homelab GitOps 持续部署 argocd.meirong.dev
HashiCorp Vault homelab 密钥管理 vault.meirong.dev
ZITADEL homelab SSO 身份提供者 auth.meirong.dev
Calibre-Web homelab 电子书管理 book.meirong.dev
Gotify homelab 推送通知 notify.meirong.dev
Homepage oracle-k3s 导航仪表盘 home.meirong.dev
IT-Tools oracle-k3s 开发者工具集 tool.meirong.dev
BentoPDF oracle-k3s PDF 处理工具 pdf.meirong.dev
Squoosh oracle-k3s 图片压缩 squoosh.meirong.dev
Miniflux oracle-k3s RSS 阅读器 rss.meirong.dev
Uptime Kuma oracle-k3s 可用性监控 status.meirong.dev
Redpanda Connect oracle-k3s 流处理引擎 内部服务
PostgreSQL oracle-k3s 关系数据库 内部服务

(homelab 侧 ZITADEL 自带的 PostgreSQL 没有单列;后来新上线的几个服务见文首补记。)

集群分工原则#

  • homelab:运行基础设施服务(Vault、ArgoCD、Grafana)和需要 NFS 持久化存储的应用(如 Calibre-Web)
  • oracle-k3s:运行无状态或轻量有状态的面向用户服务(工具类、RSS、Homepage),利用 Oracle Cloud 免费的公网带宽

可观测性:LGTM Stack#

Homelab 集群运行完整的 LGTM 可观测性栈:

  • Prometheus — 指标采集(homelab 本地 scrape)
  • Loki — 日志聚合
  • Tempo — 分布式追踪
  • Grafana — 统一仪表盘

我目前给多集群监控定下的一条约定是:所有指标都尽量带上 cluster 标签

  • homelab:Prometheus scrapeClasses 为所有本地指标添加 cluster=homelab
  • oracle-k3s:不部署 Prometheus,而是用一个 OTel Collector DaemonSet 同时采集日志和指标,通过 prometheusremotewrite 推送到 homelab 的 Prometheus,自动附加 cluster=oracle-k3s
homelab:                                oracle-k3s:
┌────────────┐                         ┌──────────────────┐
│ Prometheus │◄─── scrape ───          │  OTel Collector  │
│ (本地指标)  │                         │ (DaemonSet)      │
│            │◄── remote write ────────│  logs → Loki     │
│            │                         │  metrics → Prom  │
├────────────┤                         └──────────────────┘
│   Loki     │◄── OTLP HTTP ──────────
│   Tempo    │
│  Grafana   │
└────────────┘

密钥管理:Vault + ESO#

在当前这套设计里,HashiCorp Vault 是密钥的主来源,External Secrets Operator (ESO) 负责把 Vault 中的 Secret 同步到 K8s Secret:

Vault (homelab)                K8s Cluster
┌─────────────┐               ┌────────────────┐
│ secret/      │               │ ExternalSecret  │
│   homelab/   │◄──── ESO ────│   spec:         │
│     grafana  │    同步       │     key: ...    │
│     cloudflare│               │                 │
│   oracle-k3s/│               │ → K8s Secret    │
│     ...      │               └────────────────┘
└─────────────┘

两个集群的密钥都存在同一个 Vault 实例中(secret/homelab/*secret/oracle-k3s/*),oracle-k3s 的 ESO 通过 Tailscale 跨集群访问 Vault。

Layer 4: 外部访问与安全#

Cloudflare Tunnel + DNS#

除少数例外外,大多数外部流量都通过 Cloudflare Tunnel 进入,不暴露公网端口:

Internet → Cloudflare DNS (CNAME) → Cloudflare Tunnel → Traefik → Service

两个集群各有一个独立的 Tunnel,DNS 和 Tunnel 配置全部由 Terraform 管理:

cloudflare/terraform/            # homelab tunnel:  argocd/auth/book/grafana/vault/...
cloud/oracle/cloudflare/         # oracle  tunnel:  home/tool/pdf/rss/status/...

例外是那些需要长连接或者跨集群直连的入口:它们不走 Tunnel,而是通过 Tailscale + NodePort 暴露在内网(跨集群的 Loki / Prometheus / Tempo 入口就是这么接的,见双集群全链路追踪)。gRPC 双向流尤其明显——放在 Cloudflare Tunnel 后面会 524 超时。

Cloudflare WAF#

Zone 级 WAF 规则保护 meirong.dev 下所有子域名(两个集群共享):

层级 规则
Zone 安全设置 SSL Full、TLS 1.2+、强制 HTTPS、浏览器完整性检查等 8 项
自定义 WAF (5/5) 拦截 WP/PHP 扫描路径、敏感文件、恶意 UA、高威胁 IP 质询(这条基于 cf.threat_score,实际上是空转的,原因见 WAF 那篇的补记)、非标准 HTTP 方法
速率限制 认证端点 10 req/10s per IP

全部在 cloudflare/terraform/waf.tf 中用 Terraform 管理。

SSO 单点登录#

ZITADEL(自托管 OIDC 身份提供者)+ oauth2-proxy(认证代理)实现全站 SSO:

浏览器 → Traefik → ForwardAuth 检查 → oauth2-proxy
                                   cookie 有效?
                                   ├── 是 → 放行到后端服务
                                   └── 否 → 302 重定向到 ZITADEL 登录
                                        登录成功 → 设置 .meirong.dev cookie
                                              → 7 天免登录
  • 受保护服务:book / grafana / vault / argocd / notify / home / pdf
  • 公开服务status.meirong.dev(状态页)、rss.meirong.dev(Miniflux 自带登录)、tool.meirong.devsquoosh.meirong.dev

补记:ForwardAuth 这条链是挂在 Traefik 的 Middleware 上的,3 月 homelab 切到 Cilium Gateway API 之后这套配置就不适用了,我还没写新的接法。

Layer 5: GitOps#

ArgoCD#

ArgoCD 运行在 homelab 集群,每 3 分钟轮询 Git 仓库,自动同步变更到集群:

git push → ArgoCD 检测到变更 → 自动 apply YAML → 服务更新

ArgoCD 管理的应用(auto-sync + selfHeal):

Application 内容 集群
personal-services Calibre-Web, Gotify homelab
it-tools IT-Tools (Kustomize + Image Updater) oracle-k3s
gateway Gateway API HTTPRoute homelab
cloudflare Cloudflare Tunnel 配置 homelab
vault-eso ESO 配置 + ExternalSecret homelab
zitadel ZITADEL SSO homelab
rss-system Miniflux, Redpanda Connect oracle-k3s
monitoring-dashboards Grafana Dashboard ConfigMap homelab

不由 ArgoCD 管理的组件:Vault(需手动 init/unseal)、Prometheus/Loki/Tempo(Helm release)、PostgreSQL(有状态)、NFS Provisioner(基础设施层)。

新增服务时我现在常走的流程#

1. 创建 manifests/<service>.yaml               — 定义 K8s 资源
2. 修改 manifests/gateway.yaml                 — 添加 HTTPRoute
3. 修改 argocd/applications/personal-services.yaml — include 列表
4. 修改 cloudflare/terraform/terraform.tfvars    — 添加子域名
5. git push                                     — ArgoCD 3分钟内自动部署
6. cd cloudflare/terraform && just apply         — 创建 DNS
7. 更新 Uptime Kuma provisioner                  — 添加健康检查

ArgoCD Image Updater#

对于需要自动跟踪镜像更新的服务(如 IT-Tools),使用 ArgoCD Image Updater 的 CRD 模式:检测到新镜像后自动写回 Kustomize overlay,触发 ArgoCD 同步。

健康监控#

Uptime Kuma 运行在 oracle-k3s,覆盖两个集群的主要服务(14 个 monitor,内部组件没有全部纳入)。

  • oracle-k3s 本地服务:通过 K8s DNS 直接访问(如 homepage.homepage.svc:3000
  • homelab 服务:通过 Tailscale 跨集群访问 ClusterIP(如 10.43.70.241 — Grafana)
  • 公开状态页:status.meirong.dev(不受 SSO 保护)

所有 monitor 定义在 provisioner.yaml 的 Python 脚本中,以代码形式管理。

工具链#

工具 用途
Terraform VM 创建(Proxmox、OCI)、Cloudflare DNS/Tunnel/WAF、Tailscale ACL
Ansible K3s 安装、节点配置
Helm Prometheus stack、Loki、Tempo、Vault、ESO 等
ArgoCD GitOps 持续部署
just 任务运行器(替代 Makefile,除 Proxmox Terraform 外)
Vault 密钥管理
ESO Vault → K8s Secret 同步
Tailscale 跨集群网络

项目结构#

homelab/
├── proxmox/              # Layer 1: Proxmox VM IaC
│   ├── terraform/
│   └── ansible/
├── cloud/oracle/          # Layer 1: Oracle Cloud VM IaC
│   ├── terraform/
│   ├── ansible/
│   ├── cloudflare/        # Oracle Tunnel DNS
│   └── manifests/         # oracle-k3s 工作负载
├── k8s/
│   ├── ansible/           # Layer 2: K3s 安装
│   └── helm/
│       ├── values/        # Layer 3: Helm values
│       └── manifests/     # Layer 3: K8s YAML
├── argocd/                # Layer 5: ArgoCD 配置
│   ├── install/
│   ├── projects/
│   └── applications/
├── cloudflare/terraform/  # Layer 4: DNS + Tunnel + WAF
├── tailscale/terraform/   # Layer 2: 跨集群网络
└── docs/                  # 文档、runbooks、plan 记录

演进历程#

回顾这个 Homelab 的发展路径:

时间 里程碑
2024-07 Docker Compose → K8s 迁移
2025-10 Proxmox + Terraform + Ansible 自动化
2025-10 LGTM 可观测性栈
2026-02-19 ArgoCD GitOps + Image Updater
2026-02-20 Oracle Cloud 第二集群 + Tailscale 互联
2026-02-21 OTel Collector 多集群日志/指标
2026-02-25 ZITADEL SSO 全站登录
2026-02-27 Vault + ESO 密钥管理
2026-02-28 信息管道 + Cloudflare WAF

接下来#

几个还没做的方向:

  • Cert-Manager:自动证书管理(Let’s Encrypt + Cloudflare DNS-01)
  • Vault Dynamic Secrets:PostgreSQL 动态凭证,自动轮换

当时列的另外两项后来有了结果:告警推送在 2026-04 接上了(见Alertmanager 通过 Gotify 推送告警),Kopia 备份落地过一轮,但服务本身已经停用。

相关文章#

这篇是架构全景,以下是各组件的深入专题: