在Kubernetes集群中部署完应用后,下一步往往是让外部用户通过域名访问服务。如果你的域名托管在腾讯云DNSPod上,手动去控制台添加解析记录当然可行,但每次服务变更都要人工操作,既繁琐又容易出错。更优雅的做法是让集群自动感知Ingress或Service的变化,自动在DNSPod上创建和更新解析记录,这正是external-dns方案的用武之地。

先搞清楚:CoreDNS和DNSPod各自负责什么
很多初学者会把集群内的CoreDNS和外部域名服务商搞混。CoreDNS是Kubernetes内置的DNS服务器,主要职责是处理集群内部的服务发现,比如把my-svc.default.svc.cluster.local解析成ClusterIP,这个过程和DNSPod没有任何关系。
DNSPod则是腾讯云提供的公网域名解析服务,负责的是ippipp.com这类真实域名在全球互联网上的解析。当Pod里的应用访问一个外部域名时,请求会先到达CoreDNS,CoreDNS发现自己无法解析(因为这不是集群内部域名),就会向上游DNS服务器转发查询,最终由公网DNS体系完成解析。
所以配置DNSPod的本质有两层含义:一是让external-dns自动管理DNSPod上的解析记录,实现服务与域名的自动绑定;二是如果需要,调整CoreDNS的转发策略让特定域名的查询走指定路径。大多数场景下,我们需要的是前者。
准备工作:获取DNSPod API密钥
external-dns操作DNSPod依赖API Token,需要登录腾讯云控制台,进入云API密钥管理页面创建一个密钥对,包含SecretId和SecretKey两部分。这个密钥的权限建议只授予DNSPod相关的操作权限,避免使用主账号的全局密钥,降低安全风险。
拿到密钥后,第一步是把它存进Kubernetes的Secret里,切忌直接写在部署清单中:
apiVersion: v1 kind: Secret metadata: name: dnspod-secret namespace: external-dns type: Opaque stringData: SecretId: "你的SecretId" SecretKey: "你的SecretKey"
注意这里用的是stringData而不是data,前者可以直接写明文,Kubernetes会自动做base64编码,省去手动编码的麻烦。Secret创建完成后,记得检查命名空间是否与后续部署external-dns的命名空间一致。
部署external-dns对接DNSPod实战
external-dns的社区版本从5.x开始官方支持腾讯云DNSPod provider,部署的核心是给容器配置正确的启动参数。先创建RBAC授权,让external-dns有权监听Service和Ingress资源:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","pods","nodes"] verbs: ["get","watch","list"] - apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"]
接着部署external-dns本体,关键参数是--provider=tencentcloud,同时通过环境变量注入密钥信息:
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: external-dns
spec:
replicas: 1
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.14.0
args:
- --source=service
- --source=ingress
- --provider=tencentcloud
- --domain-filter=ippipp.com
- --policy=sync
env:
- name: TENCENTCLOUD_SECRET_ID
valueFrom:
secretKeyRef:
name: dnspod-secret
key: SecretId
- name: TENCENTCLOUD_SECRET_KEY
valueFrom:
secretKeyRef:
name: dnspod-secret
key: SecretKey这里有几个参数值得说明。--domain-filter限定了只管理ippipp.com及其子域名,防止误操作其他域名;--policy有两个取值,sync会删除DNSPod上不属于集群管理的记录,upsert-only则只增不删,生产环境如果域名下还有手动维护的记录,建议先用upsert-only观察一段时间。
部署完成后验证很简单,创建一个带host的Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
external-dns.alpha.kubernetes.io/target: 1.2.3.4
spec:
rules:
- host: app.ippipp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80几十秒后登录DNSPod控制台,如果看到app.ippipp.com的A记录已经自动生成,说明整条链路打通了。也可以直接查看external-dns的Pod日志,里面会打印每一条记录的变更动作。
常见疑问与踩坑排查
记录一直没创建怎么办?按顺序检查三点:Pod日志中有没有报错信息,最常见的是密钥无效或权限不足;DNSPod侧域名状态是否正常,未实名认证的域名无法修改解析;--domain-filter的值是否和Ingress里的host匹配,大小写和末尾的点都可能导致过滤失效。
会不会和手动记录冲突?会。external-dns在sync模式下会给托管的记录打上identifier标签,删除时只删自己创建的记录,但如果手动创建的记录和自动记录完全同名同类型,就可能出现互相覆盖。稳妥的做法是给集群使用的子域名划一个独立前缀,比如k8s.ippipp.com,人工记录和自动记录互不干扰。
更新有延迟正常吗?external-dns默认每隔一段时间轮询一次Kubernetes资源,变更后通常在一分钟内生效。如果需要更快响应,可以加上--events参数让它基于事件触发,几乎实时同步。另外公网解析生效还受TTL影响,DNSPod默认TTL为600秒,急用的话可以调低到60秒。
多个集群怎么管理同一个域名?给每个集群配置不同的--txt-owner-id,比如cluster-a和cluster-b,external-dns依靠TXT记录区分归属,各自只操作自己的记录,避免集群A把集群B的解析删掉。
整体来看,Kubernetes对接DNSPod的配置并不复杂,核心就是密钥管理、RBAC授权和external-dns参数调优这三块。把--policy的取舍和域名过滤范围想清楚再上线,基本就能避开绝大部分弯路。
kubernetes配置dnspodexternal-dns域名解析修改时间:2026-09-05 08:58:31