External DNS 自动域名配置教程
在 Kubernetes 中部署 Web 应用时,通常需要手动在 DNS 服务商处创建域名记录指向集群的入口 IP。External DNS 是一个 Kubernetes 插件,它可以自动根据集群中 Service 和 Ingress 资源的注解来创建和更新 DNS 记录,实现域名管理的完全自动化。
一、External DNS 工作原理
- 监听 Kubernetes 中 Service、Ingress 等资源的变化。
- 从资源的注解中提取域名和 IP 信息。
- 通过 DNS 提供商的 API 创建或更新 DNS 记录。
- 定期同步确保 DNS 记录与集群状态一致。
支持的 DNS 提供商包括:AWS Route53、Google Cloud DNS、Cloudflare、DigitalOcean、Azure DNS 等几十种。
二、安装 External DNS
2.1 使用 Helm 安装
helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update
helm install external-dns external-dns/external-dns \
--namespace external-dns \
--create-namespace \
--set provider=cloudflare \
--set cloudflare.apiToken=YOUR_CLOUDFLARE_API_TOKEN \
--set cloudflare.proxied=false \
--set policy=sync \
--set txtOwnerId=my-cluster
2.2 手动部署(Cloudflare 示例)
# 创建 API Token Secret
kubectl create namespace external-dns
kubectl create secret generic cloudflare-api-token \
-n external-dns \
--from-literal=cloudflare_api_token=YOUR_API_TOKEN
# 部署 External DNS
cat > external-dns.yaml <<'EOF'
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:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.0
args:
- --source=service
- --source=ingress
- --provider=cloudflare
- --cloudflare-proxied
- --policy=sync
- --txt-owner-id=my-cluster
- --domain-filter=example.com
- --log-level=info
env:
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: cloudflare-api-token
key: cloudflare_api_token
EOF
kubectl apply -f external-dns.yaml
三、配置 Service 自动创建 DNS
cat > nginx-service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: web.example.com
external-dns.alpha.kubernetes.io/ttl: "120"
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: nginx
EOF
kubectl apply -f nginx-service.yaml
# External DNS 会自动创建 A 记录:web.example.com -> LoadBalancer IP
四、配置 Ingress 自动创建 DNS
cat > ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
external-dns.alpha.kubernetes.io/hostname: app.example.com
external-dns.alpha.kubernetes.io/ttl: "60"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
EOF
kubectl apply -f ingress.yaml
五、常用注解
external-dns.alpha.kubernetes.io/hostname:指定要创建的域名。external-dns.alpha.kubernetes.io/ttl:DNS 记录的 TTL 值(秒)。external-dns.alpha.kubernetes.io/target:指定目标 IP 或 CNAME。external-dns.alpha.kubernetes.io/cloudflare-proxied:是否启用 Cloudflare CDN 代理。
六、同步策略
# --policy 参数控制同步行为:
# sync:完全同步,会创建和删除 DNS 记录
# upsert-only:只创建和更新,不删除
# create-only:只创建新记录
# --domain-filter 限制管理的域名范围
# --exclude-domains 排除特定域名
# --namespace 限制监听的命名空间
七、AWS Route53 配置示例
helm install external-dns external-dns/external-dns \
--namespace external-dns \
--create-namespace \
--set provider=aws \
--set aws.region=us-east-1 \
--set policy=sync \
--set domainFilters[0]=example.com \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789:role/external-dns
八、常见问题
DNS 记录未创建
# 查看 External DNS 日志
kubectl logs -n external-dns -l app=external-dns
# 检查权限配置
kubectl get secret -n external-dns
# 确认 domain-filter 是否正确
总结
External DNS 实现了 Kubernetes 环境下 DNS 管理的完全自动化,消除了手动配置 DNS 记录的繁琐工作。配合 MetalLB 负载均衡器 使用,可以在裸金属(如搬瓦工 VPS)K8S 集群上实现完整的服务暴露方案。选购搬瓦工 VPS 请访问 bwh81.net,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣。