Apache APISIX 是 Apache 软件基金会下的云原生 API 网关,它兼具动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、身份认证、可观测性等丰富的流量管理功能。很多场景下,我们可以选择在APISIX中使用CORS(跨源资源共享)来解决跨域问题。
APISIX提供了CRD和Annotations模式来启用CORS。本文主要介绍如何在APISIX Ingress Annotations模式下启用CORS。
环境:
应用 | 信息 |
---|---|
Kubernetes | v1.25.7 |
apisix | apache/apisix:3.4.0-debian |
apisix-ingress-controller | apache/apisix-ingress-controller:1.6.0 |
IngressAnnotations模式
IngressAnnotations模式,可以通过在Ingress资源上添加注释来配置APISIX的行为。比如添加一个CORS注释来指示APISIX启用CORS:
annotations
k8s.apisix.apache.org/enable-cors: "true"
kubernetes.io/ingress.class: apisix
接着,我们以给一个Http服务my-service, 创建了一个Ingress资源的例子来演示, Ingress详细如下:
创建Ingress
创建my-service的ingress资源:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: match-ingress
namespace: my-ns
annotations:
k8s.apisix.apache.org/enable-cors: "true"
kubernetes.io/ingress.class: apisix
spec:
rules:
- http:
paths:
- backend:
service:
name: my-service
port:
number: 8000
path: /v2
pathType: Prefix
在这个示例中,我们添加了【k8s.apisix.apache.org/enable-cors: “true”】的注释, 即启用cors功能,默认允许来自任何源的请求访问my-service的API。
Dashboard启用CORS
打开APISIX Dashboard界面:在【插件】中查找“CORS” 。单击该插件,然后单击“启用”。
然后,可以在路由点击查看my-service的对应路由,如下:
{
"uris": [
"/v2/",
"/v2/*"
],
"name": "ing_my-service-ingress_cfc81dbe",
"desc": "Created by apisix-ingress-controller, DO NOT modify it manually",
"plugins": {
"cors": {
"allow_credential": false,
"allow_headers": "*",
"allow_methods": "*",
"allow_origins": "*",
"expose_headers": "*",
"max_age": 5
}
},
"upstream_id": "7c630009",
"labels": {
"managed-by": "apisix-ingress-controller"
},
"status": 1
}
plugins.cors为跨域的对应规则配置,说明插件启用成功。
测试
然后我们向my-service的发起一个测试请求:
curl -i -k 'http://[my-cluster-ip:nodeport]/v2/my-service/api/geeker' -X OPTIONS \
-H "Access-Control-Allow-Origin: *" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type" \
-H "Origin: http://localhost/"
输出:
HTTP/1.1 200 OK
Date: Sat, 15 Jul 2023 13:53:57 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.4.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Max-Age: 5
Access-Control-Expose-Headers: *
Access-Control-Allow-Headers: *
如果返回结果中出现 CORS 相关的 header( ccess-Control-Allow-Origin: * < Access-Control-Allow-Methods: * < Access-Control-Allow-Headers: * < Access-Control-Expose-Headers: * < Access-Control-Max-Age: 5 ),则代表插件生效、跨域成功。
遇到的问题
在增加好ingress后测试API,发现没有CORS 相关的 header
,跨域失败
HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: *
Date: Sat, 15 Jul 2023 13:46:16 GMT
Server: APISIX/3.4.0
经检查,是ApiSix的config配置有误,在配置的插件里,开启了其他插件,没有包括cors,导致插件不生效。去掉后,重启插件配置生效、跨域成功。
plugins:
# the plugins you enabled
- log-rotate
- proxy-rewrite