ExternalDNS自动化DNS管理实践:实现Kubernetes服务自动注册
一、ExternalDNS概述
ExternalDNS是一个Kubernetes控制器,能够自动同步Kubernetes资源(如Service和Ingress)到外部DNS服务商。它消除了手动管理DNS记录的繁琐工作,实现了DNS记录的自动化管理。
ExternalDNS支持的DNS服务商:
- AWS Route 53
- Google Cloud DNS
- Azure DNS
- Cloudflare
- DigitalOcean
- CoreDNS
- Infoblox
- NS1
二、ExternalDNS安装与配置
2.1 使用Helm安装
# 添加ExternalDNS Helm仓库 helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/ # 创建命名空间 kubectl create namespace external-dns # 安装ExternalDNS(以AWS为例) helm install external-dns external-dns/external-dns \ --namespace external-dns \ --version 1.13.0 \ --set provider=aws \ --set aws.region=us-west-2 \ --set domainFilters="{example.com}"2.2 配置RBAC权限
apiVersion: v1 kind: ServiceAccount metadata: name: external-dns namespace: external-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services", "endpoints", "pods"] 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: external-dns2.3 验证安装
# 检查ExternalDNS Pod状态 kubectl get pods -n external-dns # 查看日志 kubectl logs -n external-dns deployment/external-dns三、配置DNS Provider
3.1 AWS Route 53配置
apiVersion: v1 kind: Secret metadata: name: aws-credentials namespace: external-dns data: credentials: | [default] aws_access_key_id = YOUR_ACCESS_KEY aws_secret_access_key = YOUR_SECRET_KEYhelm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=aws \ --set aws.region=us-west-2 \ --set aws.secretName=aws-credentials \ --set domainFilters="{example.com}"3.2 Cloudflare配置
apiVersion: v1 kind: Secret metadata: name: cloudflare-api-token namespace: external-dns data: api-token: YOUR_CLOUDFLARE_API_TOKENhelm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=cloudflare \ --set cloudflare.secretName=cloudflare-api-token \ --set domainFilters="{example.com}"3.3 Google Cloud DNS配置
# 创建服务账号密钥文件 gcloud iam service-accounts create external-dns gcloud projects add-iam-policy-binding my-project \ --member "serviceAccount:external-dns@my-project.iam.gserviceaccount.com" \ --role "roles/dns.admin" gcloud iam service-accounts keys create key.json \ --iam-account external-dns@my-project.iam.gserviceaccount.com # 创建Secret kubectl create secret generic gcp-key \ --namespace external-dns \ --from-file=key.json=./key.json # 安装ExternalDNS helm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=google \ --set google.project=my-project \ --set google.secretName=gcp-key \ --set domainFilters="{example.com}"四、使用ExternalDNS
4.1 Service配置
apiVersion: v1 kind: Service metadata: name: my-service annotations: external-dns.alpha.kubernetes.io/hostname: my-service.example.com. external-dns.alpha.kubernetes.io/ttl: "60" spec: type: LoadBalancer selector: app: my-app ports: - port: 80 targetPort: 80804.2 Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: external-dns.alpha.kubernetes.io/hostname: app.example.com. external-dns.alpha.kubernetes.io/target: "my-loadbalancer-123456.us-west-2.elb.amazonaws.com" spec: rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 804.3 多域名配置
apiVersion: v1 kind: Service metadata: name: multi-domain-service annotations: external-dns.alpha.kubernetes.io/hostname: | service1.example.com. service2.example.com. service3.example.com. spec: type: LoadBalancer selector: app: my-app ports: - port: 80五、高级配置
5.1 同步策略
helm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=aws \ --set policy=upsert-only \ --set registry=txt \ --set txtOwnerId=my-cluster-id支持的策略:
sync:完全同步(删除不存在的记录)upsert-only:只添加/更新记录,不删除create-only:只创建新记录
5.2 过滤配置
helm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=aws \ --set domainFilters="{example.com,api.example.com}" \ --set excludeDomains="{internal.example.com}" \ --set annotationFilter="external-dns\.alpha\.kubernetes\.io/enabled=true"5.3 自定义TTL
apiVersion: v1 kind: Service metadata: name: my-service annotations: external-dns.alpha.kubernetes.io/hostname: my-service.example.com. external-dns.alpha.kubernetes.io/ttl: "300" spec: type: LoadBalancer selector: app: my-app六、监控与日志
6.1 Prometheus指标
apiVersion: v1 kind: Service metadata: name: external-dns-metrics namespace: external-dns spec: selector: app.kubernetes.io/name: external-dns ports: - name: metrics port: 7979 targetPort: metrics6.2 配置ServiceMonitor
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: external-dns-monitor namespace: monitoring spec: selector: matchLabels: app.kubernetes.io/name: external-dns endpoints: - port: metrics interval: 30s七、最佳实践
7.1 权限最小化
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: external-dns-limited namespace: external-dns rules: - apiGroups: [""] resources: ["services", "endpoints"] verbs: ["get", "watch", "list"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["get", "watch", "list"]7.2 多集群场景
helm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=aws \ --set txtOwnerId=cluster-a \ --set domainFilters="{cluster-a.example.com}"7.3 测试模式
helm install external-dns external-dns/external-dns \ --namespace external-dns \ --set provider=aws \ --set dryRun=true八、故障排除
8.1 常见问题
# 查看详细日志 kubectl logs -n external-dns deployment/external-dns -f # 检查配置错误 kubectl describe deployment external-dns -n external-dns # 验证DNS记录 dig my-service.example.com8.2 调试技巧
# 启用详细日志 helm upgrade external-dns external-dns/external-dns \ --namespace external-dns \ --set logLevel=debug # 手动触发同步 kubectl delete pod -n external-dns -l app.kubernetes.io/name=external-dns九、总结
ExternalDNS为Kubernetes提供了强大的DNS自动化管理能力,消除了手动管理DNS记录的繁琐工作。通过本文的实践指南,您可以快速部署和配置ExternalDNS,实现服务的自动DNS注册。建议根据实际需求选择合适的DNS服务商和配置策略。
参考资料:
- ExternalDNS官方文档
- ExternalDNS GitHub
- Kubernetes Service文档