拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ExternalDNS 的 Ambassador / Emissary-ingress Host 源(ambassador-host)实战指南

云原生【免费下载链接】external-dnsConfigure external DNS servers dynamically from Kubernetes resources项目地址https://gitcode.com/gh_mirrors/ex/external-dns点击查看免费下载本指南完整讲解 ExternalDNS 如何通过ambassador-host源读取 Emissary-ingress原 Ambassador的Host.getambassador.io资源并为其声明的域名自动生成 DNS 记录。文章从工作原理、annotation 约定、RBAC 权限到 kind 本地端到端演练和真实云环境接入逐一给出可复制的配置与命令并深入对应源码与测试用例帮助读者理解Host 如何映射到 DNS 记录的底层机制快速落地 Ambassador/Emissary-ingress 场景的动态 DNS 管理。概述为什么需要 ambassador-host 源ExternalDNS 支持多种源source来发现 Kubernetes 中的 DNS 记录每个源监听特定类型的资源从中提取域名与目标地址完整源列表。ambassador-host源属于 Ingress Controllers 类别专门监听Host.getambassador.io资源——即 Emissary-ingress前身 Ambassador用于声明域名与 TLS 配置的 CRD。在 Emissary-ingress 的架构中Host资源描述了一个站点的主机名spec.hostname而真正的流量入口是集群内的LoadBalancer类型 Service。ambassador-host源把这两者关联起来读取每个Host的spec.hostname作为 DNS 名称把对应的 Emissary-ingressLoadBalancerService 的外部地址IP 或主机名作为记录目标从而让 DNS 记录始终跟随 Service 地址变化无需人工维护。ExternalDNS 使用getambassador.io/v3alpha1版本的 CRD这要求 Emissary-ingress 3.xdatawire/ambassadorv2 CRD 已不再随 3.10 quickstart 安装。如果仍然运行只提供 v2 CRD 的旧版本 Emissary请继续使用 ExternalDNS v0.21.0 或更早版本。工作原理ambassador-host源的核心逻辑位于 source/ambassador_host.go可总结为三步发现 Host通过 Kubernetes dynamic informer 监听getambassador.io/v3alpha1的hosts资源将Unstructured对象转换为ambassador.Host类型Endpoints方法source/ambassador_host.go。检查 annotation每个Host必须带有external-dns.ambassador-serviceannotation其值指向 Emissary-ingress 的LoadBalancerService。没有该 annotation 的Host会被直接忽略日志输出Host %s ignored: no annotation %q foundsource/ambassador_host.go。确定目标并生成记录优先使用external-dns.kubernetes.io/targetannotation 覆盖目标否则解析external-dns.ambassador-service指向的 Service取其外部地址作为目标targetsFromAmbassadorLoadBalancersource/ambassador_host.go。最终通过endpointsFromHost生成 A / CNAME 记录source/ambassador_host.go。external-dns.ambassador-service 的值格式该 annotation 支持三种写法解析逻辑见parseAmbLoadBalancerServicesource/ambassador_host.go写法含义示例name与Host同命名空间下的 Serviceemissary-ingressnamespace/name显式指定命名空间emissary/emissary-ingressname.namespaceAmbassador 历史跨命名空间语法emissary-ingress.emissary实现上先按/切分若无/再按.切分仅一次因此svc.foo.bar会被解释为命名空间foo.bar中的 Servicesvc若两者都不是则视为同命名空间 Service。测试向量完整覆盖了这些边界情况source/ambassador_host_test.go例如ns/svc/foo/bar会被判定为非法格式并返回错误。目标Target的解析优先级目标地址的确定遵循以下顺序对应源码中Endpoints的 targets 处理external-dns.kubernetes.io/targetannotation 显式指定的目标TargetsFromTargetAnnotation见 source/annotations/processors.go无该 annotation 时解析external-dns.ambassador-service指向的 Service 地址extractLoadBalancerTargetssource/service.go优先使用spec.externalIPs其次使用status.loadBalancer.ingress[].ip生成 A 记录再次使用status.loadBalancer.ingress[].hostname生成 CNAME 记录。测试用例对上述场景均有覆盖LoadBalancer IP 生成 A 记录、LoadBalancer hostname 生成 CNAME 记录、externalIPs优先级高于status.loadBalancer、target annotation 覆盖 Service 地址等source/ambassador_host_test.go。支持的 annotation根据 docs/annotations/annotations.md 的矩阵ambassador-host源支持Annotation作用external-dns.ambassador-service必需。指向 Emissary-ingressLoadBalancerService决定目标地址来源external-dns.kubernetes.io/target可选。覆盖记录目标external-dns.kubernetes.io/ttl可选。设置记录 TTLexternal-dns.kubernetes.io/provider-...可选。provider 专属 annotation如 Cloudflare 的cloudflare-proxiedTTL 与 provider 专属 annotation 分别由TTLFromAnnotationssource/annotations/processors.go与ProviderSpecificAnnotationssource/annotations/provider_specific.go解析。测试确认external-dns.kubernetes.io/ttl: 180会生成RecordTTL: 180的记录source/ambassador_host_test.goexternal-dns.kubernetes.io/cloudflare-proxied: true会附带对应的 provider 属性source/ambassador_host_test.go。过滤机制源还支持两类过滤见ambassadorHostSource结构体中的annotationFilter与labelSelectorsource/ambassador_host.goannotation 过滤通过--annotation-filter参数指定如kubernetes.io/ingress.class in (external-ingress)不匹配的 Host 被过滤annotations.Filtersource/annotations/filter.golabel 过滤通过--label-filter参数指定。在 source/ambassador_host_test.go 中多组测试验证了 annotation 过滤与 label 过滤单独或组合使用时匹配则生成记录、不匹配则忽略的行为。此外源通过--namespace参数支持所有命名空间或单个命名空间两种监听范围。在本地 kind 集群中端到端运行下面用 kind 在本地完整跑通ambassador-host源使用inmemoryprovider无需任何云凭证——ExternalDNS 本来要执行的 DNS 变更会直接打印到日志中。1. 创建集群kind create cluster --name external-dns-ambassador2. 安装 Emissary-ingress 3.10kubectl apply -f https://app.getambassador.io/yaml/emissary/3.10.0/emissary-crds.yaml kubectl wait --timeout90s --forconditionavailable deployment emissary-apiext -n emissary-system kubectl create namespace emissary kubectl apply -f https://app.getambassador.io/yaml/emissary/3.10.0/emissary-emissaryns.yaml kubectl -n emissary rollout status deployment/emissary-ingress第一步安装 CRD 后Host.getambassador.iov3alpha1才会在集群中可写。3. 部署 ExternalDNS以下清单包含 ServiceAccount、ClusterRole、ClusterRoleBinding 与 Deployment。注意--sourceambassador-host必须配合--policysync才能观察到更新与删除--inmemory-zoneexample.com让inmemoryprovider 持久化记录否则每次协调循环都会重复发出CREATE看不到UPDATE/DELETE。apiVersion: v1 kind: ServiceAccount metadata: name: external-dns namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [] resources: [services,endpoints,pods] verbs: [get,watch,list] - apiGroups: [getambassador.io] resources: [hosts] 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 namespace: default 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.23.0 args: - --sourceambassador-host - --policysync # full synchronization so updates/deletes are applied; set --policyupsert-only to prevent deletions - --providerinmemory - --inmemory-zoneexample.com # persist records so updates/deletes are observable - --log-leveldebug # show the records that would be created # for a real provider, replace the two lines above, e.g.: # - --providerxxx # - --domain-filterexample.com # - --registrytxt # - --txt-owner-idmy-identifier应用清单kubectl apply -f external-dns.yaml从源码在宿主机上运行适合测试对源本身的本地改动此时使用当前 kubeconfig 上下文即 kind 集群不需要集群内 RBACgo run main.go \ --sourceambassador-host \ --providerinmemory \ --policysync \ --inmemory-zoneexample.com \ --interval10s \ --log-leveldebug参数说明--inmemory-zoneexample.com给inmemoryprovider 一个存放记录的 zone。没有它provider 在两次协调循环之间不保留任何状态每轮都会重复发出CREATE永远看不到UPDATE或DELETE--interval10s缩短两次协调循环之间的等待时间默认一分钟--log-leveldebug显示本应创建的记录。ambassador-host源在 source/store.go 的BuildWithConfig工厂中被注册types.AmbassadorHost分支启动时通过 dynamic informer 监听Host资源并通过 source/informers 层注册事件处理器与缓存同步逻辑source/ambassador_host.go。4. 创建一个 Hostinmemoryprovider 没有云 LoadBalancer因此要用external-dns.kubernetes.io/targetannotation 显式指定目标。但external-dns.ambassador-serviceannotation 依然必须存在否则该Host不会被处理kubectl apply -f - EOF apiVersion: getambassador.io/v3alpha1 kind: Host metadata: name: my-host namespace: default annotations: external-dns.ambassador-service: emissary/emissary-ingress external-dns.kubernetes.io/target: 203.0.113.10 spec: hostname: my-host.example.com acmeProvider: authority: none EOF5. 验证kubectl logs -l appexternal-dns -f应看到 ExternalDNS 拾取该Host并为my-host.example.com创建指向203.0.113.10的 A 记录... leveldebug msgEndpoints generated from Host: default/my-host: [my-host.example.com 0 IN A 203.0.113.10 []] ... levelinfo msgCREATE: my-host.example.com 0 IN A 203.0.113.10 []这段日志与源码中的调试输出一一对应Endpoints generated from Host: %s: %vsource/ambassador_host.go也与 source/ambassador_host_test.go 中真实 API Server 形态的 v3alpha1 Host 对象含 conversion webhook 注入的ambassador_id与acmeProvider字段测试所验证的产物一致。清理kind delete cluster --name external-dns-ambassador接入真实云 DNS Provider本地验证通过后把 Deployment 中的--providerinmemory与--inmemory-zoneexample.com替换为真实 provider 参数例如args: - --sourceambassador-host - --policysync - --provideraws - --domain-filterexample.com - --registrytxt - --txt-owner-idmy-identifier同时去掉 target annotation真实环境中不再需要external-dns.kubernetes.io/target让源自动解析external-dns.ambassador-service指向的 Emissary-ingressLoadBalancerService 地址指向正确 Service把external-dns.ambassador-service设置为实际运行的 Emissary-ingress Service上述清单中为emissary/emissary-ingress。这样当云平台为 Emissary-ingress 的LoadBalancerService 分配或更换外部 IP/主机名时ExternalDNS 会在下一次协调循环中自动更新对应的 DNS 记录实现 DNS 与入口的动态对齐。常见问题与排错建议Host 被忽略日志出现Host xxx ignored: no annotation external-dns.ambassador-service found说明缺少必需 annotationsource/ambassador_host.go。找不到目标日志出现Could not find targets for service ...说明 annotation 指向的 Service 不存在、格式非法或该 Service 既没有externalIPs也没有status.loadBalancer地址source/ambassador_host.go。总是 CREATE、没有 UPDATE/DELETEinmemoryprovider 未配置--inmemory-zone时不保留状态真实 provider 场景请确认--policysync且 registry 配置正确。版本不匹配ExternalDNS 使用 v3alpha1 CRD需要 Emissary-ingress 3.x旧版仅提供 v2 CRD 的环境请使用 ExternalDNS v0.21.0 或更早版本。相关阅读支持的 Sources 总览了解ambassador-host在全部源中的定位与能力矩阵过滤器、命名空间、FQDN 模板、事件、provider 专属支持Annotations 参考target、ttl及 provider 专属 annotation 的完整说明ambassador-host 源实现核心实现ambassador-host 源测试覆盖各种 annotation、过滤与目标解析场景ExternalDNS 部署清单生产环境部署参考赞分享云原生【免费下载链接】external-dnsConfigure external DNS servers dynamically from Kubernetes resources项目地址https://gitcode.com/gh_mirrors/ex/external-dns点击查看免费下载相关推荐minikube Ambassador 插件实战用 Ingress 与 Mapping 将集群服务暴露到本地minikube Ambassador 插件实战用 Ingress 与 Mapping 将集群服务暴露到本地 本篇技术指南围绕 minikube 官方文档中的云原生容器编排CLI开发工具ElysiaAPI网关Ambassador与映射ElysiaAPI网关Ambassador与映射 在现代API开发中网关作为请求的入口点承担着路由转发、认证授权、流量控制等关键职责。Elysia平台通过上一篇如何高效自动化处理B站会员购抢票开源工具完全指南下一篇Undercover在大型Ruby项目中的应用Rails、Hanami和其他框架的最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门