Compare commits

..

6 Commits

Author SHA1 Message Date
savagebidoof
6b0b62b6a9 04-HTTPRedirect 2023-05-05 02:32:06 +02:00
savagebidoof
113ed75177 03-HTTPRewrite documented 2023-05-05 01:42:27 +02:00
savagebidoof
f3fa2372fe Spelling correction 2023-05-05 01:41:47 +02:00
savagebidoof
4e0f4ba05d 03-HTTPRewrite documented 2023-05-05 01:41:42 +02:00
savagebidoof
b37c523c39 Spelling correction 2023-05-05 01:33:08 +02:00
savagebidoof
f52e1125a7 Spelling correction 2023-05-05 01:26:51 +02:00
17 changed files with 564 additions and 172 deletions

View File

@ -342,7 +342,7 @@ virtualservice.networking.istio.io/helloworld-vs created
## Wait for the pods to be ready
Wait for the Apache and Nginx deployments to be up and ready.
Wait for the Apache, Nginx and Whoami deployments to be up and ready.
```shell
watch -n 2 kubectl get deployment helloworld-v{0..2}

View File

@ -111,7 +111,7 @@ The configuration set, targets the [gateway created](#gateway) as well of not li
We configure 2 rules for HTTP traffic (this includes `HTTPS` and `HTTP2`, this will be my last warning about this).
The first rule configure will match when the requested path is `/helloworld`.
The first rule configured will match when the requested path is `/helloworld`.
This traffic will be forwarded to the service `helloworld.default.svc.cluster.local` with port `80`.
@ -176,9 +176,8 @@ Wait for the Apache and Nginx deployments to be up and ready.
kubectl get deployment helloworld-nginx -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-v1 1/1 1 1 4m1s
helloworld-v2 1/1 1 1 4m1s
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 9s
```
## Test the service

View File

@ -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:

View File

