Documented 06_Envoy examples:
- 01-Envoy-add-response-headers - 02-envoy-logging Added section README.md to: - 05-Sidecar - 06-Envoy
This commit is contained in:
parent
6aa4cb2c03
commit
de4ae7dd09
@ -1,42 +0,0 @@
|
||||
https://github.com/istio/istio/wiki/EnvoyFilter-Samples
|
||||
|
||||
https://stackoverflow.com/questions/73262158/how-to-apply-envoyfilter-to-sidecar-inbound-and-gateway
|
||||
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/envoy-filter/
|
||||
|
||||
https://discuss.istio.io/t/adding-custom-response-headers-using-istios-1-6-0-envoy-lua-filter/7494
|
||||
|
||||
|
||||
|
||||
https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter
|
||||
|
||||
|
||||
> kubectl logs -f deployments/istiod -n istio-system
|
||||
|
||||
|
||||
|
||||
This somewhat is monitoring, can do cool stuff I don't know how or what to do
|
||||
|
||||
|
||||
enable export access logs to stdout
|
||||
|
||||
|
||||
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout
|
||||
|
||||
|
||||
|
||||
https://istio.io/latest/docs/ops/diagnostic-tools/component-logging/
|
||||
|
||||
|
||||
|
||||
|
||||
https://dev.to/aws-builders/understanding-istio-access-logs-2k5o
|
||||
|
||||
```yaml
|
||||
Note: Here I am using request_handle:logCritical method because default logLevel is WARN for Istio components. request_handle:logInfo can be used, if logLevel is set to Info.
|
||||
```
|
||||
|
||||
https://youtu.be/yOtEG1luTwU
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
@ -1,6 +0,0 @@
|
||||
https://youtu.be/yOtEG1luTwU
|
||||
|
||||
|
||||
Rate Limit:
|
||||
|
||||
https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/
|
@ -9,9 +9,9 @@ On these examples, a `Sidecar` will be configured.
|
||||
|
||||
## Heads up
|
||||
|
||||
On the example `02-egress-proxy`, it's a requisite to configure Istio's `meshConfig.outboundTrafficPolicy.mode` as "REGISTRY_ONLY".
|
||||
On the example `02-egress-proxy`, it's a requisite to configure Istio's `meshConfig.outboundTrafficPolicy.mode` as `REGISTRY_ONLY`.
|
||||
|
||||
During the installation of the cluster itself, can be set with.
|
||||
During the installation of the cluster itself, can be set with:
|
||||
|
||||
```shell
|
||||
istioctl install profile=default --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
|
||||
|
@ -1,19 +1,3 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
# annotations:
|
||||
# sidecar.istio.io/componentLogLevel: info
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@ -30,7 +14,6 @@ spec:
|
||||
labels:
|
||||
app: helloworld
|
||||
annotations:
|
||||
sidecar.istio.io/componentLogLevel: lua:info
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
@ -28,6 +28,4 @@ spec:
|
||||
inlineCode: |
|
||||
function envoy_on_response(response_handle)
|
||||
response_handle:headers():add("numbers", "lots of numbers")
|
||||
response_handle:logInfo("Added header `numbers`")
|
||||
response_handle:logInfo(">>>> Executed `envoy-add-response-header` <<<<")
|
||||
end
|
14
06-Envoy/01-Envoy-add-response-headers/Gateway.yaml
Executable file
14
06-Envoy/01-Envoy-add-response-headers/Gateway.yaml
Executable file
@ -0,0 +1,14 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
308
06-Envoy/01-Envoy-add-response-headers/README.md
Executable file
308
06-Envoy/01-Envoy-add-response-headers/README.md
Executable file
@ -0,0 +1,308 @@
|
||||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
# Description
|
||||
|
||||
This example deploys the same infrastructure as the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), this time we will be configuring `Envoy` to add a custom header to the request response when our deployed service replies back.
|
||||
|
||||
This example configures:
|
||||
|
||||
Generic Kubernetes resources:
|
||||
- 1 Service
|
||||
- 1 Deployment
|
||||
|
||||
Istio resources:
|
||||
- 1 Gateway
|
||||
- 1 Virtual Service
|
||||
- 1 EnvoyFilter
|
||||
|
||||
|
||||
|
||||
# Based on
|
||||
|
||||
- [01-Getting_Started/01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
|
||||
|
||||
# Configuration
|
||||
|
||||
## Service
|
||||
|
||||
Creates a service named `helloworld`.
|
||||
|
||||
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### helloworld
|
||||
|
||||
Deploys a Nginx server that listens for the port `80`.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: helloworld-nginx
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helloworld
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
||||
image: nginx
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent #Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
```
|
||||
|
||||
## Gateway
|
||||
|
||||
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
|
||||
|
||||
It doesn't filter for any specific host.
|
||||
|
||||
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
|
||||
|
||||
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
```
|
||||
|
||||
## VirtualService
|
||||
|
||||
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
|
||||
|
||||
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
|
||||
|
||||
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
|
||||
|
||||
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
|
||||
|
||||
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
|
||||
|
||||
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
||||
```
|
||||
|
||||
## EnvoyFilter
|
||||
|
||||
`EnvoyFilter` allows to customize the Envoy configuration generated by Istio Pilot.
|
||||
|
||||
On this scenario we will be targeting the pods deployed in the namespace `default` with the label `app` set to `helloworld`.
|
||||
|
||||
The rule created will apply to the filter `HTTP_FILTER` to attach the Lua script to the http connection manager.
|
||||
|
||||
This script will be triggered with the incoming traffic goes through the port 80.
|
||||
|
||||
The code inside the lua script is very straightforward:
|
||||
|
||||
```lua
|
||||
response_handle:headers():add("numbers", "lots of numbers")
|
||||
```
|
||||
|
||||
Adds a header on the response request, which on this scenario is adding the header `numbers`, and giving it a value of `lots of numbers`.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: EnvoyFilter
|
||||
metadata:
|
||||
name: envoy-add-response-header
|
||||
namespace: default
|
||||
spec:
|
||||
priority: 30
|
||||
workloadSelector:
|
||||
labels:
|
||||
app: helloworld
|
||||
configPatches:
|
||||
- applyTo: HTTP_FILTER
|
||||
match:
|
||||
context: SIDECAR_INBOUND
|
||||
listener:
|
||||
portNumber: 80
|
||||
filterChain:
|
||||
filter:
|
||||
name: "envoy.filters.network.http_connection_manager"
|
||||
subFilter:
|
||||
name: "envoy.filters.http.router"
|
||||
patch:
|
||||
operation: INSERT_BEFORE
|
||||
value:
|
||||
name: envoy.lua
|
||||
typed_config:
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
|
||||
inlineCode: |
|
||||
function envoy_on_response(response_handle)
|
||||
response_handle:headers():add("numbers", "lots of numbers")
|
||||
end
|
||||
```
|
||||
|
||||
# Walkthrough
|
||||
|
||||
## Deploy resources
|
||||
|
||||
Deploy the resources.
|
||||
|
||||
```shell
|
||||
kubectl apply -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps/helloworld-nginx created
|
||||
envoyfilter.networking.istio.io/envoy-add-response-header created
|
||||
gateway.networking.istio.io/helloworld-gateway created
|
||||
service/helloworld created
|
||||
virtualservice.networking.istio.io/helloworld-vs created
|
||||
```
|
||||
|
||||
## Wait for the pods to be ready
|
||||
|
||||
Wait for the Nginx deployment to be ready.
|
||||
|
||||
```shell
|
||||
kubectl get deployment helloworld-nginx -w
|
||||
```
|
||||
```text
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
helloworld-nginx 1/1 1 1 49s
|
||||
```
|
||||
|
||||
## Test the service
|
||||
|
||||
### Get LB IP
|
||||
|
||||
To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
|
||||
|
||||
On my environment, the IP is the `192.168.1.50`.
|
||||
|
||||
```shell
|
||||
kubectl get svc -l istio=ingressgateway -A
|
||||
```
|
||||
```text
|
||||
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
istio-system istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 72d
|
||||
```
|
||||
|
||||
### Confirm the deployment works correctly.
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
|
||||
```
|
||||
|
||||
```text
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
||||
### Confirm the Lua Script is working correctly
|
||||
|
||||
After confirming that the request is able to succeed and confirming the backend that it's handling such request, the
|
||||
next step is to verify if the Lua script we deployed on through the [EnvoyFilter](#envoyfilter) is adding a new header.
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/helloworld --head
|
||||
```
|
||||
|
||||
```text
|
||||
HTTP/1.1 200 OK
|
||||
server: istio-envoy
|
||||
date: Sat, 14 Oct 2023 07:21:03 GMT
|
||||
content-type: text/html
|
||||
content-length: 615
|
||||
last-modified: Tue, 15 Aug 2023 17:03:04 GMT
|
||||
etag: "64dbafc8-267"
|
||||
accept-ranges: bytes
|
||||
x-envoy-upstream-service-time: 3
|
||||
numbers: lots of numbers
|
||||
```
|
||||
|
||||
#### Reviewing the response
|
||||
|
||||
If we take a closer look at the fields returned, at the bottom of the textblock, we can appreciate the following line:
|
||||
|
||||
> numbers: lots of numbers
|
||||
|
||||
Therefore, we were able to confirm that the [EnvoyFilter](#envoyfilter) configuration we set with a Lua script, did work
|
||||
as intended and added the desired Header to the response from the backend.
|
||||
|
||||
## Cleanup
|
||||
|
||||
Finally, a cleanup from the resources deployed.
|
||||
|
||||
```shell
|
||||
kubectl delete -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps "helloworld-nginx" deleted
|
||||
envoyfilter.networking.istio.io "envoy-add-response-header" deleted
|
||||
gateway.networking.istio.io "helloworld-gateway" deleted
|
||||
service "helloworld" deleted
|
||||
virtualservice.networking.istio.io "helloworld-vs" deleted
|
||||
```
|
||||
|
||||
## Links of interest
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-ApplyTo
|
||||
- https://github.com/istio/istio/wiki/EnvoyFilter-Samples
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-Patch-Operation
|
13
06-Envoy/01-Envoy-add-response-headers/Service.yaml
Normal file
13
06-Envoy/01-Envoy-add-response-headers/Service.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
20
06-Envoy/01-Envoy-add-response-headers/VirtualService.yaml
Normal file
20
06-Envoy/01-Envoy-add-response-headers/VirtualService.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
27
06-Envoy/02-envoy-logging/Deployment.yaml
Executable file
27
06-Envoy/02-envoy-logging/Deployment.yaml
Executable file
@ -0,0 +1,27 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: helloworld-nginx
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helloworld
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: helloworld
|
||||
annotations:
|
||||
sidecar.istio.io/componentLogLevel: lua:debug
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
||||
image: nginx
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent #Always
|
||||
ports:
|
||||
- containerPort: 80
|
@ -1,7 +1,7 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: EnvoyFilter
|
||||
metadata:
|
||||
name: envoy-add-response-header2
|
||||
name: envoy-raise-logs
|
||||
namespace: default
|
||||
spec:
|
||||
priority: 40
|
||||
@ -27,12 +27,11 @@ spec:
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
|
||||
inlineCode: |
|
||||
function envoy_on_response(response_handle)
|
||||
response_handle:headers():add("fruit", "watermelons")
|
||||
response_handle:logCritical("Critical: Added header `fruit`")
|
||||
response_handle:logErr("Error: Added header `fruit`")
|
||||
response_handle:logWarn("Warning: Added header `fruit`")
|
||||
response_handle:logInfo("Info: Added header `fruit`")
|
||||
response_handle:logDebug("Debug: Added header `fruit`")
|
||||
response_handle:logTrace("Trace: Added header `fruit`")
|
||||
response_handle:logInfo(">>>> Executed `envoy-add-response-header2` <<<<")
|
||||
end
|
||||
response_handle:logCritical("Critical: This is my Critical log")
|
||||
response_handle:logErr("Error: This is my Error log")
|
||||
response_handle:logWarn("Warning: This is my Warning log")
|
||||
response_handle:logInfo("Info: This is my Info log")
|
||||
response_handle:logDebug("Debug: This is my Debug log")
|
||||
response_handle:logTrace("Trace: This is my Trace log")
|
||||
response_handle:logInfo(">>>> Executed `envoy-raise-logs` <<<<")
|
||||
end
|
14
06-Envoy/02-envoy-logging/Gateway.yaml
Executable file
14
06-Envoy/02-envoy-logging/Gateway.yaml
Executable file
@ -0,0 +1,14 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
362
06-Envoy/02-envoy-logging/README.md
Executable file
362
06-Envoy/02-envoy-logging/README.md
Executable file
@ -0,0 +1,362 @@
|
||||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
# Description
|
||||
|
||||
This example deploys the same infrastructure as the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), but instead of adding a header to the response, we will be raising a custom log entry.
|
||||
|
||||
This example configures:
|
||||
|
||||
Generic Kubernetes resources:
|
||||
- 1 Service
|
||||
- 1 Deployment
|
||||
|
||||
Istio resources:
|
||||
- 1 Gateway
|
||||
- 1 Virtual Service
|
||||
- 1 EnvoyFilter
|
||||
|
||||
|
||||
|
||||
# Based on
|
||||
|
||||
- [01-Getting_Started/01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
|
||||
|
||||
# Configuration
|
||||
|
||||
## Service
|
||||
|
||||
Creates a service named `helloworld`.
|
||||
|
||||
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### helloworld
|
||||
|
||||
Deploys a Nginx server that listens for the port `80`.
|
||||
|
||||
On this deployment, we have set an annotation to configure a log level for the Istio sidecar/envoy-proxy attached to the deployment, that will allow the Lua scripts for a "debug" log level.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: helloworld-nginx
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helloworld
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: helloworld
|
||||
annotations:
|
||||
sidecar.istio.io/componentLogLevel: lua:debug
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
||||
image: nginx
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent #Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
```
|
||||
|
||||
## Gateway
|
||||
|
||||
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
|
||||
|
||||
It doesn't filter for any specific host.
|
||||
|
||||
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
|
||||
|
||||
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
```
|
||||
|
||||
## VirtualService
|
||||
|
||||
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
|
||||
|
||||
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
|
||||
|
||||
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
|
||||
|
||||
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
|
||||
|
||||
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
|
||||
|
||||
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
||||
```
|
||||
|
||||
## EnvoyFilter
|
||||
|
||||
`EnvoyFilter` allows to customize the Envoy configuration generated by Istio Pilot.
|
||||
|
||||
On this scenario we will be targeting the pods deployed in the namespace `default` with the label `app` set to `helloworld`.
|
||||
|
||||
The rule created will apply to the filter `HTTP_FILTER` to attach the Lua script to the http connection manager.
|
||||
|
||||
This script will be triggered with the incoming traffic goes through the port 80.
|
||||
|
||||
The code inside the lua script is fairly simple, as it will generate multiple logs in various tier levels, going from **Critical** to **Trace**:
|
||||
|
||||
```lua
|
||||
response_handle:logCritical("Critical: This is my Critical log")
|
||||
response_handle:logErr("Error: This is my Error log")
|
||||
response_handle:logWarn("Warning: This is my Warning log")
|
||||
response_handle:logInfo("Info: This is my Info log")
|
||||
response_handle:logDebug("Debug: This is my Debug log")
|
||||
response_handle:logTrace("Trace: This is my Trace log")
|
||||
response_handle:logInfo(">>>> Executed `envoy-raise-logs` <<<<")
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: EnvoyFilter
|
||||
metadata:
|
||||
name: envoy-raise-logs
|
||||
namespace: default
|
||||
spec:
|
||||
priority: 40
|
||||
workloadSelector:
|
||||
labels:
|
||||
app: helloworld
|
||||
configPatches:
|
||||
- applyTo: HTTP_FILTER
|
||||
match:
|
||||
context: SIDECAR_INBOUND
|
||||
listener:
|
||||
portNumber: 80
|
||||
filterChain:
|
||||
filter:
|
||||
name: "envoy.filters.network.http_connection_manager"
|
||||
subFilter:
|
||||
name: "envoy.filters.http.router"
|
||||
patch:
|
||||
operation: INSERT_BEFORE
|
||||
value:
|
||||
name: envoy.lua
|
||||
typed_config:
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
|
||||
inlineCode: |
|
||||
function envoy_on_response(response_handle)
|
||||
response_handle:logCritical("Critical: This is my Critical log")
|
||||
response_handle:logErr("Error: This is my Error log")
|
||||
response_handle:logWarn("Warning: This is my Warning log")
|
||||
response_handle:logInfo("Info: This is my Info log")
|
||||
response_handle:logDebug("Debug: This is my Debug log")
|
||||
response_handle:logTrace("Trace: This is my Trace log")
|
||||
response_handle:logInfo(">>>> Executed `envoy-raise-logs` <<<<")
|
||||
end
|
||||
```
|
||||
|
||||
# Walkthrough
|
||||
|
||||
## Deploy resources
|
||||
|
||||
Deploy the resources.
|
||||
|
||||
```shell
|
||||
kubectl apply -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps/helloworld-nginx created
|
||||
envoyfilter.networking.istio.io/envoy-raise-logs created
|
||||
gateway.networking.istio.io/helloworld-gateway created
|
||||
service/helloworld created
|
||||
virtualservice.networking.istio.io/helloworld-vs created
|
||||
```
|
||||
|
||||
## Wait for the pods to be ready
|
||||
|
||||
Wait for the Nginx deployment to be ready.
|
||||
|
||||
```shell
|
||||
kubectl get deployment helloworld-nginx -w
|
||||
```
|
||||
```text
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
helloworld-nginx 1/1 1 1 7s
|
||||
```
|
||||
|
||||
## Test the service
|
||||
|
||||
### Get LB IP
|
||||
|
||||
To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
|
||||
|
||||
On my environment, the IP is the `192.168.1.50`.
|
||||
|
||||
```shell
|
||||
kubectl get svc -l istio=ingressgateway -A
|
||||
```
|
||||
```text
|
||||
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
istio-system istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 72d
|
||||
```
|
||||
|
||||
### Confirm the deployment works correctly.
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
|
||||
```
|
||||
|
||||
```text
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
||||
### Confirm the Lua Script is working correctly
|
||||
|
||||
#### Monitor the logs
|
||||
|
||||
In a new shell we will use the following command to monitor the logs from the `istio-proxy` container located in the deployment created.
|
||||
|
||||
```shell
|
||||
kubectl logs -l app=helloworld -c istio-proxy -f
|
||||
```
|
||||
|
||||
#### Initiate a traffic request
|
||||
|
||||
After confirming that the request is able to succeed and confirming the backend that it's handling such request, the
|
||||
next step is to verify if the Lua script we deployed on through the [EnvoyFilter](#envoyfilter) is adding a new header.
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
|
||||
```
|
||||
|
||||
```text
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
||||
#### Logs generated
|
||||
|
||||
```text
|
||||
2023-10-14T07:59:36.213492Z critical envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:933 script log: Critical: This is my Critical log thread=28
|
||||
2023-10-14T07:59:36.213714Z error envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:930 script log: Error: This is my Error log thread=28
|
||||
2023-10-14T07:59:36.213846Z warning envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:927 script log: Warning: This is my Warning log thread=28
|
||||
2023-10-14T07:59:36.213972Z info envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:924 script log: Info: This is my Info log thread=28
|
||||
2023-10-14T07:59:36.214096Z debug envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:921 script log: Debug: This is my Debug log thread=28
|
||||
2023-10-14T07:59:36.214296Z info envoy lua external/envoy/source/extensions/filters/http/lua/lua_filter.cc:924 script log: >>>> Executed `envoy-raise-logs` <<<< thread=28
|
||||
2023-10-14T07:59:36.214425Z debug envoy lua external/envoy/source/extensions/filters/common/lua/lua.cc:39 coroutine finished thread=28
|
||||
[2023-10-14T07:59:36.210Z] "GET /helloworld HTTP/1.1" 200 - via_upstream - "-" 0 615 11 1 "192.168.1.44" "curl/8.4.0" "47093b83-6658-4ec6-8d21-7da5e70d6423" "192.168.1.50" "172.16.106.50:80" inbound|80|| 127.0.0.6:44723 172.16.106.50:80 192.168.1.44:0 outbound_.80_._.helloworld.default.svc.cluster.local default
|
||||
```
|
||||
|
||||
Reviewing the logs generated, we can observe that the entries range from `critical` to `debug`, yet we cannot locate the `trace` level log entry that we configured in the Lua script.
|
||||
|
||||
This is caused due to the annotation configured in the [Deployment](#deployment), where we selected a log level for the Lua script to be `debug`, out-ranging the `trace` level.
|
||||
|
||||
Therefore, we were able to confirm that the [EnvoyFilter](#envoyfilter) configuration we set with a Lua script, did work
|
||||
as intended and added the desired Header to the response from the backend, even tho the log entry with `trace` level was not recorded.
|
||||
|
||||
#### How to check the log level settings from a pod?
|
||||
|
||||
Through the command `istioctl proxy-config log <POD>`.
|
||||
|
||||
```shell
|
||||
istioctl proxy-config log "$(kubectl get pod -l app=helloworld | grep helloworld-nginx | awk '{print $1}')"
|
||||
```
|
||||
|
||||
```text
|
||||
helloworld-nginx-d8bc84b86-h6c68.default:
|
||||
active loggers:
|
||||
...
|
||||
health_checker: warning
|
||||
http: warning
|
||||
http2: warning
|
||||
hystrix: warning
|
||||
init: warning
|
||||
io: warning
|
||||
jwt: warning
|
||||
kafka: warning
|
||||
key_value_store: warning
|
||||
lua: debug
|
||||
main: warning
|
||||
...
|
||||
```
|
||||
|
||||
As well, we can confirm that by default the settings are set to only retain "warning" level logs.
|
||||
|
||||
## Cleanup
|
||||
|
||||
Finally, a cleanup from the resources deployed.
|
||||
|
||||
```shell
|
||||
kubectl delete -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps "helloworld-nginx" deleted
|
||||
envoyfilter.networking.istio.io "envoy-raise-logs" deleted
|
||||
gateway.networking.istio.io "helloworld-gateway" deleted
|
||||
service "helloworld" deleted
|
||||
virtualservice.networking.istio.io "helloworld-vs" deleted
|
||||
```
|
||||
|
||||
## Links of interest
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-ApplyTo
|
||||
- https://github.com/istio/istio/wiki/EnvoyFilter-Samples
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-Patch-Operation
|
13
06-Envoy/02-envoy-logging/Service.yaml
Normal file
13
06-Envoy/02-envoy-logging/Service.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
20
06-Envoy/02-envoy-logging/VirtualService.yaml
Normal file
20
06-Envoy/02-envoy-logging/VirtualService.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
45
06-Envoy/README.md
Executable file
45
06-Envoy/README.md
Executable file
@ -0,0 +1,45 @@
|
||||
|
||||
## Description
|
||||
|
||||
This section focuses on configuring the object `EnvoyFilter`.
|
||||
|
||||
|
||||
## Heads up
|
||||
|
||||
On the example `02-envoy-logging`, it's a requisite to configure Istio's `meshConfig.accessLogFile` as `/dev/stdout`.
|
||||
|
||||
During the installation of the cluster itself, can be set with:
|
||||
|
||||
```shell
|
||||
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout
|
||||
```
|
||||
|
||||
On the current scenario, I would recommend purging the Istio installation and reinstalling again, as I assume that you
|
||||
are testing this examples in a sandbox that you are free to "destroy".
|
||||
|
||||
### Purging Istio
|
||||
|
||||
```shell
|
||||
istioctl uninstall --purge
|
||||
```
|
||||
|
||||
Then proceed with reinstalling Istio using the command from above.
|
||||
|
||||
### What if I don't want to purge Istio?
|
||||
|
||||
Modify the IstioOperator similarly as mentioned [here](https://istio.io/latest/docs/tasks/traffic-management/egress/egress-control/#change-to-the-blocking-by-default-policy), and populate the object with the following fields:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
profile: minimal
|
||||
meshConfig:
|
||||
accessLogFile: /dev/stdout
|
||||
```
|
||||
|
||||
|
||||
## Links of Interest
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-ApplyTo
|
||||
- https://github.com/istio/istio/wiki/EnvoyFilter-Samples
|
||||
- https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-Patch-Operation
|
Loading…
x
Reference in New Issue
Block a user