如何在EKS中为每个命名空间自动配置对应子域名解析路由?
现有架构与需求
当前架构配置如下,新增服务时需要手动添加DNS记录:
Route53 ------> AWS ALB -----> Ingress-Nginx in EKS ---> Ingress-Rules -------> Service (app|api).ex.de | A record target | Target group of listener | Pointing to service
目标为通过命名空间实现多环境复制部署,为不同命名空间分配对应子域名并完成域名自动关联,映射规则为:
- dev-namespace -> (app|api).dev.ex.de
- pr-1-namespace -> (app|api).pr-1.ex.de
核心要求为新建命名空间部署新环境时,自动完成域名解析配置与路由链路关联,无需手动操作。
落地方案
整体思路是将DNS记录、Ingress路由规则的维护全流程转为K8s资源事件驱动的自动化模式,一次性完成基础组件配置后,新建环境只需创建对应命名空间即可,实现零手动操作。改造后链路如下:
Route53 ------> AWS ALB -----> Ingress-Nginx in EKS ---> 按Host头匹配路由 ---> 对应命名空间下Service 自动同步的域名记录 | 全量转发80/443流量到Ingress-Nginx | 自动加载新生成的命名空间对应路由规则
1. 一次性基础组件配置
ALB层改造
不需要为每个子域单独配置监听器规则,只需做两项全局配置:
- 为ALB的443监听器绑定覆盖
*.ex.de、*.*.ex.de的通配符ACM证书,监听器默认动作设置为将所有流量转发到Ingress-Nginx对应的目标组,80端口监听器默认配置跳转到HTTPS即可。 - 保留ALB到Ingress-Nginx的原有健康检查规则,不需要做额外调整。
DNS自动化配置
选择以下任意一种DNS方案即可,生产环境优先选方案B:
- 方案A(零组件依赖,一次配置永久生效):在Route53的ex.de托管区添加两条A类型别名记录,分别为
*.ex.de和*.*.ex.de,目标均指向当前ALB。配置完成后所有符合<env>.ex.de、<svc>.<env>.ex.de格式的域名都会自动解析到ALB,后续完全不需要维护DNS记录。缺点是不存在的服务域名也会被解析到ALB,会产生少量无效流量。 - 方案B(按需生成解析记录,生产推荐):在EKS集群部署
ExternalDNS组件,为其配置绑定拥有ex.de托管区记录修改权限的IRSA角色,配置组件监听集群内的Ingress资源,当检测到Ingress中新增host规则时,自动在Route53中创建对应的A记录指向ALB,Ingress删除时同步清理对应解析记录,不会产生无效解析。
路由自动注入组件部署
在集群部署Kyverno准入控制器,用于在命名空间创建时自动生成对应子域的Ingress规则,不需要每次部署环境手动编写Ingress配置。
2. 配置自动生成Ingress的策略
编写Kyverno ClusterPolicy策略,实现带指定标签的命名空间创建时,自动生成对应子域的Ingress资源,策略示例如下:
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: auto-generate-env-ingress spec: rules: - name: generate-subdomain-ingress match: any: - resources: kinds: - Namespace selector: matchLabels: auto-subdomain: "true" generate: kind: Ingress name: env-default-ingress namespace: "{{request.object.metadata.name}}" synchronize: true data: spec: ingressClassName: nginx rules: - host: "app.{{request.object.metadata.name}}.ex.de" http: paths: - path: / pathType: Prefix backend: service: name: app port: number: 80 - host: "api.{{request.object.metadata.name}}.ex.de" http: paths: - path: / pathType: Prefix backend: service: name: api port: number: 80
策略说明:
- 仅打了
auto-subdomain: "true"标签的命名空间会触发自动Ingress生成,不影响集群内现有其他命名空间。 synchronize: true表示命名空间删除、标签变更时,自动生成的Ingress资源会同步清理/更新,无残留垃圾规则。- 若需要自定义子域名前缀(比如dev-namespace对应子域前缀为dev而非dev-namespace),可在命名空间添加
subdomain-prefix: dev注解,修改策略内host取值为app.{{request.object.metadata.annotations.'subdomain-prefix'}}.ex.de即可适配。 - 策略内的服务名、端口可按实际业务部署情况修改。
3. 新环境部署流程
所有基础配置完成后,新建环境只需要创建带对应标签的命名空间即可,示例:
apiVersion: v1 kind: Namespace metadata: name: dev-namespace labels: auto-subdomain: "true"
后续全流程自动完成,无任何手动操作步骤:
- Kyverno监测到带标签的命名空间创建,自动在该命名空间下生成对应app、api子域的Ingress规则。
- Ingress-Nginx自动监听Ingress资源变化,加载新的路由规则,将对应域名的流量转发到命名空间内的对应服务。
- 如果使用ExternalDNS方案,检测到新的Ingress host后自动在Route53创建对应的解析记录;如果使用泛解析方案,DNS解析天然已经通了。
- 流量从用户侧到Route53、ALB、Ingress-Nginx最终到服务的全链路自动打通。
补充说明
- 若需要为每个子域配置独立的HTTPS证书,可在集群部署cert-manager,在Kyverno生成的Ingress模板里添加对应的注解,自动申请并挂载证书即可。
- 若需要做路径重写、跨域、流量限流等规则,统一在Ingress-Nginx层面配置全局策略,或者在自动生成的Ingress模板里添加对应注解即可,不需要每次单独配置。
- 权限配置遵循最小化原则:ExternalDNS的IRSA角色仅授予ex.de托管区的记录修改权限,Kyverno的服务账号仅授予Ingress资源的生成、修改、删除权限即可。
内容的提问来源于stack exchange,提问作者user18275887
相关产品推荐
相关产品推荐

