Merge pull request '15/May/2023' (#62) from dev into main

Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/62
This commit is contained in:
ofilter 2023-05-15 13:33:16 +00:00
commit fe4cfa88a6
145 changed files with 2689 additions and 615 deletions

54
.placeholder/text.md Normal file
View File

@ -0,0 +1,54 @@
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect
## The idea is that this rewrite is handled "externally" by the client, not by Istio.
## Practical examples
### HTTP to HTTPS redirect.
The following Virtual Service configuration will redirect all the incoming traffic from the gateway `my-gateway` that uses the http protocol, to the https protocol.
In this example, it would forward all the `http` traffic without taking into account which port is used.
```
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: to-https-vs
spec:
hosts:
- "*"
gateways:
- my-gateway
http:
- match:
- name: to_https
match:
scheme: http
redirect:
scheme: https
```
### Migrated from a domain
The following will update the requests coming "to" the domain `old.domain.com` and rewrite the URL to use the "new" `new.domain.com`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: update-domain-vs
spec:
hosts:
- "old.domain.com"
gateways:
- helloworld-gateway
http:
- name: forward-to-new-domain
redirect:
authority: "new.domain.com"
```

View File

@ -78,6 +78,26 @@ listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
kubectl logs -n istio-system -f deployments/istiod
```
## Istio-Proxy Pod
This will display the logs from a deployment while targeting the `istio-proxy` container from the targeted pod/deployment.
As well will attach the session to stream new logs. (`-f` `--follow`)
```shell
kubectl logs deployments/helloworld-default -f -c istio-proxy
```
```text
[2023-05-15T00:42:03.699Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.111.90.232:8080 172.17.121.65:52006 - -
[2023-05-15T00:42:24.785Z] "HEAD / HTTP/1.1" 200 - via_upstream - "-" 0 0 2 1 "-" "curl/7.74.0" "c133cbf0-b57d-4fba-8f84-d683ab903399" "helloworld.default.svc.cluster.local" "172.17.121.65:80" inbound|80|| 127.0.0.6:51695 172.17.121.65:80 172.17.121.65:43786 outbound_.80_._.helloworld.default.svc.cluster.local default
[2023-05-15T00:42:24.784Z] "HEAD / HTTP/1.1" 200 - via_upstream - "-" 0 0 5 4 "-" "curl/7.74.0" "c133cbf0-b57d-4fba-8f84-d683ab903399" "helloworld.default.svc.cluster.local" "172.17.121.65:80" outbound|80||helloworld.default.svc.cluster.local 172.17.121.65:43786 10.111.90.232:80 172.17.121.65:57030 - default
[2023-05-15T00:43:23.209Z] "HEAD / HTTP/1.1" 200 - via_upstream - "-" 0 0 6 5 "-" "curl/7.74.0" "e1f0a2f3-93ff-4c41-8cb3-6d3a53fce065" "helloworld.foo.svc.cluster.local" "172.17.247.42:80" outbound|80||helloworld.foo.svc.cluster.local 172.17.121.65:55040 10.109.248.148:80 172.17.121.65:60520 - default
[2023-05-15T00:43:29.751Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.109.248.148:8080 172.17.121.65:40370 - -
[2023-05-15T00:43:31.979Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.109.248.148:8080 172.17.121.65:40402 - -
```
## Ingress
The service targeted, `istio-ingressgateway`, is an Ingress Load Balancer service from Istio.
@ -177,4 +197,8 @@ InboundPassthroughClusterIpv4 - -
PassthroughCluster - - - ORIGINAL_DST
agent - - - STATIC
...
```
```
# Other links
## [Debugging with Istio](https://www.istioworkshop.io/12-debugging/01-istioctl-debug-command/)

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,17 +1,3 @@
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,61 +1,255 @@
---
gitea: none
include_toc: true
---
# Description
# Continues from
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.
- 01-hello_world_1_service_1_deployment
This example configures:
Istio resources:
- 1 Gateway
- 1 Virtual Service
# Based on
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
## The idea is that this rewrite is handled "externally" by the client, not by Istio.
# Configuration
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
## Practical examples
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.
### HTTP to HTTPS redirect.
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.
The following Virtual Service configuration will redirect all the incoming traffic from the gateway `my-gateway` that uses the http protocol, to the https protocol.
In this example, it would forward all the `http` traffic without taking into account which port is used.
```
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
kind: Gateway
metadata:
name: to-https-vs
name: helloworld-gateway
spec:
hosts:
- "*"
gateways:
- my-gateway
http:
- match:
- name: to_https
match:
scheme: http
redirect:
scheme: https
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
### Migrated from a domain
## VirtualService
The following will update the requests coming "to" the domain `old.domain.com` and rewrite the URL to use the "new" `new.domain.com`
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: update-domain-vs
name: helloworld-vs
spec:
hosts:
- "old.domain.com"
- "*"
gateways:
- helloworld-gateway
http:
- name: forward-to-new-domain
- name: to_https
match:
- uri:
exact: /https
redirect:
authority: "new.domain.com"
```
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

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

@ -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,55 +0,0 @@
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:
- name: https-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: "github.com"
port:
number: 8443
rewrite:
uri: "/OriolFilter/"
headers:
request:
set:
HOST: "github.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: github.com
namespace: default
spec:
host: github.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE

View File

@ -1,23 +1 @@
# Examples
(almost) ALL NEEDS DOCUMENTATION / REVIEW
- 01-2_deployments_method
- 02-DirectResponse-HTTP-Body
- 03-HTTPRewrite
- 04-HTTPRedirect
- 05a-FaultInjection-delay
- 05b-FaultInjection-abort
- 06-mTLS (would need some documentation review, mainly go over the differences respective to the template/prior configuration used)
- 07-HTTPS-Gateway-Simple-TLS <- Doesn't respect the changelog format.
- 08a-HTTPS-min-TLS-version
- 08b-HTTPS-max-TLS-version
- 09-HTTPS-backend
- 10-TCP-FORWARDING
- 11-TLS-PASSTHROUGH
- 12-HTTP-to-HTTPS-traffic-redirect -> Documented.
This will need some reorganization.
This gloves the resources `Virtual Service` and `Destination Rule`

View File

@ -1,17 +1,3 @@
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

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "my.domain"

View File

@ -0,0 +1,238 @@
---
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), and restricts the access to the gateway based on the domain host from the destination URL.
The domain host targeted will be `my.domain`.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 1 Deployment
Istio resources:
- 1 Gateway
- 1 Virtual Service
> **Note:**\
> I don't intend to explain thing related to Kubernetes unless necessary.
# 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.
The gateway only will allow the traffic that uses as a URL host: `my.domain`.
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:
- "my.domain"
```
## 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: "/"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the deployment 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 44s
```
## 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
```
### Curl /helloworld
When performing a curl towards the destination path, as we are not using the domain host specified in the [gateway resource](#gateway), we are failing to match any rule.
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 404 Not Found
date: Wed, 10 May 2023 08:25:26 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl my.domain/helloworld
We can "fake" the destination domain by modifying the `Host` header.
After setting that up, and attempting to curl the destination, we receive a positive response from the Nginx backend.
```shell
curl 192.168.1.50/helloworld -s -HHOST:my.domain | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-nginx" 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/gateway/

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

