blob: a7ecd238fc1f4e8991105a62c6205110c83e9759 [file] [log] [blame] [view]
---
title: ApisixRoute
---
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
`ApisixRoute` is a CRD resource which focus on how to route traffic to
expected backend, it exposes many features supported by Apache APISIX.
Compared to [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/),
functions are implemented in a more native way, with stronger semantics.
Path based route rules
----------------------
URI path are always used to split traffic, for instance, requests with host `foo.com` and
`/foo` prefix should be routed to service `foo` while requests which path is `/bar`
should be routed to service `bar`, in the manner of `ApisixRoute`, the configuration
should be:
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: foo-bar-route
spec:
http:
- name: foo
match:
hosts:
- foo.com
paths:
- "/foo*"
backends:
- serviceName: foo
servicePort: 80
- name: bar
match:
paths:
- "/bar"
backends:
- serviceName: bar
servicePort: 80
```
There are two path types can be used, `prefix` and `exact`, default is `exact`,
while if `prefix` is desired, just append a `*`, for instance, `/id/*` matches
all paths with the prefix of `/id/`.
Advanced route features
-----------------------
Path based route are most common, but if it's not enough, try
other route features in `ApisixRoute` such as `methods`, `exprs`.
The `methods` splits traffic according to the HTTP method, the following configurations routes requests
with `GET` method to `foo` service (a Kubernetes Service).
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: method-route
spec:
http:
- name: method
match:
paths:
- /
methods:
- GET
backends:
- serviceName: foo
servicePort: 80
```
The `exprs` allows user to configure match conditions with arbitrary predicates in HTTP, such as queries, HTTP headers, Cookie.
It's composed by several expressions, which in turn composed by subject, operator and value/set.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: method-route
spec:
http:
- name: method
match:
paths:
- /
exprs:
- subject:
scope: Query
name: id
op: Equal
value: "2143"
backends:
- serviceName: foo
servicePort: 80
```
The above configuration configures an extra route match condition, which asks the
query `id` must be equal to `2143`.
Service Resolution Granularity
------------------------------
By default a referenced Service will be watched, so
it's newest endpoints list can be updated to Apache APISIX.
apisix-ingress-controller provides another mechanism that just use
the `ClusterIP` of this service, if that's what you want, just set
the `resolveGranularity` to `service` (default is `endpoint`).
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: method-route
spec:
http:
- name: method
match:
paths:
- /*
methods:
- GET
backends:
- serviceName: foo
servicePort: 80
resolveGranularity: service
```
Weight Based Traffic Split
--------------------------
There can more than one backend specified in one route rule,
when multiple backends co-exist there, the traffic split based on weights
will be applied (which actually uses the [traffic-split](http://apisix.apache.org/docs/apisix/plugins/traffic-split/) plugin in Apache APISIX).
You can specify weight for each backend, the default weight is `100`.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: method-route
spec:
http:
- name: method
match:
paths:
- /*
methods:
- GET
exprs:
- subject:
scope: Header
name: User-Agent
op: RegexMatch
value: ".*Chrome.*"
backends:
- serviceName: foo
servicePort: 80
weight: 100
- serviceName: bar
servicePort: 81
weight: 50
```
The above `ApisixRoute` has one route rule, which contains two backends `foo` and `bar`, the weight ratio is `100:50`,
which means `2/3` requests (with `GET` method and `User-Agent` matching regex pattern `.*Chrome.*`) will be sent to service `foo` and `1/3` requests
will be proxied to service `bar`.
Plugins
-------
Apache APISIX provides more than 70 [plugins](https://github.com/apache/apisix/tree/master/docs/en/latest/plugins), which can be used
in `ApisixRoute`. All configuration items are named same to the one in APISIX.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: httpbin
match:
hosts:
- local.httpbin.org
paths:
- /*
backends:
- serviceName: foo
servicePort: 80
plugins:
- name: cors
enable: true
```
The above configuration enables [Cors](https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/cors.md) plugin for requests
which host is `local.httpbin.org`.
Websocket Proxy
---------------
[Websocket](https://en.wikipedia.org/wiki/WebSocket#:~:text=WebSocket%20is%20a%20computer%20communications,WebSocket%20is%20distinct%20from%20HTTP.) service can be proxied
by creating a route with specifying the `websocket` field.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: ws-route
spec:
http:
- name: websocket
match:
hosts:
- ws.foo.org
paths:
- /*
backends:
- serviceName: websocket-server
servicePort: 8080
websocket: true
```
TCP Route
---------
apisix-ingress-controller supports the port-based tcp route.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: tcp-route
spec:
stream:
- name: tcp-route-rule1
protocol: TCP
match:
ingressPort: 9100
backend:
serviceName: tcp-server
servicePort: 8080
```
The above yaml configuration guides TCP traffic entered to the Ingress proxy server (i.e. [APISIX](https://apisix.apache.org)) port `9100` should be routed to the backend service `tcp-server`.
Note since APISIX doesn't support dynamic listening, so here the `9100` port should be pre-defined in APISIX [configuration](https://github.com/apache/apisix/blob/master/conf/config-default.yaml#L101).
UDP Route
---------
apisix-ingress-controller supports the port-based udp route.
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: udp-route
spec:
stream:
- name: udp-route-rule1
protocol: UDP
match:
ingressPort: 9200
backend:
serviceName: udp-server
servicePort: 53
```
The above yaml configuration guides UDP traffic entered to the Ingress proxy server (i.e. [APISIX](https://apisix.apache.org)) port `9200` should be routed to the backend service `udp-server`.
Note since APISIX doesn't support dynamic listening, so here the `9200` port should be pre-defined in APISIX [configuration](https://github.com/apache/apisix/blob/master/conf/config-default.yaml#L105).