ExternalDNS与Azure DNS集成:跨云环境DNS管理实践
你是否还在为跨云环境中的DNS配置而烦恼?手动更新DNS记录不仅耗时易错,还可能导致服务中断。本文将详细介绍如何使用ExternalDNS自动化管理Azure DNS记录,从环境准备到实际部署,全程实操指南帮你解决云环境DNS管理难题。读完本文,你将掌握ExternalDNS与Azure DNS的集成方法、权限配置技巧以及常见问题解决方案,让跨云DNS管理变得简单高效。
什么是ExternalDNS?
ExternalDNS是一个开源项目,它能够自动将Kubernetes的Ingress和Service资源同步到外部DNS服务提供商,如Azure DNS、AWS Route53等。通过ExternalDNS,用户无需手动管理DNS记录,系统会根据Kubernetes资源的变化自动更新DNS配置,大大减少了人工操作和出错概率。
ExternalDNS的核心功能包括:
- 监控Kubernetes中的Service和Ingress资源变化
- 根据资源注解自动生成DNS记录
- 支持多种DNS服务提供商
- 提供记录所有权验证机制
项目官方文档:README.md
Azure DNS集成架构
ExternalDNS与Azure DNS的集成架构主要包含以下几个组件:
- Kubernetes集群:运行ExternalDNS和业务应用
- ExternalDNS组件:负责监控Kubernetes资源并同步到Azure DNS
- Azure DNS服务:提供DNS记录管理功能
- Azure资源管理器:提供API接口供ExternalDNS调用
环境准备
安装必要工具
在开始之前,需要确保已安装以下工具:
- Azure CLI 2.0+:用于管理Azure资源
- kubectl:用于管理Kubernetes集群
- Helm(可选):用于部署ExternalDNS
创建Azure资源组和DNS区域
首先,使用Azure CLI创建一个资源组和DNS区域:
# 创建资源组
az group create --name "MyDnsResourceGroup" --location "eastus"
# 创建DNS区域
az network dns zone create --resource-group "MyDnsResourceGroup" --name "example.com"
如果需要使用私有DNS区域,可以参考:Azure Private DNS教程
配置Azure认证
ExternalDNS需要具备管理Azure DNS的权限,有四种认证方式可供选择:服务主体、AKS Kubelet身份、AAD Pod身份和工作负载身份。
服务主体认证(推荐)
创建服务主体并分配权限:
# 创建服务主体
EXTERNALDNS_NEW_SP_NAME="ExternalDnsServicePrincipal"
AZURE_DNS_ZONE_RESOURCE_GROUP="MyDnsResourceGroup"
AZURE_DNS_ZONE="example.com"
DNS_SP=$(az ad sp create-for-rbac --name $EXTERNALDNS_NEW_SP_NAME)
EXTERNALDNS_SP_APP_ID=$(echo $DNS_SP | jq -r '.appId')
EXTERNALDNS_SP_PASSWORD=$(echo $DNS_SP | jq -r '.password')
# 获取DNS区域ID
DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE \
--resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv)
# 分配权限
az role assignment create --role "Reader" --assignee $EXTERNALDNS_SP_APP_ID --scope $DNS_ID
az role assignment create --role "DNS Zone Contributor" --assignee $EXTERNALDNS_SP_APP_ID --scope $DNS_ID
创建Azure配置文件:
cat <<-EOF > /local/path/to/azure.json
{
"tenantId": "$(az account show --query tenantId -o tsv)",
"subscriptionId": "$(az account show --query id -o tsv)",
"resourceGroup": "$AZURE_DNS_ZONE_RESOURCE_GROUP",
"aadClientId": "$EXTERNALDNS_SP_APP_ID",
"aadClientSecret": "$EXTERNALDNS_SP_PASSWORD"
}
EOF
创建Kubernetes密钥:
kubectl create secret generic azure-config-file --namespace "default" --from-file /local/path/to/azure.json
部署ExternalDNS
使用部署清单部署
创建一个部署清单文件external-dns.yaml:
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", "nodes"]
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"]
---
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.19.0
args:
- --source=service
- --source=ingress
- --domain-filter=example.com
- --provider=azure
- --azure-resource-group=MyDnsResourceGroup
- --azure-zones-cache-duration=30m
volumeMounts:
- name: azure-config-file
mountPath: /etc/kubernetes
readOnly: true
volumes:
- name: azure-config-file
secret:
secretName: azure-config-file
应用部署清单:
kubectl apply -f external-dns.yaml
使用Helm部署(可选)
如果使用Helm,可以添加外部DNS的Helm仓库并安装:
helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update
helm install external-dns external-dns/external-dns \
--set provider=azure \
--set azure.resourceGroup=MyDnsResourceGroup \
--set azure.zoneType=public \
--set domainFilters[0]=example.com \
--set sources[0]=service \
--set sources[1]=ingress \
--set extraVolumes[0].name=azure-config-file \
--set extraVolumes[0].secret.secretName=azure-config-file \
--set extraVolumeMounts[0].name=azure-config-file \
--set extraVolumeMounts[0].mountPath=/etc/kubernetes \
--set extraVolumeMounts[0].readOnly=true
使用示例
创建测试服务和Ingress
创建一个简单的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
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
创建Ingress资源并添加注解:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
external-dns.alpha.kubernetes.io/hostname: nginx.example.com
spec:
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
验证DNS记录
等待几分钟后,使用Azure CLI验证DNS记录是否已创建:
az network dns record-set a list --resource-group MyDnsResourceGroup --zone-name example.com
高级配置
私有DNS集成
如果需要使用Azure Private DNS,可以参考详细配置:Azure Private DNS集成
主要步骤包括:
- 创建私有DNS区域
- 配置VNet链接
- 使用
azure-private-dns提供程序部署ExternalDNS
限流和缓存配置
ExternalDNS提供了限流和缓存机制,可以减少对Azure API的请求:
args:
- --azure-zones-cache-duration=30m
- --azure-maxretries-count=5
环境变量配置:
env:
- name: AZURE_SDK_MAX_RETRIES
value: "5"
常见问题解决
权限问题
如果遇到权限错误,检查服务主体是否具有正确的角色分配:
az role assignment list --assignee $EXTERNALDNS_SP_APP_ID --output json
记录未同步
检查ExternalDNS日志:
kubectl logs -f deployment/external-dns
确认Kubernetes资源是否正确配置了注解,并且域名与domain-filter匹配。
私有DNS解析问题
如果使用私有DNS,确保VNet链接已正确配置:
az network private-dns link vnet show --resource-group MyDnsResourceGroup --name mylink --zone-name example.com
总结与展望
通过本文的步骤,你已经成功实现了ExternalDNS与Azure DNS的集成,实现了Kubernetes资源到DNS记录的自动同步。这种方式不仅减少了人工操作,还提高了系统的可靠性和一致性。
未来,你可以进一步探索:
- 多区域DNS部署
- 结合Azure Traffic Manager实现负载均衡
- 使用GitOps方式管理DNS配置
ExternalDNS支持多种DNS提供商,完整列表请参考:支持的DNS提供商
希望本文对你的跨云DNS管理有所帮助!如有任何问题,欢迎参考项目文档或提交issue。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




