ExternalDNS与Azure DNS集成:跨云环境DNS管理实践

ExternalDNS与Azure DNS集成:跨云环境DNS管理实践

【免费下载链接】external-dns Configure external DNS servers (AWS Route53, Google CloudDNS and others) for Kubernetes Ingresses and Services 【免费下载链接】external-dns 项目地址: https://gitcode.com/gh_mirrors/ex/external-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的集成架构主要包含以下几个组件:

  1. Kubernetes集群:运行ExternalDNS和业务应用
  2. ExternalDNS组件:负责监控Kubernetes资源并同步到Azure DNS
  3. Azure DNS服务:提供DNS记录管理功能
  4. Azure资源管理器:提供API接口供ExternalDNS调用

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集成

主要步骤包括:

  1. 创建私有DNS区域
  2. 配置VNet链接
  3. 使用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。

【免费下载链接】external-dns Configure external DNS servers (AWS Route53, Google CloudDNS and others) for Kubernetes Ingresses and Services 【免费下载链接】external-dns 项目地址: https://gitcode.com/gh_mirrors/ex/external-dns

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值