「EXTERNAL-DNS」- 为 Ingress / Service 创建 DNS 记录

认识

官网:https://kubernetes-sigs.github.io/external-dns/latest/
文档:https://kubernetes-sigs.github.io/external-dns/v0.14.0/
仓库:https://github.com/kubernetes-sigs/external-dns

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.

Inspired by Kubernetes DNS, Kubernetes’ cluster-internal DNS server, ExternalDNS makes Kubernetes resources discoverable via public DNS servers.

In a broader sense, ExternalDNS allows you to control DNS records dynamically via Kubernetes resources in a DNS provider-agnostic way.

组成

程序命令

针对命令参数及其含义,我们暂未(12/16/2024)找到相关说明文档。我们通过 –help 查看:

  • docker run registry.k8s.io/external-dns/external-dns:v0.15.0 –help

https://kubernetes-sigs.github.io/external-dns/latest/docs/flags/ # 2025-10-10

DNS Providers

in-tree

Webhook System | Webhook provider

No new provider will be added to ExternalDNS in-tree.

ExternalDNS has introduced a webhook system, which can be used to add a new provider. See PR #3063 for all the discussions about it.

性质

Like KubeDNS, it retrieves a list of resources (Services, Ingresses, etc.) from the Kubernetes API to determine a desired list of DNS records.

Unlike KubeDNS, however, it’s not a DNS server itself, but merely configures other DNS providers accordingly—e.g. AWS Route 53 or Google Cloud DNS.

ExternalDNS allows you to keep selected zones (via –domain-filter) synchronized with Ingresses and Services of type=LoadBalancer and nodes in various DNS providers: Google Cloud DNS, AWS Route 53, AWS Cloud Map, AzureDNS, BlueCat, Civo, CloudFlare, RcodeZero, DigitalOcean, DNSimple, Dyn, OpenStack Designate, PowerDNS, CoreDNS, Exoscale, Oracle Cloud Infrastructure DNS, Linode DNS, RFC2136, NS1, TransIP, VinylDNS, Vultr, OVH, Scaleway, Akamai Edge DNS, GoDaddy, Gandi, ANS Group SafeDNS, IBM Cloud DNS, TencentCloud PrivateDNS, TencentCloud DNSPod, Plural, Pi-hole

ExternalDNS is, by default, aware of the records it is managing, therefore it can safely manage non-empty hosted zones. We strongly encourage you to set –txt-owner-id to a unique value that doesn’t change for the lifetime of your cluster. You might also want to run ExternalDNS in a dry run mode (–dry-run flag) to see the changes to be submitted to your DNS Provider API.

场景 | 绑定 Service[type=LoadBalancer] 到域名

kubernetes-sigs/external-dns

通过为 Service[type=LoadBalancer] 添加注解,ExternalDNS 将自动在云商中添加 DNS 解析;

# kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.example.org"
# kubectl annotate service nginx "external-dns.alpha.kubernetes.io/ttl=10"

场景 | 同个域名,被多个集群管理

–txt-owner-id “my-cluster-id”

通过该参数,其创建的 DNS 解析记录中将包含该 id 值,该值用于与其他 External DNS 实例创建的 DNS Record 进行区分。

场景 | 解析到特定地址

external-dns/docs/annotations/annotations.md at master · kubernetes-sigs/external-dns

external-dns.alpha.kubernetes.io/target: cdn-cname.exmaple.com

构建

安装 | 升级 | Installing | Upgrading

版本选择

Kubernetes version compatibility
https://github.com/kubernetes-sigs/external-dns?tab=readme-ov-file#kubernetes-version-compatibility

Kubernetes >= 1.22 → External DNS >= 0.10.0

部署方式

参考 kubernetes-sigs/external-dns/docs/tutorials/ 页面,该目录提供针对多个 DNS Provider 进行配置的案例。

容器镜像

  • registry.k8s.io/external-dns/external-dns:v0.17.0
  • ccr.ccs.tencentyun.com/d3rm-3rd/registry.k8s.io_external-dns_external-dns:v0.17.0

  • [I] SRC: registry.k8s.io/external-dns/external-dns:v0.19.0
  • [I] DST: ccr.ccs.tencentyun.com/d3rm-3rd/registry.k8s.io_external-dns_external-dns:v0.19.0

Working with DNSPod

Releases v0.18.0 https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.18.0

This release remove in-tree support for ibmcloud, tencentcloud & ultradns. Users needing those providers can use a previous version of external-dns or create a webhook-based provider. —— 针对该问题,现在 2025-10-10 我们最高使用 v0.17.0 版本。

文档:https://kubernetes-sigs.github.io/external-dns/v0.17.0/

腾讯云 / 在 TKE 中,配置 ExternalDNS | https://cloud.tencent.com/document/product/457/72679

我们没有找到支持 DNSPod 的 Helm Chart 资源,所以我们通过 Manifest 部署。

kubectl create namespace external-dns
kubectl config set-context --current --namespace external-dns

kubectl apply -f dnspod.yaml

Q:… failed to sync v1.Ingress: context deadline execeded …
A:通过 YAML 部署,需要注意 ClusterRoleBinding.subjects[].namespace 配置,错误配置将导致其无法访问 api-server 而退出。
R:failed to sync v1.Ingress: context deadline exceeded · Issue #2407 · kubernetes-sigs/external-dns

Working with Route53

https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md

Working with Alidns

# 2025-10-10 如果使用 Helm Chart 部署,则还要了解相关字段及含义。所以,我们通过 Manifest 部署,足以解决问题。

–alibaba-cloud-config-file=”/etc/kubernetes/alibaba-cloud.json”

{
  "accessKeyId": "YOUR_ACCESS_KEY_ID",
  "accessKeySecret": "YOUR_ACCESS_KEY_SECRET"
}

应用

在 Kubernetes 中,自动完成 DNS 解析。某些服务需要使用的域名较多,手动解析是个繁琐的事情。通过 External DNS 组件,仅需在 YAML 中配置相关域名即可,无需再手动进行 DNS 解析。

改进

场景 | 最后的 CNAME 记录无法被删除

external-dns 会创建 3 条记录,当修改 Ingress Class 之后,最终的 CNAME 不会被删除。

cannot delete cname records in route53 with txt registry and txt-suffix · Issue #2474 · kubernetes-sigs/external-dns