尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ExternalDNS 对接 Pi-hole 自定义 DNS:从部署到验证的完整指南

ExternalDNS 对接 Pi-hole 自定义 DNS:从部署到验证的完整指南 云原生【免费下载链接】external-dnsConfigure external DNS servers dynamically from Kubernetes resources项目地址https://gitcode.com/gh_mirrors/ex/external-dns点击查看免费下载导读本指南基于 external-dns 官方教程讲解如何将 Kubernetes 中 Service 与 Ingress 的 DNS 需求通过 ExternalDNS 自动同步到 Pi-hole 的 Custom DNS本地 DNS 记录列表。读完本文你将掌握 Pi-hole v6 伪 API 的工作原理、ExternalDNS 的完整部署清单、三个 pihole 专用参数的用法以及用dig验证记录生效的完整实操流程。同时本文会结合本仓库中 Pi-hole 提供商实现 与 API 客户端 的源码深入说明认证、记录读写与变更应用的真实机制。集成原理ExternalDNS 如何写记录到 Pi-holePi-hole 不仅是一个广告拦截 DNS还维护着一张「自定义 DNS」记录表。在解析请求时Pi-hole 会最后检查这张本地列表因此它可以承载任意数量的 A、AAAA 或 CNAME 记录。ExternalDNS 正是利用 Pi-hole 暴露的一套伪 API 来管理这些记录从而把集群内的域名解析任务无缝交给 Pi-hole 完成。整体工作流如下ExternalDNS 从 Kubernetes 的 Service、Ingress 等资源中收集期望的 DNS 记录Endpoints通过Records()读取 Pi-hole 当前已有的 A/AAAA/CNAME 记录在 plan 中对比期望状态与现状生成 Create / Update / Delete 变更通过ApplyChanges()调用 Pi-hole 伪 API最终把记录写入或移出 Custom DNS 列表。版本要求重要本教程要求 Pi-hole 版本为6.0 或更高v5 的旧 API 已不再被支持。若你在 v5 环境上运行将无法正常工作。前置条件一台运行中的 Pi-hole 实例v6.0可访问该实例的 Kubernetes 集群与kubectl了解 Pi-hole 管理后台的访问地址后续会写入--pihole-server参数。部署 ExternalDNS第一步为管理员密码创建 Secret可选如果 Pi-hole 管理后台受密码保护建议先把密码存入 Kubernetes Secret再以envFrom方式注入容器。密码也可以直接用--pihole-password参数传入两者择一即可。kubectl create secret generic pihole-password \ --from-literal EXTERNAL_DNS_PIHOLE_PASSWORDsupersecret把supersecret替换为你的真实密码。注意这里的键名EXTERNAL_DNS_PIHOLE_PASSWORD必须与下文清单中envFrom: secretRef配合的键名一致因为envFrom会把 Secret 中的每个键直接映射为容器环境变量而 ExternalDNS 恰好在启动时读取该环境变量作为密码来源。第二步应用 ExternalDNS 部署清单若你的 Pi-hole 未开启认证、或不想使用 Secret可跳过第一步直接应用以下清单。若你使用非default命名空间请同步修改ClusterRoleBinding中的namespace字段。--- apiVersion: v1 kind: ServiceAccount metadata: name: external-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [] resources: [services,pods] verbs: [get,watch,list] - apiGroups: [discovery.k8s.io] resources: [endpointslices] verbs: [get,watch,list] - apiGroups: [extensions,networking.k8s.io] resources: [ingresses] verbs: [get,watch,list] - apiGroups: [] resources: [nodes] verbs: [list,watch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-dns-viewer roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dns subjects: - kind: ServiceAccount name: external-dns namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: registry.k8s.io/external-dns/external-dns:v0.23.0 # 若未开启认证或未创建 Secret可删除此块 envFrom: - secretRef: # 若 Secret 名称不同请同步修改 name: pihole-password args: - --sourceservice - --sourceingress # Pi-hole 仅支持 A/AAAA/CNAME 记录无法跟踪记录所有权 # 该参数可不设置但不设置时 ExternalDNS 尝试创建 TXT 记录会输出告警日志 - --registrynoop # 重要如果 Pi-hole 中存在手动维护的记录务必设置为 upsert-only 以防被删除 - --policyupsert-only - --providerpihole # 改成你的 Pi-hole Web 服务器实际地址 - --pihole-serverhttp://pihole-web.pihole.svc.cluster.local securityContext: fsGroup: 65534 # 使 ExternalDNS 能读取 Kubernetes token 文件清单要点说明--sourceservice与--sourceingress声明数据来源ExternalDNS 会监听这两类资源--registrynoopPi-hole 只支持 A/AAAA/CNAME无法像 TXT 记录那样标记所有权因此使用 noop 注册表跳过所有权跟踪不设置则会出现 TXT 记录创建告警--policyupsert-only只新增/更新、不删除。如果你在 Pi-hole 里手动维护着记录务必开启它否则 ExternalDNS 发现期望状态中不存在的记录时会把它们删除securityContext.fsGroup: 65534让进程以可以读取挂载的 Kubernetes token 文件的组运行。第三步Pi-hole 相关参数速查参数环境变量说明--pihole-serverEXTERNAL_DNS_PIHOLE_SERVERPi-hole Web 服务器的基地址--providerpihole时必填--pihole-passwordEXTERNAL_DNS_PIHOLE_PASSWORD管理后台密码若已开启认证--pihole-tls-skip-verifyEXTERNAL_DNS_PIHOLE_TLS_SKIP_VERIFY跳过对 Pi-hole Web 服务器 TLS 证书的校验这些参数在 配置类型定义 中以 pflag 方式注册并一一映射到Config结构体的PiholeServer、PiholePassword标记为secure:yes打印日志时会脱敏、PiholeTLSInsecureSkipVerify字段。也可在 flags 文档 中查看到相同定义。当--providerpihole且未设置--pihole-server时客户端初始化会直接返回ErrNoPiholeServer见 client.go。验证 ExternalDNS 是否工作用 Ingress 验证创建一个 Ingress 资源ExternalDNS 会使用其spec.rules[].host字段作为记录名apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: foo spec: ingressClassName: nginx rules: - host: foo.bar.com http: paths: - path: / pathType: Prefix backend: service: name: foo port: number: 80用 Service 验证对于 ServiceExternalDNS 读取注解external-dns.kubernetes.io/hostname的值作为记录名。下面的示例同时包含了 Service 与其后端 Deployment--- apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.kubernetes.io/hostname: nginx.external-dns-test.homelab.com spec: type: LoadBalancer ports: - port: 80 name: http targetPort: 80 selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 name: http查询记录是否创建成功将192.168.100.2替换为你实际使用的 DNS 服务器地址然后用dig验证$ dig short 192.168.100.2 nginx.external-dns-test.homelab.com 192.168.100.129返回 LoadBalancer 的外部 IP 即表示记录已写入 Pi-hole 的 Custom DNS 并生效。源码深读Pi-hole Provider 的内部实现支持的记录类型与读写格式从 client.go 可以看到Provider 只支持三类记录分别对应两个 API 路径A / AAAA/api/config/dns/hosts记录格式为目标IP 域名如192.168.100.129 nginx.external-dns-test.homelab.comCNAME/api/config/dns/cnameRecords记录格式为域名,目标[,TTL]TTL 可选。listRecords()会按 A、AAAA、CNAME 三类分别拉取并聚合成 Endpoint见 pihole.go并对同一域名多目标的情况进行合并。认证机制获取与续期 Session Token当配置了密码时客户端初始化会向POST /api/auth发送{password: ...}从响应的session.sid中取得 Token见 client.go。之后所有请求都会携带X-FTL-SID请求头。更贴心的是 Token 的自动续期当请求返回 401 时客户端会先通过GET /api/auth检查 Token 有效性若已过期则重新获取新 Token 并重发请求最多重试 3 次见 client.go。这个机制在长时间运行、Pi-hole 会话过期时能保证同步任务不中断。变更应用策略先删后建与多目标合并ApplyChanges() 的执行顺序很有讲究先处理纯删除changes.Delete直接调用 DELETE将UpdateNew按「域名 记录类型」合并去重同一域名多个新目标会 append 并去重避免重复写入对UpdateOld若新旧目标集合完全一致排序后比较则跳过删除否则先删旧记录最后统一创建新记录。另外创建时若收到 Item already present 错误会被忽略幂等写入删除不存在的记录时 404 也会被忽略见 client.go因此重复同步是安全的。两条硬性约束不支持通配符记录apply()中若检测到域名包含*会返回软错误UNSUPPORTED: Pihole DNS names cannot return wildcard见 client.goCNAME 只能有一个目标多目标 CNAME 同样返回软错误见 client.go。这两条约束与 Pi-hole Custom DNS 的存储格式直接相关在规划记录时应提前避开。测试佐证仓库为 Pi-hole Provider 提供了完整的单元测试provider 测试 覆盖了创建、删除、更新、多目标合并去重、新旧目标完全一致时跳过删除等场景客户端测试 则用httptest模拟/api/auth认证成功/失败、无服务器配置时报ErrNoPiholeServer等分支。你可以直接运行go test ./provider/pihole/...复现这些行为。此外Provider 已通过 provider 工厂 注册为externaldns.ProviderPihole即--providerpihole实际调用的就是pihole.New。常见问题与最佳实践为什么建议--registrynoopPi-hole 无法存储 TXT 记录所有权追踪无从谈起。不设置时 ExternalDNS 仍会尝试创建 TXT 记录并输出告警日志设置后可保持日志干净。手动维护的记录会丢吗会。只要记录不在 Kubernetes 期望状态中ExternalDNS 就可能删除它。务必使用--policyupsert-only保护手动记录。HTTPS 证书不可信怎么办自签名证书场景下可开启--pihole-tls-skip-verify注意这会降低传输安全性仅建议在可信内网使用。如何排查同步失败关注 ExternalDNS 容器日志中的Pihole token has expired, fetching a new one与received ... status code from request两类日志前者是正常的 Token 续期后者通常对应认证失败或 API 路径错误。更多教程与资料可参考 Pi-hole 教程原文 以及 Provider 列表文档。赞分享云原生【免费下载链接】external-dnsConfigure external DNS servers dynamically from Kubernetes resources项目地址https://gitcode.com/gh_mirrors/ex/external-dns点击查看免费下载相关推荐如何快速实现iOS滑动单元格SwipeCellKit终极完整指南如何快速实现iOS滑动单元格SwipeCellKit终极完整指南 你是否在为iOS应用的列表交互体验而烦恼想要实现像原生邮件应用那样流畅的滑动操作却苦于复云原生ExternalDNS 接入 GoDaddy DNS 完整指南API Key 配置、Helm/Manifest 部署与记录同步验证ExternalDNS 接入 GoDaddy DNS 完整指南API Key 配置、Helm/Manifest 部署与记录同步验证 本教程基于 Kuberne云原生KubeEdge终极指南5分钟掌握云原生边缘计算核心架构KubeEdge终极指南5分钟掌握云原生边缘计算核心架构 KubeEdge作为CNCF旗下的Kubernetes原生边缘计算框架彻底改变了传统边缘设备的管理云原生边缘计算物联网容器编排边缘网关上一篇regl高级特性探索多重渲染目标和实例化渲染下一篇Thanos协议缓冲数据序列化方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表