为ELB Ingress配置跨域访问
在Web开发中,由于浏览器的同源策略,一个域下的网页通常不能直接请求另一个域下的资源。CORS(跨资源共享,Cross-Origin Resource Sharing)提供了一种安全的方式来绕过这个限制,允许跨域请求。
使用CORS允许跨域访问的场景较多,可能的场景如下:
- 前后端分离:前端应用部署在一个域名下(如 app.example.com),而后端API服务使用另一个域名(如 api.example.com),前端应用在尝试从API服务获取数据时会遇到跨域资源共享问题,需要配置CORS允许跨域访问。
- 第三方服务集成:网站可能需要调用第三方服务(例如地图服务、社交平台登录等)的API接口,则需要配置CORS允许跨域访问。
- 使用内容分发网络CDN:静态资源可能通过CDN提供,而CDN域名与主站域名不同,需要使用跨域访问来加载这些资源。
- ELB Ingress的跨域访问功能依赖ELB能力,使用该功能前请提交工单申请开通ELB跨域访问能力。
- 为ELB Ingress配置跨域访问时,不支持同时设置URL重定向、Rewrite重写、HTTP重定向到HTTPS。
前提条件
- 已创建一个CCE Standard或CCE Turbo集群,且集群版本满足以下要求:
- v1.23集群:v1.23.18-r10及以上
- v1.25集群:v1.25.16-r0及以上
- v1.27集群:v1.27.16-r0及以上
- v1.28集群:v1.28.13-r0及以上
- v1.29集群:v1.29.8-r0及以上
- v1.30集群:v1.30.4-r0及以上
- 其他更高版本的集群
- 您需要使用kubectl连接到集群,详情请参见通过kubectl连接集群。
通过kubectl命令行配置
- 请参见通过kubectl连接集群,使用kubectl连接集群。
- 创建名为“ingress-test.yaml”的YAML文件,此处文件名可自定义。
vi ingress-test.yaml
以使用已有ELB创建Ingress的场景为例,YAML配置如下:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test namespace: default annotations: kubernetes.io/elb.class: performance # 仅支持独享型ELB kubernetes.io/elb.cors-allow-origin: 'http://example.com' # 允许访问的域 kubernetes.io/elb.cors-allow-headers: 'fake-header-1' # 允许的请求头 kubernetes.io/elb.cors-expose-headers: 'fake-header-2' # 需要公开的响应头 kubernetes.io/elb.cors-allow-methods: 'GET,POST' # 允许的HTTP请求方法 kubernetes.io/elb.cors-allow-credentials: 'true' # 允许发送凭据 kubernetes.io/elb.cors-max-age: '3600' # 预检请求的缓存时长 kubernetes.io/elb.port: '80' kubernetes.io/elb.id: 3f5906fb-2b07-4e33-b3fe-b095f03d86a6 spec: rules: - host: example.com http: paths: - path: / backend: service: name: nginx-03657 port: number: 80 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: cce
表1 跨域访问注解 参数
类型
描述
样例
kubernetes.io/elb.cors-allow-origin
Array[string]
指定Access-Control-Allow-Origin响应头的值,表示允许访问的域。
支持以下取值:
- 通配符*:表示允许所有域名访问。
- 配置域名列表:必须为http://或者https://开头的域名,支持填写一级泛域名。格式为“http(s)://example.com”或“http(s)://example.com:port”,端口范围为1~65535。
可填写多个值,以英文逗号分隔。
kubernetes.io/elb.cors-allow-origin: 'http://example.com'
kubernetes.io/elb.cors-allow-headers
Array[string]
指定Access-Control-Allow-Headers响应头的值,表示允许的请求头。可填写多个值,以英文逗号分隔。
kubernetes.io/elb.cors-allow-headers: 'fake-header-1'
kubernetes.io/elb.cors-expose-headers
Array[string]
指定Access-Control-Expose-Headers响应头的值,表示可以被跨域请求读取的自定义响应头部,例如通过客户端的JavaScript代码获取非标准响应头字段。可填写多个值,以英文逗号分隔。
kubernetes.io/elb.cors-expose-headers: 'fake-header-2'
kubernetes.io/elb.cors-allow-methods
Array[string]
指定Access-Control-Allow-Methods响应头的值,表示允许的HTTP请求方法。
可填写多个值,以英文逗号分隔。
kubernetes.io/elb.cors-allow-methods: 'GET,POST'
kubernetes.io/elb.cors-allow-credentials
String
指定Access-Control-Allow-Credentials响应头的值,表示是否允许发送凭据(如Cookies)。
取值如下:
- true:允许发送凭据。
- false:不允许发送凭据。
设置后不允许删除,如需可通过kubernetes.io/elb.cors-disabled删除所有跨域配置。
kubernetes.io/elb.cors-allow-credentials: 'true'
kubernetes.io/elb.cors-max-age
String
指定Access-Control-Max-Age响应头的值,表示CORS预检请求的缓存时长。单位:秒。取值范围:-1~172800。
该参数值应该根据实际需求合理设置。如果设置得太短,可能会导致频繁的预检请求;如果设置得太长,可能会在CORS策略更新后延迟生效。
kubernetes.io/elb.cors-max-age: '3600'
kubernetes.io/elb.cors-disabled
String
该参数用于关闭所有跨域配置。取值如下:
- true:关闭所有跨域配置。YAML中的参数值不会被删除,但所有配置均不生效。
- false:默认取值,跨域配置将根据用户设置生效。
kubernetes.io/elb.cors-disabled: 'true'
- 创建Ingress。
kubectl create -f ingress-test.yaml
回显如下,表示Ingress服务已创建。
ingress/ingress-test created
- 查看已创建的Ingress。
kubectl get ingress
回显如下,表示Ingress服务创建成功。NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test cce * 121.**.**.** 80 10s
验证跨域访问配置是否生效
- 登录ELB控制台,找到Ingress使用的ELB实例,查看监听器的转发策略中是否存在跨域配置。
- 使用curl命令行工具发送跨域请求,并检查响应头部。
curl -X OPTIONS -H 'Origin: {源站点}' {Ingress访问URL}
例如,本示例中源站点为example.com,访问的Ingress URL为121.**.**.**:80,则命令如下:
curl -X OPTIONS -H 'Origin: example.com' 121.**.**.**:80
回显如下,跨域访问会在原始后端响应中添加Access-Control-**相关的请求头:
HTTP/1.1 200 OK Access-Control-Allow-Headers: fake-header-1 Access-Control-Expose-Headers: fake-header-2 Access-Control-Allow-Methods: GET, POST Access-Control-Allow-Credentials: true Access-Control-Max-Age: 3600