traffic-split
This guide describes how to use the traffic-split plugin in APISIX Ingress.
The traffic-split plugin can be used to dynamically route part of traffic to various upstream services.
IMPORTANT
If multiple services are declared in ApisixRoute http[].backends
, it cannot be used with traffic-split.
Correct example:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
plugins:
- name: traffic-split # It works.
enable: true
Invalid examples:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
paths:
- /*
backends:
- serviceName: httpbin1
servicePort: 80
- serviceName: httpbin2
servicePort: 80
plugins:
- name: traffic-split # Not working, this plugin is invalid and cannot be used with multiple backend.
enable: true
#
Example-usageIMPORTANT
The traffic-split plugin will directly use Kubernetes DNS, which will not automatically resolve services.
Because there is namespace isolation between services, and use the form of ${service}.${namespace}
in the upstream.nodes
.
#
Deploy hecho1 and hecho2 serviceWe use hashicorp/http-echo as the service image, See its overview page for details.
Deploy it to the default namespace:
# deployment hecho1
kubectl run hecho1 --image hashicorp/http-echo --port 5678 -- -text "http-echo v1"
kubectl expose pod hecho1 --port 5678
# deployment hecho2
kubectl run hecho2 --image hashicorp/http-echo --port 5678 -- -text "http-echo v2"
kubectl expose pod hecho2 --port 5678
#
Route the trafficRoutes to different services according to the http header subset
.
- If HTTP header
subset: v1
routing to hecho1. - If HTTP header
subset: v2
routing to hecho2.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
paths:
- /hecho
backends:
- serviceName: hecho1
servicePort: 5678
plugins:
- name: traffic-split
enable: true
config:
rules:
- match:
- vars:
- - http_subset
- ==
- v1
weighted_upstreams:
- upstream:
name: v1
type: roundrobin
nodes:
hecho1.default:5678: 1
- match:
- vars:
- - http_subset
- ==
- v2
weighted_upstreams:
- upstream:
name: v2
type: roundrobin
nodes:
hecho2.default:5678: 1
Use header sebset: v1
to access:
kubectl run -it --rm curl --restart=Never --image=curlimages/curl -- \
curl http://apisix-gateway.ingress-apisix/hecho -H 'subset: v1' -i
It should output:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
X-App-Name: http-echo
X-App-Version: 0.2.3
Date: Tue, 28 Feb 2023 08:54:31 GMT
Server: APISIX/3.1.0
http-echo v1
Use header sebset: v2
to access:
kubectl run -it --rm curl --restart=Never --image=curlimages/curl -- \
curl http://apisix-gateway.ingress-apisix/hecho -H 'subset: v2' -i
It should output:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
X-App-Name: http-echo
X-App-Version: 0.2.3
Date: Tue, 28 Feb 2023 08:55:04 GMT
Server: APISIX/3.1.0
http-echo v2