更新时间:2024-11-12 GMT+08:00

为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命令行配置

  1. 请参见通过kubectl连接集群,使用kubectl连接集群。
  2. 创建名为“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'

  3. 创建Ingress。

    kubectl create -f ingress-test.yaml

    回显如下,表示Ingress服务已创建。

    ingress/ingress-test created

  4. 查看已创建的Ingress。

    kubectl get ingress
    回显如下,表示Ingress服务创建成功。
    NAME          CLASS    HOSTS     ADDRESS          PORTS   AGE
    ingress-test  cce      *         121.**.**.**     80      10s

验证跨域访问配置是否生效

  1. 登录ELB控制台,找到Ingress使用的ELB实例,查看监听器的转发策略中是否存在跨域配置。

  2. 使用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