From 4e0f4ba05d2374c35376eea062bc4173d9ae8aaa Mon Sep 17 00:00:00 2001 From: savagebidoof Date: Fri, 5 May 2023 01:41:42 +0200 Subject: [PATCH] 03-HTTPRewrite documented --- .../{deployment.yaml => Deployment.yaml} | 15 - .../03-HTTPRewrite/README.md | 260 +++++++++++++++++- .../03-HTTPRewrite/Service.yaml | 13 + .../03-HTTPRewrite/VirtualService.yaml | 26 ++ .../03-HTTPRewrite/gateway.yaml | 22 -- 5 files changed, 297 insertions(+), 39 deletions(-) rename 02-Traffic_management/03-HTTPRewrite/{deployment.yaml => Deployment.yaml} (63%) create mode 100644 02-Traffic_management/03-HTTPRewrite/Service.yaml create mode 100644 02-Traffic_management/03-HTTPRewrite/VirtualService.yaml diff --git a/02-Traffic_management/03-HTTPRewrite/deployment.yaml b/02-Traffic_management/03-HTTPRewrite/Deployment.yaml similarity index 63% rename from 02-Traffic_management/03-HTTPRewrite/deployment.yaml rename to 02-Traffic_management/03-HTTPRewrite/Deployment.yaml index 01dd2b0..233fd2c 100755 --- a/02-Traffic_management/03-HTTPRewrite/deployment.yaml +++ b/02-Traffic_management/03-HTTPRewrite/Deployment.yaml @@ -1,18 +1,3 @@ -# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml -apiVersion: v1 -kind: Service -metadata: - name: helloworld - labels: - app: helloworld - service: helloworld -spec: - ports: - - port: 80 - name: http - selector: - app: helloworld ---- apiVersion: apps/v1 kind: Deployment metadata: diff --git a/02-Traffic_management/03-HTTPRewrite/README.md b/02-Traffic_management/03-HTTPRewrite/README.md index 0204f98..edcfc2f 100755 --- a/02-Traffic_management/03-HTTPRewrite/README.md +++ b/02-Traffic_management/03-HTTPRewrite/README.md @@ -1,8 +1,260 @@ +--- +gitea: none +include_toc: true +--- + +# Description + +Based on the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), we configure the [VirtualService](#virtualservice) to internally rewrite the destination URL. + +This is useful, as if for example we have a rule that targets the traffic with destination path `/helloworld`, when we connect to the backend, the path that the request contains will also be `/helloworld`, and unless the destination service is already build around this and/or is ready to manage traffic with such destination, we will receive a status code 404 meaning that the page destination was not found. + +If we internally rewrite such traffic to the root directory (`/`), we can interact with the root path from the destination service without issues, without the need of specifically altering the behavior of the destination service due this architectural requirement. + +Additionally, we also configure a second rule that won't have the URL path rewrite configured, as it will allow us to compare the behaviors. + +This example configures: + + Generic Kubernetes resources: + - 1 Service + - 1 Deployments + + Istio resources: + - 1 Gateway + - 1 Virtual Service + + +# Based on + +- [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 + +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 # use istio default controller + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - "*" +``` + +## VirtualService + +The configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host. + +We configure 2 HTTP rules. + +The first rule will match when the requested path is `/helloworld`. + +Internally, we will rewrite the URL path, from `/helloworld` to `/`, as otherwise it will result in status code 404 due not containing such destination in the service, since we are using the default Nginx image. + +The second rule will math with the path `/norewrite`, and won't have the rewrite URL path setting configured. This rule will be used to compare behaviors. + + +Both rules will connect with the backend service `helloworld.default.svc.cluster.local` with port `80`. + +```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.default.svc.cluster.local + port: + number: 80 + - match: + - uri: + exact: /norewrite + route: + - destination: + host: helloworld.default.svc.cluster.local + port: + number: 80 +``` + +# Walkthrough + +## Deploy resources + +Deploy the resources. + +```shell +kubectl apply -f ./ +``` +```text +deployment.apps/helloworld-nginx created +service/helloworld created +virtualservice.networking.istio.io/helloworld-vs created +gateway.networking.istio.io/helloworld-gateway created +``` + +## Wait for the pods to be ready + +Wait for the Nginx deployment to be up and ready. + +```shell +kubectl get deployment helloworld-nginx -w +``` +```text +NAME READY UP-TO-DATE AVAILABLE AGE +helloworld-nginx 1/1 1 1 2m47s +``` + +## 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 +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h +``` + +### helloworld + +Due to rewriting the URL path internally, we are able to connect to the backend root path (`/`) + +```shell +curl 192.168.1.50/helloworld -s | grep "

.*

" +``` +```text +

Welcome to nginx!

+``` + +### norewrite + +As expected, due the backend service not having a destination path named `/norewrite`, we receive a status code 404 as well of their pertinent service error page. + +```shell +curl 192.168.1.50/helloworld -s | grep "

.*

" +``` +```text +

404 Not Found

+``` + +## Cleanup + +Finally, a cleanup from the resources deployed. + +```shell +kubectl delete -f ./ +``` +```text +deployment.apps "helloworld-nginx" deleted +service "helloworld" deleted +virtualservice.networking.istio.io "helloworld-vs" deleted +gateway.networking.istio.io "helloworld-gateway" deleted +``` + +# Links of interest + +- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPDirectResponse + +- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPBody + + + + + + + + + + + + -# Continues from -- 01-hello_world_1_service_1_deployment # There were no changes respective to that version @@ -13,6 +265,10 @@ Through rewriting the URI we can point to the root directory from nginx. uri: "/" ``` + + + + ## The idea is that this rewrite is handled "internally" by Istio, not by the Client that started the request diff --git a/02-Traffic_management/03-HTTPRewrite/Service.yaml b/02-Traffic_management/03-HTTPRewrite/Service.yaml new file mode 100644 index 0000000..271ce25 --- /dev/null +++ b/02-Traffic_management/03-HTTPRewrite/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/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml b/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml new file mode 100644 index 0000000..9155ab0 --- /dev/null +++ b/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml @@ -0,0 +1,26 @@ +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.default.svc.cluster.local + port: + number: 80 + - match: + - uri: + exact: /norewrite + route: + - destination: + host: helloworld.default.svc.cluster.local + port: + number: 80 diff --git a/02-Traffic_management/03-HTTPRewrite/gateway.yaml b/02-Traffic_management/03-HTTPRewrite/gateway.yaml index 838bef9..456e384 100755 --- a/02-Traffic_management/03-HTTPRewrite/gateway.yaml +++ b/02-Traffic_management/03-HTTPRewrite/gateway.yaml @@ -1,4 +1,3 @@ -# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: @@ -13,24 +12,3 @@ spec: 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.default.svc.cluster.local - port: - number: 80 - rewrite: - uri: "/" \ No newline at end of file