diff --git a/.placeholder/06-Envoy/01-envoy_add_headers/README.md b/.placeholder/06-Envoy/01-envoy_add_headers/README.md deleted file mode 100755 index 74fa6b5..0000000 --- a/.placeholder/06-Envoy/01-envoy_add_headers/README.md +++ /dev/null @@ -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 - - diff --git a/.placeholder/06-Envoy/01-envoy_add_headers/gateway.yaml b/.placeholder/06-Envoy/01-envoy_add_headers/gateway.yaml deleted file mode 100755 index 8ba8a20..0000000 --- a/.placeholder/06-Envoy/01-envoy_add_headers/gateway.yaml +++ /dev/null @@ -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: "/" \ No newline at end of file diff --git a/.placeholder/06-Envoy/README.md b/.placeholder/06-Envoy/README.md deleted file mode 100755 index 42d222c..0000000 --- a/.placeholder/06-Envoy/README.md +++ /dev/null @@ -1,6 +0,0 @@ -https://youtu.be/yOtEG1luTwU - - -Rate Limit: - -https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/ \ No newline at end of file diff --git a/05-Sidecar/README.md b/05-Sidecar/README.md index 1d132cf..cd189d4 100755 --- a/05-Sidecar/README.md +++ b/05-Sidecar/README.md @@ -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 diff --git a/.placeholder/06-Envoy/01-envoy_add_headers/deployment.yaml b/06-Envoy/01-Envoy-add-response-headers/Deployment.yaml similarity index 61% rename from .placeholder/06-Envoy/01-envoy_add_headers/deployment.yaml rename to 06-Envoy/01-Envoy-add-response-headers/Deployment.yaml index e3319c3..d6dc8b9 100755 --- a/.placeholder/06-Envoy/01-envoy_add_headers/deployment.yaml +++ b/06-Envoy/01-Envoy-add-response-headers/Deployment.yaml @@ -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 diff --git a/.placeholder/06-Envoy/01-envoy_add_headers/envoy.yaml b/06-Envoy/01-Envoy-add-response-headers/Envoy.yaml similarity index 85% rename from .placeholder/06-Envoy/01-envoy_add_headers/envoy.yaml rename to 06-Envoy/01-Envoy-add-response-headers/Envoy.yaml index 00a50dc..a70ea82 100755 --- a/.placeholder/06-Envoy/01-envoy_add_headers/envoy.yaml +++ b/06-Envoy/01-Envoy-add-response-headers/Envoy.yaml @@ -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 diff --git a/06-Envoy/01-Envoy-add-response-headers/Gateway.yaml b/06-Envoy/01-Envoy-add-response-headers/Gateway.yaml new file mode 100755 index 0000000..bbd9d67 --- /dev/null +++ b/06-Envoy/01-Envoy-add-response-headers/Gateway.yaml @@ -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: + - "*" \ No newline at end of file diff --git a/06-Envoy/01-Envoy-add-response-headers/README.md b/06-Envoy/01-Envoy-add-response-headers/README.md new file mode 100755 index 0000000..de589c5 --- /dev/null +++ b/06-Envoy/01-Envoy-add-response-headers/README.md @@ -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 "

.*

" +``` + +```text +

Welcome to nginx!

+``` + +### 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 \ No newline at end of file diff --git a/06-Envoy/01-Envoy-add-response-headers/Service.yaml b/06-Envoy/01-Envoy-add-response-headers/Service.yaml new file mode 100644 index 0000000..271ce25 --- /dev/null +++ b/06-Envoy/01-Envoy-add-response-headers/Service.yaml @@ -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 \ No newline at end of file diff --git a/06-Envoy/01-Envoy-add-response-headers/VirtualService.yaml b/06-Envoy/01-Envoy-add-response-headers/VirtualService.yaml new file mode 100644 index 0000000..205231b --- /dev/null +++ b/06-Envoy/01-Envoy-add-response-headers/VirtualService.yaml @@ -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: "/" \ No newline at end of file diff --git a/06-Envoy/02-envoy-logging/Deployment.yaml b/06-Envoy/02-envoy-logging/Deployment.yaml new file mode 100755 index 0000000..056a1da --- /dev/null +++ b/06-Envoy/02-envoy-logging/Deployment.yaml @@ -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 diff --git a/.placeholder/06-Envoy/01-envoy_add_headers/envoy2.yaml b/06-Envoy/02-envoy-logging/Envoy.yaml similarity index 54% rename from .placeholder/06-Envoy/01-envoy_add_headers/envoy2.yaml rename to 06-Envoy/02-envoy-logging/Envoy.yaml index 664b472..0961e7c 100755 --- a/.placeholder/06-Envoy/01-envoy_add_headers/envoy2.yaml +++ b/06-Envoy/02-envoy-logging/Envoy.yaml @@ -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 \ No newline at end of file + 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 diff --git a/06-Envoy/02-envoy-logging/Gateway.yaml b/06-Envoy/02-envoy-logging/Gateway.yaml new file mode 100755 index 0000000..bbd9d67 --- /dev/null +++ b/06-Envoy/02-envoy-logging/Gateway.yaml @@ -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: + - "*" \ No newline at end of file diff --git a/06-Envoy/02-envoy-logging/README.md b/06-Envoy/02-envoy-logging/README.md new file mode 100755 index 0000000..d7f64f4 --- /dev/null +++ b/06-Envoy/02-envoy-logging/README.md @@ -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 "

.*

" +``` + +```text +

Welcome to nginx!

+``` + +### 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 "

.*

" +``` + +```text +

Welcome to nginx!

+``` + +#### 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 `. + +```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 \ No newline at end of file diff --git a/06-Envoy/02-envoy-logging/Service.yaml b/06-Envoy/02-envoy-logging/Service.yaml new file mode 100644 index 0000000..271ce25 --- /dev/null +++ b/06-Envoy/02-envoy-logging/Service.yaml @@ -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 \ No newline at end of file diff --git a/06-Envoy/02-envoy-logging/VirtualService.yaml b/06-Envoy/02-envoy-logging/VirtualService.yaml new file mode 100644 index 0000000..205231b --- /dev/null +++ b/06-Envoy/02-envoy-logging/VirtualService.yaml @@ -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: "/" \ No newline at end of file diff --git a/06-Envoy/README.md b/06-Envoy/README.md new file mode 100755 index 0000000..6ddf0b6 --- /dev/null +++ b/06-Envoy/README.md @@ -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