https://github.com/tokers/envoy-apisix-in-mesh
Demonstration about how to run envoy-apisix in Istio Mesh.
https://github.com/tokers/envoy-apisix-in-mesh
Last synced: 26 days ago
JSON representation
Demonstration about how to run envoy-apisix in Istio Mesh.
- Host: GitHub
- URL: https://github.com/tokers/envoy-apisix-in-mesh
- Owner: tokers
- Created: 2020-12-22T11:47:53.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2020-12-26T03:05:37.000Z (over 4 years ago)
- Last Synced: 2024-06-20T10:04:11.158Z (11 months ago)
- Language: Go
- Homepage:
- Size: 42 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# envoy-apisix-in-mesh
This project aims to demonstrate how to run [envoy-apisix](https://github.com/api7/envoy-apisix) in Istio mesh.
## Kubernetes Cluster & Service Mesh
Before you start, make sure you have an available Kubernetes cluster, [Minikube](https://minikube.sigs.k8s.io/docs/start/) is a nice choice to build Kubernetes cluster in your own development environment.
Also, we need [Istio distribution](https://github.com/istio/istio/releases/tag/1.8.1) to build the Service Mesh. So Istio ingress/egress gateways, Istiod and other resources should also be installed, use Istio's helm [charts](https://github.com/istio/istio/tree/master/manifests/charts) to install will make the process easiler.
## Topology
We will use the [Bookinfo Application](https://istio.io/latest/docs/examples/bookinfo/) as the base Service Mesh environment. The topology as shown below:

Install all the necessary apps by running:
```
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
```Then, add a VirtualService resource to configure the istio-gateway, so that it knows how to forward trafic to the mesh. Note we have our own [copy](./samples/bookinfo-gateway.yaml) of it with some minor changes (use FQDN).
```
$ kubectl apply -f https://raw.githubusercontent.com/tokers/envoy-apisix-in-mesh/main/samples/bookinfo-gateway.yaml -n istio-system
```## Extra Steps
Although Envoy embeds LuaJIT to extend itself, all Lua codes (not the runtime) are prepared by Users, so does envoy-apisix, so all Lua files in envoy-apisix need to be mounted into the istio-ingressgateway (gateway) and all istio-proxy (sidecar) containers.
We have a [configmap.go](configmap.go) script to iterate all Lua codes in envoy-apisix and create correpsonding configmap resouces.
We will run it twice for our demostrations.
The first run will generate necessary resources for the istio-ingressgateway, and the second one is for sidecars.
```sh
$ LUA_DIR=/path/to/envoy-apisix/lua go run configmap.goCreated configmap file configmaps/envoy-apisix-configmap-3
Created configmap file configmaps/envoy-apisix-configmap-0
Created configmap file configmaps/envoy-apisix-configmap-1
Created configmap file configmaps/envoy-apisix-configmap-2
Created kustomization.yamlRun
kubectl apply -k .to install configmaps in namespace istio-system
Please add these flags when you use helm to install istiod/istio-ingressgateway
--set gateways.istio-ingressgateway.configVolumes\[0\].mountPath="/usr/local/share/lua/5.1/deps/net" \
--set gateways.istio-ingressgateway.configVolumes\[0\].name="envoy-apisix-configmap-3" \
--set gateways.istio-ingressgateway.configVolumes\[0\].configMapName="envoy-apisix-configmap-3" \
--set gateways.istio-ingressgateway.configVolumes\[1\].mountPath="/usr/local/share/lua/5.1/apisix/core" \
--set gateways.istio-ingressgateway.configVolumes\[1\].name="envoy-apisix-configmap-0" \
--set gateways.istio-ingressgateway.configVolumes\[1\].configMapName="envoy-apisix-configmap-0" \
--set gateways.istio-ingressgateway.configVolumes\[2\].mountPath="/usr/local/share/lua/5.1/apisix" \
--set gateways.istio-ingressgateway.configVolumes\[2\].name="envoy-apisix-configmap-1" \
--set gateways.istio-ingressgateway.configVolumes\[2\].configMapName="envoy-apisix-configmap-1" \
--set gateways.istio-ingressgateway.configVolumes\[3\].mountPath="/usr/local/share/lua/5.1/apisix/plugins" \
--set gateways.istio-ingressgateway.configVolumes\[3\].name="envoy-apisix-configmap-2" \
--set gateways.istio-ingressgateway.configVolumes\[3\].configMapName="envoy-apisix-configmap-2" \
```Three kinds of resources are bumped:
1. a bunch of ConfigMap resources, each one contains several filename (base name) / codes key pairs.
2. a kustomization.yaml
3. a series of `--set` options, which guide you how to re-install istio-ingressgateway with these Lua codes.So just use Kustomization to install these ConfigMap resources.
```sh
$ kubectl apply -k . -n istio-system
configmap/envoy-apisix-configmap-1 configured
configmap/envoy-apisix-configmap-2 configured
configmap/envoy-apisix-configmap-3 configured
```As per the 3rd step, we should re-install the istio-ingressgateway, thanks for the good design of istio's helm charts, we don't need to hack it any more.
```sh
$ helm install -n istio-system istio-ingress manifests/charts/gateways/istio-ingress \
--set global.imagePullPolicy="IfNotPresent" \
--set global.hub="docker.io/istio" \
--set global.tag="1.8.1" \
--set global.jwtPolicy=first-party-jwt \
--set gateways.istio-ingressgateway.configVolumes\[0\].mountPath="/usr/local/share/lua/5.1/deps/net" \
--set gateways.istio-ingressgateway.configVolumes\[0\].name="envoy-apisix-configmap-3" \
--set gateways.istio-ingressgateway.configVolumes\[0\].configMapName="envoy-apisix-configmap-3" \
--set gateways.istio-ingressgateway.configVolumes\[1\].mountPath="/usr/local/share/lua/5.1/apisix/core" \
--set gateways.istio-ingressgateway.configVolumes\[1\].name="envoy-apisix-configmap-0" \
--set gateways.istio-ingressgateway.configVolumes\[1\].configMapName="envoy-apisix-configmap-0" \
--set gateways.istio-ingressgateway.configVolumes\[2\].mountPath="/usr/local/share/lua/5.1/apisix" \
--set gateways.istio-ingressgateway.configVolumes\[2\].name="envoy-apisix-configmap-1" \
--set gateways.istio-ingressgateway.configVolumes\[2\].configMapName="envoy-apisix-configmap-1" \
--set gateways.istio-ingressgateway.configVolumes\[3\].mountPath="/usr/local/share/lua/5.1/apisix/plugins" \
--set gateways.istio-ingressgateway.configVolumes\[3\].name="envoy-apisix-configmap-2" \
--set gateways.istio-ingressgateway.configVolumes\[3\].configMapName="envoy-apisix-configmap-2"
NAME: istio-ingress
LAST DEPLOYED: Tue Dec 22 21:47:57 2020
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
```And it's similar to change the istio-injector-template (to be continued).
Now try the sidecar.
```
$ NAMESPACE=bookinfo LUA_DIR=/path/to/envoy-apisix/lua go run configmap.go
Created configmap file configmaps/envoy-apisix-configmap-0
Created configmap file configmaps/envoy-apisix-configmap-1
Created configmap file configmaps/envoy-apisix-configmap-2
Created configmap file configmaps/envoy-apisix-configmap-3
Created kustomization.yamlRun
kubectl apply -k .to install configmaps in namespace bookinfo
Please add the following annotations to your application Pod template
sidecar.istio.io/userVolume: |
{"envoy-apisix-configmap-0":{"configMap":{"name":"envoy-apisix-configmap-0"},"name":"envoy-apisix-configmap-0"},"envoy-apisix-configmap-1":{"configMap":{"name":"envoy-apisix-configmap-1"},"name":"envoy-apisix-configmap-1"},"envoy-apisix-configmap-2":{"configMap":{"name":"envoy-apisix-configmap-2"},"name":"envoy-apisix-configmap-2"},"envoy-apisix-configmap-3":{"configMap":{"name":"envoy-apisix-configmap-3"},"name":"envoy-apisix-configmap-3"}}sidecar.istio.io/userVolumeMount: |
{"envoy-apisix-configmap-0":{"name":"envoy-apisix-configmap-0","mountPath":"/usr/local/share/lua/5.1/apisix/core"},"envoy-apisix-configmap-1":{"name":"envoy-apisix-configmap-1","mountPath":"/usr/local/share/lua/5.1/apisix"},"envoy-apisix-configmap-2":{"name":"envoy-apisix-configmap-2","mountPath":"/usr/local/share/lua/5.1/apisix/plugins"},"envoy-apisix-configmap-3":{"name":"envoy-apisix-configmap-3","mountPath":"/usr/local/share/lua/5.1/deps/net"}}
```It also generates ConfigMap resources which need to be mounted to the istio-proxy container, Istio's injection template will check annotions `sidecar.istio.io/userVolume` and `sidecar.istio.io/userVolumeMount` in application pod template, which allows us to mount custom volumes.
Now edit the deployment of reviews, and scale it down and up.
```
$ kube edit -n bookinfo reviews-v1
# add annotations sidecar.istio.io/userVolumeMount and sidecar.istio.io/userVolume.$ kube scale -n bookinfo --replicas 0
$ kube scale -n bookinfo --replicas 1
```## Goal
We prepare to demostrate two plugins in envoy-apisix:
* Redirect
* URI Blocker### Redirect
Redirect plugin intercepts the current request with configured status code and a custom Location header. We have [envoyfilter-ingressgateway.yaml](./samples/envoyfilter-ingressgateway.yaml) to let istio-ingressgateway returns 302 to https://apisix.apache.org when URI path is `/productpage`.
```sh
$ kubectl apply -f samples/envoyfilter-ingressgateway.yaml -n istio-system
```Now try to access the istio-ingressgateway.
```sh
export ISTIO_INGRESSGATEWAY_PORT=$(kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export ISTIO_INGRESSGATEWAY_HOST=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}')curl http://$ISTIO_INGRESSGATEWAY_HOST:$ISTIO_INGRESSGATEWAY_PORT/
productpage -vo /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 192.168.64.3...
* TCP_NODELAY set
* Connected to 192.168.64.3 (192.168.64.3) port 30679 (#0)
> GET /productpage HTTP/1.1
> Host: 192.168.64.3:30679
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 302 Found
< location: https://apisix.apache.org
< server: istio-envoy
< content-length: 4
< date: Tue, 22 Dec 2020 10:16:45 GMT
```When you see this output in your own machine, it means the plugin has already come into force.
### URI Blocker
URI Blocker allows you to deny some types of URI path and reject with custom status code. We have [envoyfilter-sidecar-reviews-v1.yaml](./samples/envoyfilter-sidecar-reviews-v1.yaml) to make the sidecar in reviews-v1 reject URI which contains `reviews`.
```
# first delete the legacy rules in istio-ingressgateway
$ kubectl delete -f samples/envoyfilter-ingressgateway.yaml -n istio-system
$ kubectl apply -f samples/envoyfilter-sidecar-reviews-v1.yaml -n bookinfoexport ISTIO_INGRESSGATEWAY_PORT=$(kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export ISTIO_INGRESSGATEWAY_HOST=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}')
```Now open your browser and access `http://$ISTIO_INGRESSGATEWAY_HOST:$ISTIO_INGRESSGATEWAY_PORT/productpage`, refresh the page several times (be patient, since Envoy uses keep-alived connections), and you will see `Sorry, product reviews are currently unavailable for this book.` in the Bookinfo Reviews bar.