@ -1,22 +1,4 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: foo

View File

@ -1,17 +1,3 @@
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

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-b
protocol: HTTP
hosts:
- "foo/*"

View File

@ -0,0 +1,294 @@
---
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), and restrict which `VirtualService` Istio resources can access/select the `Gateway` Istio resource, based on the `VirtualService` namespace.
The domain host targeted will be `my.domain`.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 1 Deployment
- 1 Namespace
Istio resources (`default` namespace):
- 1 Gateway
- Virtual Service
Istio resources (`foo`namespace):
- 1 Virtual Service
> **Note:**\
> I don't intend to explain thing related to Kubernetes unless necessary.
# 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
```
## Namespace
Creates a namespace named `foo`.
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: foo
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
The gateway won't target any specific host domain, yet limits the `VirtualService` Istio resources that can target this gateway, limiting its access to the `VirtualServices` Istio resources created in the `foo` namespace.
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-b
protocol: HTTP
hosts:
- "foo/*"
```
## VirtualService
We will create two `VirtualServices` with the same configuration, only difference will be the namespace they are created onto (and the destination path), this will be used to test if the [`Gateway` namespace restriction configured](#gateway) is being applied to the `VirtualService` resources as desired.
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.
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).
## helloworld-foo
`VirtualService` created in the namespace `foo`.
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.default.svc.cluster.local`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-foo
namespace: foo
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
```
## helloworld-default
`VirtualService` created in the namespace `default`.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/failure`.
This traffic will be forwarded to the port `80` of the destination service `helloworld.default.svc.cluster.local`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-default
namespace: default
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /failure
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
namespace/foo created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-foo created
virtualservice.networking.istio.io/helloworld-default created
```
## Wait for the deployment 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 44s
```
## 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
```
### Curl /helloworld
When performing a curl towards the destination path, as we are not using the domain host specified in the [gateway resource](#gateway), we are failing to match any rule.
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 404 Not Found
date: Wed, 10 May 2023 08:25:26 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl my.domain/helloworld
We can "fake" the destination domain by modifying the `Host` header.
After setting that up, and attempting to curl the destination, we receive a positive response from the Nginx backend.
```shell
curl 192.168.1.50/helloworld -s -HHOST:my.domain | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
namespace "foo" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-foo" deleted
virtualservice.networking.istio.io "helloworld-default" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/gateway/

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,43 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-foo
namespace: foo
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-default
namespace: default
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /failure
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"

View File

@ -1,17 +1,3 @@
## https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
ports:
- port: 8080
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -0,0 +1,17 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret

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

View File

@ -0,0 +1,25 @@
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

@ -16,24 +16,3 @@ spec:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_3
---
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: "/"

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

View File

@ -0,0 +1,25 @@
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

@ -16,24 +16,3 @@ spec:
mode: SIMPLE
credentialName: my-tls-cert-secret
maxProtocolVersion: TLSV1_2
---
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: "/"

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

View File

View File

@ -1,172 +0,0 @@
# Continues from
- 01-hello_world_1_service_1_deployment
# TO TRAFFIC PATH DIAGRAM
`etc -> "POD" -> sidecar -> service container`
# Description
This example configures the sidecar proxy on the pods created, to forward the traffic incoming from the port `8080` to the port `80`
## Files
- deployment.yaml
- gateway.yaml
- sidecar.yaml
> Added the `sidecar.yaml` file.
## deployment.yaml
### Creates
#### Service
- helloworld
#### Deployments
- helloworld-nginx (Nginx container)
## gateway.yaml
### Creates
#### Gateway
##### helloworld-gateway
###### Configuration
```yml
...
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
#### VirtualService
##### helloworld-vs
###### Configuration
```yaml
...
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
```
- On this example, we are using the port `8080` as a destination.
## sidecar.yaml
### creates
#### sidecar
##### helloworld-sidecar
###### Configuration
```yaml
...
spec:
workloadSelector:
labels:
app: helloworld
ingress:
- port:
number: 8080
protocol: HTTP
name: ingressport
defaultEndpoint: 127.0.0.1:80
````
workloadSelector:
> `workloadSelector` is used to target the `PODS`, on which apply this sidecar configuration. \
> Bear in mind that this configuration doesn't target kinds `Service`, nor `Deployment`, it's applied to a kind `Pod` or `ServiceEntry` \
> If there is no `workloadSelector` specified, it will be used as default configuration for the namespace on which was created. \
> More info in the [Istio documentation for workloadSelector](https://istio.io/latest/docs/reference/config/networking/sidecar/#WorkloadSelector)
ingress:
> Configure the behavior of the ingress traffic.\
> On this "grabs"/targets the ingress traffic with port 8080, and forwards it to the port IP `127.0.0.1` (loopback) respective to the destination pod, with the destination port set to 80, which is the port that the service is currently listening to.
# Run example
## Deploy resources
```shell
$ kubectl apply -f ./
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
sidecar.networking.istio.io/helloworld-sidecar created
```
## Wait for the pods to be ready
```shell
$ kubectl get deployment helloworld-nginx -w
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 39s
```
## Test the service
### Get LB IP
```shell
$ kubectl get svc istio-ingressgateway -n istio-system
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
```
### Curl
```shell
$ curl 192.168.1.50/helloworld -s | grep "<title>.*</title>"
<title>Welcome to nginx!</title>
```
### Delete the sidecar configuration to force failure.
```shell
$ kubectl delete sidecars.networking.istio.io helloworld-sidecar
sidecar.networking.istio.io "helloworld-sidecar" deleted
```
### Curl again
```shell
$ curl 192.168.1.50/helloworld -s
upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: delayed connect error: 111
```

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,19 +1,4 @@
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

View File

@ -5,7 +5,7 @@ include_toc: true
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
- [08a-HTTPS-min-TLS-version](../../03-Gateway_Ingress/08a-HTTPS-min-TLS-version)
# Description
@ -197,7 +197,7 @@ spec:
```
> **Note**:\
> As this configuration is very board, and targets the whole namespace, I would strongly recommend referring to the following example [06-Internal-Authentication/02-target-service-accounts](../../06-AuthorizationPolicy/02-target-service-accounts), which shows how to target service accounts set to resources, limiting the scope of this rule set.
> As this configuration is very board, and targets the whole namespace, I would strongly recommend referring to the following example [06-Internal-Authentication/02-target-service-accounts](../../08-AuthorizationPolicy/02-target-service-accounts), which shows how to target service accounts set to resources, limiting the scope of this rule set.
# Walkthrough

0
04-Backends/README.md Normal file
View File

View File

@ -0,0 +1,25 @@
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

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

@ -0,0 +1,289 @@
---
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), configures the **sidecar** `envoy-proxy`/`istio-proxy`/`sidecar-proxy` on the pods created, to forward the traffic incoming from the port `8080` to the port `80`.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 1 Deployment
Istio resources:
- 1 Gateway
- 1 Virtual Service
- 1 Sidecar configration
# 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 `8080` expecting `HTTP` traffic and will forward the incoming traffic towards the port `8080` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
ports:
- port: 8080
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
We can notice how in the service we opened the port `8080` and in the deployment we are listening to the port `80`, more about this in the [Sidecar Section](#sidecar).
```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 when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `8080` 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: "/"
```
## Sidecar
This will configure the sidecar configuration from the `envoy-proxy` in each pod.
`workloadSelector` will be used to select the target pods, where, on this scenario, it will target the pods that have the label set `app: helloworld`.
The ingress configuration set, will listen for the port `8080` from the pod, and forward it to the pod's port `80` through the loopback (127.0.0.1) IP.
On this scenario we are performing a simple `8080` to `80` redirect.
> **Note:**\
> A reminder that a `POD` is an object that groups container(s).
+ more notes:
- workloadSelector:
> `workloadSelector` is used to target the `PODS`, on which apply this sidecar configuration. \
> Bear in mind that this configuration doesn't target kinds `Service`, nor `Deployment`, it's applied to a kind `Pod` or `ServiceEntry` \
> If there is no `workloadSelector` specified, it will be used as default configuration for the namespace on which was created. \
> More info in the [Istio documentation for workloadSelector](https://istio.io/latest/docs/reference/config/networking/sidecar/#WorkloadSelector)
- ingress:
> Configure the behavior of the ingress traffic.\
> On this "grabs"/targets the ingress traffic with port 8080, and forwards it to the port IP `127.0.0.1` (loopback) respective to the destination pod, with the destination port set to 80, which is the port that the service is currently listening to.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar
spec:
workloadSelector:
labels:
app: helloworld
ingress:
- port:
number: 8080
protocol: HTTP
name: ingressport
defaultEndpoint: 127.0.0.1:80
```
# Run example
## Deploy resources
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
sidecar.networking.istio.io/helloworld-sidecar created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the pods to be ready
```shell
kubectl get deployment helloworld-nginx -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 39s
```
## 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
```
### Curl
We can perform a curl towards the destination.
A reminder that the configuration set in the [service](#service) created, it's listening to the port `8080` and forwarding the traffic to the same pod (`8080`).
As well on the Istio's [VirtualService](#virtualservice), we configured the destination port as `8080`.
Yet, on the [Sidecar](#sidecar) configuration, we are redirecting the ingress traffic from the port `8080`, to the port `80`.
```shell
curl 192.168.1.50/helloworld -s | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
### Delete the sidecar configuration to force failure.
As per the moment let's delete the `sidecar` configuration deployed.
```shell
kubectl delete sidecars.networking.istio.io helloworld-sidecar
```
```text
sidecar.networking.istio.io "helloworld-sidecar" deleted
```
### Curl again
After deleting the `sidecar` configuration, which was handling the ingress traffic from port `8080`, we can observe that we are no longer able to handle the incoming requests, raising an error message.
```shell
curl 192.168.1.50/helloworld -s
```
```text
upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: delayed connect error: 111
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
Error from server (NotFound): error when deleting "Sidecar.yaml": sidecars.networking.istio.io "helloworld-sidecar" not found
```

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
ports:
- port: 8080
name: http
selector:
app: helloworld

View File

@ -1,19 +1,4 @@
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

View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: foo
labels:
istio-injection: "enabled"

View File

@ -1,24 +1,10 @@
# 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
name: helloworld-default
labels:
app: helloworld
namespace: default
spec:
replicas: 1
selector:
@ -38,3 +24,30 @@ spec:
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-foo
labels:
app: helloworld
namespace: foo
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

@ -0,0 +1,738 @@
---
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), configures the **sidecar** `envoy-proxy`/`istio-proxy`/`sidecar-proxy` on the pods created, to limit the egress resources to which the `istio-proxy`, who proxies the traffic from the pod (both ingress and egress), can send request to.
This will be done through 2 principles: <FILL>
This example configures:
Generic Kubernetes resources:
- 2 Services
- 2 Deployments
- 1 Namespace
Istio resources:
- 2 Sidecar configrations
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Configuration
## Namespace
Creates a namespace named `foo` with the `istio-proxy` injection enabled.
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: foo
labels:
istio-injection: "enabled"
```
## Service
### hellowolrd (default/foo namespace)
Creates two services named `helloworld`, one in the namespace `default`, and another in the namespace `foo`.
This service listens for the port `8080` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
Also 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
namespace: foo
spec:
ports:
- port: 8080
name: http-a
targetPort: 80
- port: 80
name: http-b
targetPort: 80
selector:
app: helloworld
---
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
namespace: default
spec:
ports:
- port: 8080
name: http-a
targetPort: 80
- port: 80
name: http-b
targetPort: 80
selector:
app: helloworld
```
## Deployment
Creates two deployments named `helloworld`, one in the namespace `default`, and another in the namespace `foo`
### helloworld-default
Contains a Nginx server that listens for the port `80`.
It's created in the namespace `default`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-default
labels:
app: helloworld
namespace: default
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
```
### helloworld-foo
Contains a Nginx server that listens for the port `80`.
It's created in the namespace `foo`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-foo
labels:
app: helloworld
namespace: foo
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
```
## Sidecar
This will configure the sidecar configuration from the `envoy-proxy` in each pod.
`workloadSelector` will be used to select the target pods, where, on this scenario, it will target the pods that have the label set `app: helloworld`.
> **Note:**\
> A reminder that a `POD` is an object that groups container(s).
+ more notes:
- workloadSelector:
> `workloadSelector` is used to target the `PODS`, on which apply this sidecar configuration. \
> Bear in mind that this configuration doesn't target kinds `Service`, nor `Deployment`, it's applied to a kind `Pod` or `ServiceEntry` \
> If there is no `workloadSelector` specified, it will be used as default configuration for the namespace on which was created. \
> More info in the [Istio documentation for workloadSelector](https://istio.io/latest/docs/reference/config/networking/sidecar/#WorkloadSelector)
- egress:
> Configure the behavior of the proxied egress traffic.\
> On this example, we limit port that the `sidecar-proxy` will be allowed to send traffic to, as well limiting the routes that can the `sidecar-proxy` container will be able to learn the routes from.\
> A reminder that Istio automatically creates routes for each one of the services and each one of the ports configured to be exposed.\
> More info in the [Istio documentation for IstioEgressListener](https://istio.io/latest/docs/reference/config/networking/sidecar/#IstioEgressListener)
- outboundTrafficPolicy.mode:
> The most important step from this configuration.\
> By setting the value to `REGISTRY_ONLY`, it will restrict the egress connectivity towards the destinations defined in the registry as well of the defined `ServiceEntry` configurations.
> Taking into account that the field `egress`, where we limited the routes that the `sidecar-proxy` would be allowed to learn routes from, combined with this setting set to `REGISTRY_ONLY`, we limit the egress reachability from the PODS.\
> If the setting is set to `ALLOW_ANY`, the egress limitation will be ignored.
> More info in the [Istio documentation for OutboundTrafficPolicy.Mode](https://istio.io/latest/docs/reference/config/networking/sidecar/#OutboundTrafficPolicy-Mode)
### helloworld-sidecar-default
On this example we target the Deployments from the namespace `default` that contain a label named `app` with the contents set to `helloworld`.
We limit the egress to the port `80`, and will only be able to reach out to the learned destinations from the namespaces `foo`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar-default
namespace: default
spec:
workloadSelector:
labels:
app: helloworld
egress:
- port:
number: 80
protocol: HTTP
name: egress-http
hosts:
- "foo/*"
outboundTrafficPolicy:
mode: REGISTRY_ONLY
```
### helloworld-sidecar-foo
On this example we target the Deployments from the namespace `foo` that contain a label named `app` with the contents set to `helloworld`.
We limit the egress to the port `8080`, and will only be able to reach out to the learned destinations from the namespaces `default`, and it's own (`./*`) aka. `foo`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar-foo
namespace: foo
spec:
workloadSelector:
labels:
app: helloworld
egress:
- port:
number: 8080
protocol: HTTP
name: egress-default
hosts:
- "./*"
- "default/*"
outboundTrafficPolicy:
mode: REGISTRY_ONLY
```
# Run example
## Deploy resources
```shell
kubectl apply -f ./
```
```text
namespace/foo created
deployment.apps/helloworld-default created
deployment.apps/helloworld-foo created
service/helloworld created
service/helloworld created
sidecar.networking.istio.io/helloworld-sidecar-default created
sidecar.networking.istio.io/helloworld-sidecar-foo created
```
## Wait for the pods to be ready
```shell
watch -n 5 "kubectl get deployment -A | grep helloworld"
```
```text
default helloworld-default 1/1 1 1 10s
foo helloworld-foo 1/1 1 1 10s
```
## Test the service
### from `helloworld-default`
Reminder of the **egress** criteria that has been configured to be met:
[ ] Port `80`.
[ ] `HTTP` protocol.
[ ] Namespace destination `foo`.
#### Curl helloworld.foo.svc.cluster.local:80
On this scenario we meet the following criteria:
[x] Port `80`.
[x] `HTTP` protocol.
[x] Namespace destination `foo`.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:80 -sI
```
```text
HTTP/1.1 200 OK
server: envoy
date: Mon, 15 May 2023 11:49:34 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 10
```
#### Curl helloworld.foo.svc.cluster.local:8080
[ ] Port `80`.
[x] `HTTP` protocol.
[x] Namespace destination `foo`.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:8080 -sI
```
```text
command terminated with exit code 56
```
##### What's happening?
Let's observe the logs activity from the `istio-proxy` container, of the deployment `helloworld` in the namespace `default` when we send request towards the service `helloworld` in the namespace `foo` through the port `8080`.
```shell
NAMESPACE="default" && kubectl logs -l app=helloworld --follow -c istio-proxy -n $NAMESPACE --tail 0
```
From another `shell` send a request towards the destination.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:8080 -sI
```
We can see, how the `istio-proxy` container, from the `helloworld` POD, in the namespace `default`, generates the following log entry:
```text
[2023-05-15T12:19:03.577Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.107.249.242:8080 172.17.247.52:58820 - -
```
On the log generated, it specifies the word `BlackHoleCluster`.
`BlackHoleCluster` is an Istio resource/destination used to block requests, meaning that our request was forwarded to it, preventing us to reach to the desired destination, as per configured in the [sidecar configuration](#sidecar).
I understand that this behavior is caused due that the namespace `foo` is an external location respective to the deployment, and for such it requires `istio-proxy` to learn its destination, whereas in this scenario, due [sidecar configuration](#sidecar), doesn't figure either in the list of accepted routes.
For such, instead the is sent towards `BlackHoleCluster`.
#### Curl helloworld.default.svc.cluster.local:80
[x] Port `80`.
[x] `HTTP` protocol.
[ ] Namespace destination `foo`.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:80 -sI
```
```text
HTTP/1.1 502 Bad Gateway
date: Mon, 15 May 2023 12:23:12 GMT
server: envoy
transfer-encoding: chunked
```
##### What's happening?
Let's observe the logs activity from the `istio-proxy` container, of the deployment `helloworld` in the namespace `default` when we send request towards the service `helloworld` in the namespace `default` through the port `80`.
```shell
NAMESPACE="default" && kubectl logs -l app=helloworld --follow -c istio-proxy -n $NAMESPACE --tail 0
```
From another `shell` send a request towards the destination.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:80 -sI
```
We can see, how the `istio-proxy` container, from the `helloworld` POD, in the namespace `default`, generates the following log entry:
```text
[2023-05-15T12:24:40.757Z] "HEAD / HTTP/1.1" 502 - direct_response - "-" 0 0 0 - "-" "curl/7.74.0" "952652df-7761-4f15-be58-776eeedfb6cf" "helloworld.default.svc.cluster.local" "-" - - 10.108.186.1:80 172.17.247.52:57516 - block_all
```
On the log generated, we can observe further information than the previous one, nevertheless I want to put emphasis on the following sections:
- `502 - direct_response`
This means that the status code `502` was a `direct response`, coming from istio itself, directly targeting this request.
- `block_all`
Istio already acknowledges this request and flags is as doesn't meet the requirements configured in the [sidecar configuration](#sidecar).
I understand that this behavior is different from when sending a request to `foo` on the port `8080`, in the current configuration set, we didn't specify any egress setting that allow any kind of egress towards the port `80`.
For such it raises a `direct response` with status code `502`, as the `istio-proxy` strictly won't accept any egress request with that port.
#### Curl helloworld.default.svc.cluster.local:8080
[x] Port `8080`.
[x] `HTTP` protocol.
[ ] Namespace destination `foo`.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:8080 -sI
```
```text
command terminated with exit code 56
```
##### What's happening?
Let's observe the logs activity from the `istio-proxy` container, of the deployment `helloworld` in the namespace `default` when we send request towards the service `helloworld` in the namespace `default` through the port `8080`.
```shell
NAMESPACE="default" && kubectl logs -l app=helloworld --follow -c istio-proxy -n $NAMESPACE --tail 0
```
From another `shell` send a request towards the destination.
```shell
NAMESPACE="default" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:8080 -sI
```
We can see, how the `istio-proxy` container, from the `helloworld` POD, in the namespace `default`, generates the following log entry:
```text
[2023-05-15T12:48:31.605Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.108.186.1:8080 172.17.247.52:53742 - -
```
`BlackHoleCluster` resembles the same behavior as on the section [Curl helloworld.foo.svc.cluster.local:8080](#curl-helloworldfoosvcclusterlocal--8080).
### from `helloworld-foo`
Reminder of the **egress** criteria that has been configured to be met:
[ ] Port `8080`.
[ ] `HTTP` protocol.
[ ] Namespace destination `foo` or `default`.
#### Curl helloworld.foo.svc.cluster.local:80
On this scenario we meet the following criteria:
[ ] Port `8080`.
[x] `HTTP` protocol.
[x] Namespace destination `foo` or `default`.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:80 -sI
```
```text
command terminated with exit code 56
```
##### What's happening?
Let's observe the logs activity from the `istio-proxy` container, of the deployment `helloworld` in the namespace `foo` when we send request towards the service `helloworld` in the namespace `foo` through the port `80`.
```shell
NAMESPACE="foo" && kubectl logs -l app=helloworld --follow -c istio-proxy -n $NAMESPACE --tail 0
```
From another `shell` send a request towards the destination.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:80 -sI
```
We can see, how the `istio-proxy` container, from the `helloworld` POD, in the namespace `foo`, generates the following log entry:
```text
[2023-05-15T12:56:49.064Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.107.249.242:80 172.17.121.93:57680 - -
```
`BlackHoleCluster` resembles the same behavior as on the section [Curl helloworld.foo.svc.cluster.local:8080](#curl-helloworldfoosvcclusterlocal--8080).
#### Curl helloworld.foo.svc.cluster.local:8080
On this scenario we meet the following criteria:
[x] Port `8080`.
[x] `HTTP` protocol.
[x] Namespace destination `foo` or `default`.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.foo.svc.cluster.local:8080 -sI
```
```text
HTTP/1.1 200 OK
server: envoy
date: Mon, 15 May 2023 12:57:58 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 77
```
#### Curl helloworld.default.svc.cluster.local:80
On this scenario we meet the following criteria:
[ ] Port `8080`.
[x] `HTTP` protocol.
[x] Namespace destination `foo` or `default`.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:80 -sI
```
```text
command terminated with exit code 56
```
##### What's happening?
Let's observe the logs activity from the `istio-proxy` container, of the deployment `helloworld` in the namespace `foo` when we send request towards the service `helloworld` in the namespace `default` through the port `80`.
```shell
NAMESPACE="foo" && kubectl logs -l app=helloworld --follow -c istio-proxy -n $NAMESPACE --tail 0
```
From another `shell` send a request towards the destination.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:80 -sI
```
We can see, how the `istio-proxy` container, from the `helloworld` POD, in the namespace `foo`, generates the following log entry:
```text
[2023-05-15T13:03:50.935Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 10.108.186.1:80 172.17.121.93:43342 - -
```
`BlackHoleCluster` resembles the same behavior as on the section [Curl helloworld.foo.svc.cluster.local:8080](#curl-helloworldfoosvcclusterlocal--8080).
#### Curl helloworld.default.svc.cluster.local:8080
On this scenario we meet the following criteria:
[x] Port `8080`.
[x] `HTTP` protocol.
[x] Namespace destination `foo` or `default`.
```shell
NAMESPACE="foo" && kubectl exec -n ${NAMESPACE} "$(kubectl get pod -n ${NAMESPACE} -l app=helloworld -o jsonpath={.items..metadata.name})" -- curl helloworld.default.svc.cluster.local:8080 -sI
```
```text
HTTP/1.1 200 OK
server: envoy
date: Mon, 15 May 2023 13:07:49 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 67
```
## BlackHoleCluster?
Let's check the learned routes from each deployment.
### helloworld-default
```shell
NAMESPACE="default" && istioctl proxy-config clusters -n $NAMESPACE "$(kubectl get pods -n ${NAMESPACE} -l app=helloworld | tail -n 1 | awk '{ print $1 }')"
```
```text
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
80 - inbound ORIGINAL_DST
BlackHoleCluster - - - STATIC
InboundPassthroughClusterIpv4 - - - ORIGINAL_DST
PassthroughCluster - - - ORIGINAL_DST
agent - - - STATIC
helloworld.foo.svc.cluster.local 80 - outbound EDS
prometheus_stats - - - STATIC
sds-grpc - - - STATIC
xds-grpc - - - STATIC
zipkin - - - STRICT_DNS
```
We can observe the following entries:
- `BlackHoleCluster - - - STATIC`
and
- `helloworld.foo.svc.cluster.local 80 - outbound EDS`
Where `BlackHoleCluster` is a static destination without port attributed nor direction set, and is the route used to send the traffic to the `void`.
As well, we can find the route `helloworld.foo.svc.cluster.local` that specifies the port `80` and direction `outbound`.
> **Note:**\
> For more information about the routes, refer to the [documentation about `pilot-discovery`](https://istio.io/latest/docs/reference/commands/pilot-discovery/#pilot-discovery-completion).
### helloworld-foo
```shell
NAMESPACE="foo" && istioctl proxy-config clusters -n $NAMESPACE "$(kubectl get pods -n ${NAMESPACE} -l app=helloworld | tail -n 1 | awk '{ print $1 }')"
```
```text
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
80 - inbound ORIGINAL_DST
BlackHoleCluster - - - STATIC
InboundPassthroughClusterIpv4 - - - ORIGINAL_DST
PassthroughCluster - - - ORIGINAL_DST
agent - - - STATIC
helloworld.default.svc.cluster.local 8080 - outbound EDS
helloworld.foo.svc.cluster.local 8080 - outbound EDS
prometheus_stats - - - STATIC
sds-grpc - - - STATIC
xds-grpc - - - STATIC
zipkin - - - STRICT_DNS
```
We can observe the following entries:
- `BlackHoleCluster - - - STATIC`
and
- `helloworld.foo.svc.cluster.local 80 - outbound EDS`
Where `BlackHoleCluster` is a static destination without port attributed nor direction set, and is the route used to send the traffic to the `void`.
As well, we can find the routes `helloworld.foo.svc.cluster.local` and `helloworld.default.svc.cluster.local` where both specify the port `8080` and direction `outbound`.
> **Note:**\
> For more information about the routes, refer to the [documentation about `pilot-discovery`](https://istio.io/latest/docs/reference/commands/pilot-discovery/#pilot-discovery-completion).
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
namespace "foo" deleted
deployment.apps "helloworld-default" deleted
deployment.apps "helloworld-foo" deleted
service "helloworld" deleted
service "helloworld" deleted
sidecar.networking.istio.io "helloworld-sidecar-default" deleted
sidecar.networking.istio.io "helloworld-sidecar-foo" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/sidecar/#IstioEgressListener
- https://istio.io/latest/blog/2019/monitoring-external-service-traffic/#what-are-blackhole-and-passthrough-clusters
- https://istio.io/v1.0/help/ops/traffic-management/proxy-cmd/#deep-dive-into-envoy-configuration
- https://istio.io/latest/docs/reference/commands/pilot-discovery/#pilot-discovery-completion

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
namespace: foo
spec:
ports:
- port: 8080
name: http-a
targetPort: 80
- port: 80
name: http-b
targetPort: 80
selector:
app: helloworld
---
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
namespace: default
spec:
ports:
- port: 8080
name: http-a
targetPort: 80
- port: 80
name: http-b
targetPort: 80
selector:
app: helloworld

View File

@ -0,0 +1,38 @@
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar-default
namespace: default
spec:
workloadSelector:
labels:
app: helloworld
egress:
- port:
number: 80
protocol: HTTP
name: egress-http
hosts:
- "foo/*"
outboundTrafficPolicy:
mode: REGISTRY_ONLY
---
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar-foo
namespace: foo
spec:
workloadSelector:
labels:
app: helloworld
egress:
- port:
number: 8080
protocol: HTTP
name: egress-default
hosts:
- "default/*"
- "./*"
outboundTrafficPolicy:
mode: REGISTRY_ONLY

View File

@ -10,7 +10,7 @@ On this example compares the behavior between setting up the MeshConfig `Outboun
- REGISTRY_ONLY: Restricted to services that figure in the service registry a and the ServiceEntry objects.
More info regarding this configuration at the pertintent documentation (https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode)
More info regarding this configuration at the pertinent documentation (https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode)
## Runthrough
@ -70,7 +70,7 @@ server: istio-envoy
### Test egress the helloworld deployment
It returns a 301 code, meaning that it was able to reach the destination and it was attempted to redirect the traffic from HTTP to HTTPS.
It returns a 301 code, meaning that it was able to reach the destination, and it was attempted to redirect the traffic from HTTP to HTTPS.
```shell
$ kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl wikipedia.com -I

View File

@ -5,7 +5,7 @@ include_toc: true
# Continues from
- [06-mTLS](../../02-Traffic_management/06-mTLS)
- [06-mTLS](../../10-mTLS_PeerAuthentication/06-mTLS)
## Description

Some files were not shown because too many files have changed in this diff Show More