@ -1,52 +1,240 @@
---
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
# Continues from
# Based on
- 01-hello_world_1_service_1_deployment
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# There were no changes respective to that version
# Configuration
Through rewriting the URI we can point to the root directory from nginx.
## 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
rewrite:
uri: "/"
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## The idea is that this rewrite is handled "internally" by Istio, not by the Client that started the request
## Practical usages:
If we refactor our application, and for example we previously where hosting an API to the URL `/apiV1` and now it's being hosted in `/api/V1`, we can do the following rule:
## 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: /apiV1
exact: /helloworld
route:
- destination:
host: mynewapi # the service destination/target
host: helloworld.default.svc.cluster.local
port:
number: 80 # whatever port it is
rewrite:
uri: "/api/V1"
```
Or if we "upgraded" the API, and the new API (v2) is retro-compatible with the old API (v1), we could do the following to force all the usages from the old API to be handled by the newer version:
```yaml
number: 80
- match:
- uri:
exact: /api/V1
exact: /norewrite
route:
- destination:
host: mynewapi # the service destination/target
host: helloworld.default.svc.cluster.local
port:
number: 80 # whatever port it is
rewrite:
uri: "/api/V2"
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 "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
### 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 "<h1>.*</h1>"
```
```text
<center><h1>404 Not Found</h1></center>
```
## 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/#HTTPRewrite

View 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

View File

@ -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

View File

@ -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: "/"

View 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:
- "*"

View File

@ -1,3 +1,257 @@
---
gitea: none
include_toc: true
---
# Description
Based on the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), we create multiple rules in the [VirtualService](#virtualservice) that will make usage of the `redirect` field to modify the request received and redirect the incoming request towards a new destination.
This example configures:
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
## 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 3 HTTP rules.
- to_https
A practical example regarding modifying protocol used from the incoming traffic request.
It will set the protocol used to `HTTPS`.
> **Note:**\
> Bear in mind that this example is not planned to be used `as it is` on production environments as other configurations should be applied, as an example you should target a specific source port.
- wikipedia
We are using the regex query `/wiki/?` to match the URL path, this rule allows us to target both `/wiki` and `/wiki/`.
On this example we will redirect the traffic that accesses to this rule towards the Wikipedia page, as well the protocol will be modified and set to `HTTPS`.
- wikipedia_search
Very similar to the previous rule, we will match the traffic that, as a prefix of the URl used, as long it starts by `/wiki/`.
More information about the behavior of ties rule will be seen in the [Walkthrough](#walkthrough) section.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: to_https
match:
- uri:
exact: /https
redirect:
scheme: "https"
- name: wikipedia
match:
- uri:
regex: "/wiki/?"
redirect:
uri: "/"
scheme: "https"
authority: "en.wikipedia.org"
- name: wikipedia_search
match:
- uri:
prefix: "/wiki/"
redirect:
scheme: "https"
authority: "en.wikipedia.org"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the rules
### 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
```
### to_https
We are receiving the status code `301` as the request is being modified.
By default `curl` won't follow the redirects.
```shell
curl 192.168.1.50/https -I
```
```text
HTTP/1.1 301 Moved Permanently
location: https://192.168.1.50/https
date: Fri, 05 May 2023 00:15:41 GMT
server: istio-envoy
transfer-encoding: chunked
```
The flag `-L` can be used to allow `curl` to follow redirects, as well of `-v` to increase the verbosity to review the behavior.
From the output received, we can see how the request initially points towards the port `80`.
After receiving the status code `301`, we can see the following line `Clear auth, redirects to port from 80 to 443`, stating that there was a redirect that changed the destination port, from `80`, to `443`.
As well, there is the line `Issue another request to this URL: 'https://192.168.1.50/https'`, which confirms that the protocol used, which previously was using `HTTP`, now is using `HTTPS`.
This proves that the configuration set is currently being applied and works as intended.
```shell
curl 192.168.1.50/https -L -v
```
```text
* Trying 192.168.1.50:80...
* Connected to 192.168.1.50 (192.168.1.50) port 80 (#0)
> GET /https HTTP/1.1
> Host: 192.168.1.50
> User-Agent: curl/8.0.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< location: https://192.168.1.50/https
< date: Fri, 05 May 2023 00:17:12 GMT
< server: istio-envoy
< content-length: 0
<
* Connection #0 to host 192.168.1.50 left intact
* Clear auth, redirects to port from 80 to 443
* Issue another request to this URL: 'https://192.168.1.50/https'
* Trying 192.168.1.50:443...
* connect to 192.168.1.50 port 443 failed: Connection refused
* Failed to connect to 192.168.1.50 port 443 after 0 ms: Couldn't connect to server
* Closing connection 1
curl: (7) Failed to connect to 192.168.1.50 port 443 after 0 ms: Couldn't connect to server
```
### /wiki/
On this example I will be using the Firefox browser to access the destination path `/wiki/`.
Which on accessing the path, it modified the request and forwarded the traffic towards the path `https://en.wikipedia.org/wiki`.
After accessing such destination, Wikipedia will forward you to the path `/wiki/Main_Page`, as we didn't target any specific element from the wiki.
```shell
firefox 192.168.1.50/wiki/
```
![img.png](src/img.png)
### /wiki/*
On this example I will be using the Firefox browser to access the destination path `/wiki/Istio` and `/wiki/Gitea`.
This will forward us towards the pertinent wiki service, as meanwhile the domain is modified, the path remains the same, allowing us to match the right destination paths.
```shell
firefox 192.168.1.50/wiki/Service_mesh
```
![img_1.png](src/img_1.png)
```shell
firefox 192.168.1.50/wiki/Gitea
```
![img_2.png](src/img_2.png)
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect
# Continues from

View File

@ -0,0 +1,33 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: to_https
match:
- uri:
exact: /https
redirect:
scheme: "https"
- name: wikipedia
match:
- uri:
regex: "/wiki/?"
redirect:
uri: "/"
scheme: "https"
authority: "en.wikipedia.org"
- name: wikipedia_search
match:
- uri:
prefix: "/wiki/"
redirect:
scheme: "https"
authority: "en.wikipedia.org"

View File

@ -1,40 +0,0 @@
# 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:
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

View File

@ -1,58 +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.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
- name: to_https
match:
- uri:
exact: /https
scheme: http
redirect:
scheme: "https"
- name: wikipedia
match:
- uri:
exact: "/wiki"
redirect:
uri: "/"
scheme: "https"
authority: "en.wikipedia.org"
- name: wikipedia_search
match:
- uri:
prefix: "/wiki/"
redirect:
scheme: "https"
authority: "en.wikipedia.org"

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -6,7 +6,7 @@ include_toc: true
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Description
@ -108,7 +108,7 @@ Thank you for installing Istio 1.17. Please take a few minutes to tell us about
### Deploy gateway
```shell
kubectl apply -f gateway.yaml
kubectl apply -f Gateway.yaml
```
```text
@ -162,7 +162,7 @@ x-envoy-upstream-service-time: 15
```shell
kubectl delete -f ./deployment-nomtls.yaml
kubectl delete -f ./gateway.yaml
kubectl delete -f ./Gateway.yaml
```
```text
service "helloworld" deleted