当前位置: 首页 > news >正文

ExternalDNS 配置实践:自动化 DNS 记录管理

ExternalDNS 配置实践:自动化 DNS 记录管理

引言

在 Kubernetes 环境中,管理 DNS 记录是一项繁琐的任务。ExternalDNS 可以自动将 Kubernetes Service 和 Ingress 资源同步到外部 DNS 提供商,实现 DNS 记录的自动化管理。本文将深入探讨 ExternalDNS 的安装、配置和最佳实践。

ExternalDNS 基础概念

什么是 ExternalDNS

ExternalDNS 是一个 Kubernetes 控制器,它自动管理 DNS 记录:

  • 自动同步:将 Service/Ingress 同步到 DNS 提供商
  • 多提供商支持:支持 AWS Route 53、Google Cloud DNS、Azure DNS 等
  • 声明式管理:使用 Kubernetes 资源定义 DNS 配置
  • TTL 管理:支持自定义 DNS 记录 TTL

ExternalDNS 工作流程

┌─────────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Services / Ingresses │ │ │ └──────────────────────────┬─────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ ExternalDNS Controller │ │ │ │ - 监听 Kubernetes API │ │ │ │ - 解析 Service/Ingress 配置 │ │ │ │ - 同步到 DNS 提供商 │ │ │ └──────────────────────────┬─────────────────────────────┘ │ └─────────────────────────────┼─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ External DNS Provider │ │ ┌──────────────────┐ ┌──────────────────┐ ┌─────────────┐ │ │ │ AWS Route 53 │ │ Google Cloud │ │ Azure DNS │ │ │ └──────────────────┘ │ DNS │ └─────────────┘ │ │ └──────────────────┘ │ └─────────────────────────────────────────────────────────────────┘

ExternalDNS 安装

使用 Helm 安装

# 添加 ExternalDNS Helm 仓库 helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/ helm repo update # 创建命名空间 kubectl create namespace external-dns # 安装 ExternalDNS(以 AWS Route 53 为例) helm install external-dns external-dns/external-dns -n external-dns \ --set provider=aws \ --set aws.region=us-east-1 \ --set domainFilters="{example.com}" \ --set txtOwnerId=my-k8s-cluster

验证安装

# 检查 Pod 状态 kubectl get pods -n external-dns # 查看日志 kubectl logs -n external-dns external-dns-xxx # 检查 Service 状态 kubectl get svc -n external-dns

ExternalDNS 配置

AWS Route 53 配置

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-dns --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: 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.14.0 args: - --source=service - --source=ingress - --provider=aws - --domain-filter=example.com - --txt-owner-id=my-k8s-cluster - --policy=upsert-only

Google Cloud DNS 配置

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns image: registry.k8s.io/external-dns/external-dns:v0.14.0 args: - --source=service - --source=ingress - --provider=google - --domain-filter=example.com - --txt-owner-id=my-k8s-cluster volumes: - name: google-cloud-key secret: secretName: google-cloud-key volumeMounts: - name: google-cloud-key mountPath: /var/secrets/google readOnly: true

Azure DNS 配置

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns image: registry.k8s.io/external-dns/external-dns:v0.14.0 args: - --source=service - --source=ingress - --provider=azure - --domain-filter=example.com - --txt-owner-id=my-k8s-cluster env: - name: AZURE_SUBSCRIPTION_ID valueFrom: secretKeyRef: name: azure-config key: subscription-id - name: AZURE_TENANT_ID valueFrom: secretKeyRef: name: azure-config key: tenant-id - name: AZURE_CLIENT_ID valueFrom: secretKeyRef: name: azure-config key: client-id - name: AZURE_CLIENT_SECRET valueFrom: secretKeyRef: name: azure-config key: client-secret

Service 配置示例

LoadBalancer 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: 8080

Ingress 配置

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: external-dns.alpha.kubernetes.io/hostname: my-app.example.com external-dns.alpha.kubernetes.io/ttl: "300" spec: rules: - host: my-app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80

ExternalDNS 策略配置

Sync Policy

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns args: - --policy=sync - --source=service - --source=ingress - --provider=aws

UPSERT-ONLY Policy

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns args: - --policy=upsert-only - --source=service - --source=ingress - --provider=aws

ExternalDNS 高级配置

多域名支持

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns args: - --domain-filter=example.com - --domain-filter=another-domain.com - --source=service - --source=ingress - --provider=aws

自定义 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: "120" spec: type: LoadBalancer selector: app: my-app

权重路由配置

apiVersion: v1 kind: Service metadata: name: my-service-primary annotations: external-dns.alpha.kubernetes.io/hostname: my-app.example.com external-dns.alpha.kubernetes.io/aws-weight: "100" spec: type: LoadBalancer selector: app: my-app-primary --- apiVersion: v1 kind: Service metadata: name: my-service-secondary annotations: external-dns.alpha.kubernetes.io/hostname: my-app.example.com external-dns.alpha.kubernetes.io/aws-weight: "50" spec: type: LoadBalancer selector: app: my-app-secondary

ExternalDNS 监控与日志

Prometheus 集成

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: external-dns-monitor namespace: external-dns spec: selector: matchLabels: app: external-dns endpoints: - port: http interval: 30s path: /metrics

日志配置

apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: template: spec: containers: - name: external-dns args: - --log-level=debug - --source=service - --source=ingress - --provider=aws

ExternalDNS 最佳实践

