Files
panxiao81 110dbcc2c3
ansible / lint (pull_request) Failing after 0s
ansible / collection-test (pull_request) Failing after 0s
yaml / yaml (pull_request) Failing after 0s
terraform / validate (pull_request) Failing after 0s
新增 Nexus 统一制品仓库 POC
2026-09-18 19:11:30 +00:00
..

DNS 声明与权威边界

records.yml 是 homelab DNS 的唯一声明清单,但不是 DNS 服务本身。不同视图仍由最适合 它们的后端提供:

视图 权威或递归服务 配置方式
公网 ddupan.top Cloudflare 由生成器输出 Terraform;尚待完整导入已有记录
AD ad.ddupan.top Samba internal DNS samba_dns_record Ansible module
LAN split horizon Blocky 由生成器维护 customDNS.mapping 标记块
Kubernetes Pod split horizon CoreDNS 由生成器维护 .server 标记块

生成配置

安装了 uv 后,在仓库根目录运行:

uv run infrastructure/dns/generate.py
uv run infrastructure/dns/generate.py --check

脚本使用内嵌锁定版本的 PyYAML 和 Jinja2,从 records.yml 渲染三个目标:

  • apps/blocky/config.yml 中带 marker 的 LAN split-horizon mapping
  • platform/k3s/coredns-custom.yaml 中带 marker 的 Pod split-horizon server blocks
  • infrastructure/cloudflared/terraform/dns.generated.tf 中已经完成 Terraform 接管的公网记录。

生成文件需要提交进 Git,以便 PR 直接审阅最终配置。CI 执行 --check,任何手工修改生成块、 漏跑生成器或非确定性输出都会失败。Jinja 使用 [[ ... ]] 作为变量定界符,避免与 CoreDNS 模板表达式 {{ .Name }} 冲突。

backendsterraform.managed 是分阶段接管开关,而不是第二份记录数据:只有已经完成 零变更接管的后端才会生成。把记录加入新的后端前,应先完成相应的 live/state 对账。

安全边界

  • Samba module 只管理 homelab_dns.samba.records 明确列出的 RRset,不遍历或清理 zone。
  • _ldap_kerberos、域控制器 locator 等由 Samba 自动维护的记录不进入 inventory。
  • 一个受管 RRset 默认使用 exact: true:同名同类型的额外值会被删除,但其他名称和类型 不受影响。
  • DHCP 切换不属于本阶段。Blocky 仍未成为 LAN 客户端的正式 resolver。

分阶段接管

  1. 用 Samba module 接管现有静态 A RRset,首次 check mode 应为零变更。
  2. 将 Cloudflare 已有 tunnel DNS 记录逐条导入 Terraform state,再启用 terraform.managed
  3. Blocky 与 CoreDNS 已从 split_horizon.records 生成;通过 backends 分阶段扩展。
  4. 验证公网、LAN、Pod、AD 四个视图后,再单独修改 DHCP。

当前 inventory 明确保留一个既有差异:obj.ddupan.topbackends 只有 Blocky,CoreDNS 尚无对应覆盖。本阶段不改变线上语义;后续验证 Pod 侧入口后再加入 coredns

CoreDNS split-horizon 的原因是避免集群内请求经 Cloudflare 公网绕回同一个集群。尤其 Gitea 启动时会访问 Authelia discovery URL,公网路径故障曾令其启动失败;生成块仍返回相同 LAN A 记录,并对 AAAA 返回 NOERROR/no-data。