如何借助External-DNS将dev.front.example.com/resources路由至S3/CloudFront
我用Terraform搭建了v1.28版本的EKS集群,用于托管一套Web解决方案,包含3个API和2个React前端。集群DNS由External-DNS管理,主域名为example.com,负载均衡通过AWS Load Balancer Controller实现。
我的React前端应用中所有静态资源均以/resources路径引用,目前这些静态资源存储在S3桶中,通过Nginx容器对外提供服务。当前请求链路为:S3 → Nginx容器 → ALB → 浏览器,存在多余跳转且产生额外计费流量。
我的目标链路是:S3(或CloudFront)→ 浏览器。
请问:能否在保持External-DNS管理DNS的前提下,将dev.front.example.com/resources的请求直接路由至S3或CloudFront?
补充信息
Nginx配置(ConfigMap)
--- apiVersion: v1 data: nginx-dev.conf: | server { listen 80; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html =404; } location /api/ { proxy_pass https://dev.api.admin.example.com/; } location /resources/ { proxy_pass https://bucket-dev.s3.eu-west-1.amazonaws.com/; } } kind: ConfigMap metadata: name: b2b-front-configs
Pod挂载配置
volumeMounts: - name: nginx-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf nodeSelector: instance-type: work-load volumes: - name: nginx-config configMap: name: b2b-front-configs items: - key: nginx-dev.conf path: default.conf
完全可以实现,且能保留External-DNS对DNS的管理权限,以下是两种可行方案:
方案一:通过AWS Load Balancer Controller配置ALB路径路由到S3
配置S3桶访问权限
确保S3桶bucket-dev允许ALB访问:可以设置桶的访问策略允许ALB的执行角色读取资源,或开启静态网站托管并设置公开访问(根据安全需求选择)。如果桶内资源没有/resources前缀,后续需在ALB中配置路径重写。修改Ingress资源添加路径规则
在现有指向dev.front.example.com的Ingress中,新增/resources/*路径的路由规则,直接转发到S3,无需经过Nginx Pod。AWS Load Balancer Controller支持通过自定义资源将ALB路径指向S3服务:- 首先定义关联S3桶的
AWSService资源:apiVersion: k8s.aws/v1alpha1 kind: Service metadata: name: s3-bucket-dev spec: type: AWS aws: service: s3 region: eu-west-1 bucket: name: bucket-dev path: /resources # 对应桶内资源的路径前缀 - 然后更新Ingress,添加路径路由:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: front-ingress annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip # 保留原有其他注解 spec: ingressClassName: alb rules: - host: dev.front.example.com http: paths: - path: / pathType: Prefix backend: service: name: front-nginx-service port: number: 80 - path: /resources/* pathType: Prefix backend: resource: apiGroup: k8s.aws kind: Service name: s3-bucket-dev
- 首先定义关联S3桶的
保留External-DNS管理
原有Ingress的host字段仍为dev.front.example.com,External-DNS会继续维护该域名指向ALB的DNS记录,ALB自动将/resources路径的请求转发到S3。
方案二:结合CloudFront优化静态资源访问
创建CloudFront分发
将CloudFront的源设置为bucket-dev.s3.eu-west-1.amazonaws.com,配置缓存策略适配静态资源,并设置行为匹配/resources/*路径(或根据需求调整为默认行为)。CloudFront会缓存资源,进一步降低S3流量费用并提升访问速度。配置ALB转发到CloudFront
在现有Ingress中新增/resources/*路径规则,将请求转发到CloudFront的域名,无需修改External-DNS的DNS记录——域名仍指向ALB,由ALB完成路径分流。可选:直接用CloudFront作为域名源
如果希望完全绕开ALB,可通过External-DNS管理dev.front.example.com的DNS记录指向CloudFront,同时在CloudFront中配置多个源:一个指向S3处理/resources路径,另一个指向ALB处理前端页面和API请求。这种方式需要在CloudFront中配置路径行为规则区分不同请求。
额外注意事项
- 权限验证:确保ALB或CloudFront具备访问S3桶的权限,避免出现403错误,可通过IAM角色关联的方式实现权限控制。
- 路径重写:如果S3桶内资源没有
/resources前缀,需在ALB或CloudFront中配置路径重写,将/resources/*改写为/*后转发。 - 测试验证:修改配置后,通过
curl -v dev.front.example.com/resources/xxx.jpg测试请求链路,检查响应头的Server字段(S3返回AmazonS3,CloudFront返回CloudFront),确认请求未经过Nginx容器。
内容的提问来源于stack exchange,提问作者Ben Rhouma Zied