权限最小化

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services", "endpoints", "pods"] verbs: ["get", "watch", "list"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["get", "watch", "list"]

安全的 Secret 管理

apiVersion: v1 kind: Secret metadata: name: external-dns-credentials namespace: external-dns type: Opaque data: AWS_ACCESS_KEY_ID: <base64-encoded> AWS_SECRET_ACCESS_KEY: <base64-encoded>

定期验证

# 检查 DNS 记录 nslookup my-service.example.com # 查看 ExternalDNS 状态 kubectl logs -n external-dns external-dns-xxx | grep "record"

常见问题与解决方案

问题 1:DNS 记录未创建

排查步骤

# 检查 ExternalDNS 日志 kubectl logs -n external-dns external-dns-xxx # 检查 Service/Ingress 配置 kubectl describe service my-service # 验证 DNS 提供商配置 kubectl get secret external-dns-credentials -o yaml

解决方案

  • 检查 DNS 提供商权限配置
  • 验证 domain-filter 配置
  • 确认 Service/Ingress 注解配置正确

问题 2:DNS 记录更新延迟

排查步骤

# 查看日志中的同步周期 kubectl logs -n external-dns external-dns-xxx | grep "sync" # 检查 DNS 提供商状态 nslookup my-service.example.com

解决方案

  • 调整同步间隔
  • 检查 DNS 提供商 API 速率限制
  • 验证网络连通性

问题 3:权限不足

排查步骤

# 检查 ServiceAccount kubectl describe serviceaccount external-dns -n external-dns # 检查 IAM 角色(AWS) aws iam get-role-policy --role-name external-dns-role # 查看 ExternalDNS 日志 kubectl logs -n external-dns external-dns-xxx | grep "permission"

解决方案

  • 配置正确的 RBAC 权限
  • 验证云提供商 IAM 权限
  • 确认 Secret 配置正确

总结

ExternalDNS 是 Kubernetes 环境中自动化 DNS 管理的强大工具。通过合理配置,可以实现 Service 和 Ingress 的自动 DNS 记录管理。在实际应用中,需要注意权限配置、策略选择和监控告警,确保 DNS 记录的准确和及时更新。


参考文献

  • ExternalDNS Documentation: https://kubernetes-sigs.github.io/external-dns/
  • ExternalDNS GitHub: https://github.com/kubernetes-sigs/external-dns
  • AWS Route 53 Documentation: https://docs.aws.amazon.com/Route53/
http://www.jsqmd.com/news/853905/

相关文章:

  • 从零到一:基于TrueNAS SCALE构建家庭媒体与数据备份中心
  • 2026 广州天河保洁 海珠开荒保洁前五强 开荒 上门 办公室保洁 - 广州搬家老班长
  • 不止于显示图片:在ROS2 Foxy中,用OpenCV和cv_bridge玩转摄像头图像订阅与简单处理
  • 专业视角 | 宜昌高考志愿填报的「隐形陷阱」:90%家长忽略了这三点 - 新闻快传
  • 从零到一:STM32驱动TM1637四位数码管实战解析
  • 企业如何利用多模型聚合能力构建稳定的AI客服系统
  • Vue3响应式原理:深入理解Proxy和Ref
  • 告别apt!Ubuntu 20.04下从源码编译安装ROS Noetic版UUV Simulator的保姆级教程
  • 5分钟从图片到3D模型:零基础掌握ImageToSTL图片转STL技术
  • 5元级MCU Air601实战评测:硬件兼容、LuatOS开发与ESP12F迁移指南
  • 2026 中国伺服卷板机权威实力排行榜 - 安徽工业
  • 2026 中国拼板焊设备权威实力排行榜 - 安徽工业
  • Kubernetes GitOps 实践:使用 Argo CD 实现持续部署
  • 2026 中国直缝焊机权威实力排行榜 - 安徽工业
  • 2026年餐饮酒店采购供应商推荐榜单:优质酒水供应商综合测评发布 - 资讯速览
  • 4种颠覆性组合:重构Pixelle-Video的模块化潜能
  • SPICE仿真实战:从时序分析基础到建立保持时间验证
  • 一小时快速上手BLDC电机FOC控制:从零到稳定运行的实战指南
  • 【年内检索、连续4届EI检索】第五届电力工程与电气技术学术会议(ICPEET 2026)
  • L298N驱动模块进阶玩法:用Arduino实现直流电机的软启动、缓停与速度曲线控制
  • 2026 中国四辊卷板机权威实力排行榜 - 安徽工业
  • Kafka 旧版本迁移到新集群如何保证数据一致性和完整性?
  • 2026年论文AI率过高怎么破?揭秘高效降AI率的必看神器 - 降AI实验室
  • Linux 进阶运维与 AI 环境实战:进程管理、网络排错与 GPU 监控
  • 别再死记硬背了!用打王者荣耀掉帧的例子,5分钟搞懂视频编码里的I/P/B帧
  • ROS2多机通信避坑指南:为什么你的虚拟机和宿主机能Ping通,但节点就是找不到?
  • 从‘盲人摸象’到‘全局视野’:手把手教你用MATLAB/Simulink仿真PSO-MPPT对抗光伏遮荫(避坑指南)
  • ElementPlus el-tabs组件样式深度定制:从基础美化到高级交互视觉方案
  • 基于Orange Pi 5 Plus与DEEPX栈的边缘AI部署实战指南
  • OpenHuman 深度解析:23k Star 的开源桌面 AI 超级助手完全指南