Merge pull request 'Cleanup and minimal documentation added.' (#46) from dev into main

Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/46
This commit is contained in:
ofilter 2023-05-01 00:08:05 +00:00
commit ce4cb196eb
178 changed files with 1741 additions and 1940 deletions

View File

@ -52,14 +52,16 @@ Warning [IST0104] (Gateway default/helloworld-gateway) The gateway refers to a p
Target a pod and start a packet capture on the istio-proxy container.
This step requires istio to be installed with the flag `values.global.proxy.privileged=true`
This step requires Istio to be installed with the flag `values.global.proxy.privileged=true`
This is very useful to confirm if the service is receiving any traffic, or which is the traffic received.
If mTLS is enabled and configured, the traffic received should be encrypted.
```shell
$ kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80 -A
kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80 -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
...

View File

@ -1,25 +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: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -36,7 +14,6 @@ spec:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx

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

View File

@ -0,0 +1,236 @@
---
gitea: none
include_toc: true
---
# Description
This is the most basic example, most of the examples spread through this [repository](../../) will be using variants of this.
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.
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
It doesn't filter for any specific host.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
```
# 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
Due to accessing the path `/helloworld`, we are triggering the rule set on the [VirtualService configuration](#virtualservice), sending a request to the Nginx backend and returning us its contents.
```shell
curl 192.168.1.50/helloworld -s | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
### Curl /other
What happens if we access a path or URL that doesn't trigger any rule?
```shell
curl 192.168.1.50/other -s -I
```
```text
HTTP/1.1 404 Not Found
date: Sun, 30 Apr 2023 22:16:30 GMT
server: istio-envoy
transfer-encoding: chunked
```
We receive a status code `404`.
I would like to put emphasis on the following line returned:
```text
server: istio-envoy
```
This means that the contents returned was performed by the Istio service, instead of the Nginx or any other possible backend service.
## 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
```

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

@ -1,25 +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: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -36,7 +14,6 @@ spec:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx
@ -63,7 +40,6 @@ spec:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: httpd

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

View File

@ -0,0 +1,306 @@
---
gitea: none
include_toc: true
---
# Description
This example deploys the same infrastructure as the [previous example](../01-hello_world_1_service_1_deployment), this time containing 2 deployments under the same service.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 2 Deployments
Istio resources:
- 1 Gateway
- 1 Virtual Service
# Based on
- [01-hello_world_1_service_1_deployment](../01-hello_world_1_service_1_deployment)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
### helloworld-v1
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
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
ports:
- containerPort: 80
```
### helloworld-v2
Deploys an Apache server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: httpd
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
It doesn't filter for any specific host.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-v1 created
deployment.apps/helloworld-v2 created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the pods to be ready
Wait for the Apache and Nginx deployments to be up and ready.
```shell
kubectl get deployment helloworld-v{1..2} -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-v1 1/1 1 1 4m1s
helloworld-v2 1/1 1 1 4m1s
```
## 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
Performing a series of `curl` requests, we can observe how the response iterate between the Nginx and Apache backends.
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<html><body><h1>It works!</h1></body></html>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<html><body><h1>It works!</h1></body></html>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<html><body><h1>It works!</h1></body></html>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<html><body><h1>It works!</h1></body></html>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-v1" deleted
deployment.apps "helloworld-v2" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```

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

@ -1,37 +1,11 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
---
apiVersion: v1
kind: Service
metadata:
name: helloworld
namespace: defaultnt
labels:
app: helloworldll
service: helloworld
sidecar.istio.io/inject: "false"
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
namespace: defaultnt
labels:
app: helloworld
version: v1
namespace: default
spec:
replicas: 1
selector:
@ -58,10 +32,10 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
namespace: defaultnt
labels:
app: helloworld
version: v2
namespace: default
spec:
replicas: 1
selector:
@ -82,5 +56,4 @@ spec:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
- containerPort: 80

View File

@ -0,0 +1,16 @@
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
# name: helloworld (OLD)
name: helloworld.default.svc.cluster.local # Destination that will "interject"
namespace: default
spec:
# host: helloworld # destination service (OLD)
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

View File

@ -0,0 +1,15 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

View File

@ -0,0 +1,426 @@
---
gitea: none
include_toc: true
---
# Description
Based on the [previous example](../02-hello_world_1_service_2_deployments_unmanaged), where we created 2 deployments under the same service, we will attribute different tags to each Deployment, and afterwards, through the usage of a [DestinationRule](#destinationrule), internationally target the desired backend to route the traffic towards it.
This is example is based on the following post regarding [canary deployments on Istio](https://istio.io/latest/blog/2017/0.1-canary/).
This example configures:
Generic Kubernetes resources:
- 1 Service
- 2 Deployments
Istio resources:
- 1 Gateway
- 1 Virtual Service
- 1 Destination rule
Additionally, for consistency, now the resources are being created in the `default` namespace.
As well, on the [VirtualService section](#virtualservice), we are targeting the service `helloworld` by the full URL, where on previous examples it was targeted by `helloworld`, now it's targeted by `helloworld.default.svc.cluster.local`.
# Based on
- [02-hello_world_1_service_2_deployments_unmanaged](../02-hello_world_1_service_2_deployments_unmanaged)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
### helloworld-v1
Deploys a Nginx server that listens for the port `80`.
On this deployment, we attributed the label `version` set to `v1`, this will be used by the [DestinationRule](#destinationrule) resource to target this deployment.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
labels:
app: helloworld
version: v1
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
```
### helloworld-v2
Deploys an Apache server that listens for the port `80`.
On this deployment, we attributed the label `version` set to `v2`, this will be used by the [DestinationRule](#destinationrule) resource to target this deployment.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
labels:
app: helloworld
version: v2
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v2
template:
metadata:
labels:
app: helloworld
version: v2
spec:
containers:
- name: helloworld
image: httpd
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
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
namespace: default
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
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).
Also, there's been configured 2 destinations under the same rule, each one with a `subset` set, which will be used by the [DestinationRule](#destinationrule) object to manage the traffic from each destination.
As well, where each one of the destinations mentioned, has a `weight` set, this value will be used to distribute the incoming requests towards the specified subsets.
> **Note:**
> A 20% of the traffic will be sent to the `subset` v1, meanwhile 80% will be sent to the `subset` v2.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
# host: helloworld (OLD)
port:
number: 80
subset: v1
weight: 20
- destination:
# host: helloworld (OLD)
host: helloworld.default.svc.cluster.local
port:
number: 80
subset: v2
weight: 80
rewrite:
uri: "/"
```
## DestinationRule
This `DestinationRule` interferes with the traffic with destination `helloworld.default.svc.cluster.local`.
Contains 2 subsets defined, where each one will target a different backend.
A reminder that the `version: v1` was given to the Nginx backend, meanwhile the Apache backend had set `version: v2`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
# name: helloworld (OLD)
name: helloworld.default.svc.cluster.local # Destination that will "interject"
namespace: default
spec:
# host: helloworld # destination service (OLD)
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-v1 created
deployment.apps/helloworld-v2 created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the pods to be ready
Wait for the Apache and Nginx deployments to be up and ready.
```shell
watch -n 2 kubectl get deployment helloworld-v{1..2}
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-v1 1/1 1 1 58s
helloworld-v2 1/1 1 1 58s
```
## 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
By performing a series of curls, we can notice how the output received iterates between Nginx and Apache.
If we take into account the configuration set, and we review the results, we can notice how the ratio is close to the one configured in the [VirtualService](#virtualservice) section.
> Nginx instances (v1): 2 \
> Apache instances (v2): 9
```text
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<h1>Welcome to nginx!</h1>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<h1>Welcome to nginx!</h1>
```
## Check Istio internal configurations created
Using the command `istioctl x describe pod $POD`, we can see which Istio configuration is currently attributed to that specific pod.
### v1
We can notice the following line:
`Weight 20%`
Which matches the configuration set in the [VirtualService](#virtualservice) configuration.
```sh
istioctl x describe pod $(kubectl get pod -l app=helloworld,version=v1 -o jsonpath='{.items[0].metadata.name}')
```
```text
Pod: helloworld-v1-7454b56b86-4cksf
Pod Revision: default
Pod Ports: 80 (helloworld), 15090 (istio-proxy)
--------------------
Service: helloworld
Port: http 80/HTTP targets pod port 80
DestinationRule: helloworld for "helloworld.default.svc.cluster.local"
Matching subsets: v1
(Non-matching subsets v2)
No Traffic Policy
--------------------
Effective PeerAuthentication:
Workload mTLS mode: PERMISSIVE
Exposed on Ingress Gateway http://192.168.1.50
VirtualService: helloworld-vs
Weight 20%
/helloworld
```
### v2
We can notice the following line:
`Weight 80%`
Which matches the configuration set in the [VirtualService](#virtualservice) configuration.
```shell
istioctl x describe pod `kubectl get pod -l app=helloworld,version=v2 -o jsonpath='{.items[0].metadata.name
```
```text
Pod: helloworld-v2-64b5656d99-5bwgr
Pod Revision: default
Pod Ports: 80 (helloworld), 15090 (istio-proxy)
--------------------
Service: helloworld
Port: http 80/HTTP targets pod port 80
DestinationRule: helloworld for "helloworld.default.svc.cluster.local"
Matching subsets: v2
(Non-matching subsets v1)
No Traffic Policy
--------------------
Effective PeerAuthentication:
Workload mTLS mode: PERMISSIVE
Exposed on Ingress Gateway http://192.168.1.50
VirtualService: helloworld-vs
Weight 80%
/helloworld
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-v1" deleted
deployment.apps "helloworld-v2" deleted
destinationrule.networking.istio.io "helloworld.default.svc.cluster.local" 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/blog/2017/0.1-canary/
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#DestinationRule

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
namespace: default
spec:
ports:
- port: 80
name: http
selector:
app: helloworld

View File

@ -0,0 +1,31 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
# host: helloworld (OLD)
port:
number: 80
subset: v1
weight: 20
- destination:
# host: helloworld (OLD)
host: helloworld.default.svc.cluster.local
port:
number: 80
subset: v2
weight: 80
rewrite:
uri: "/"

View File

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

View File

@ -1,29 +1,8 @@
# 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: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
namespace: foo
labels:
app: helloworld
version: v1
@ -39,7 +18,6 @@ spec:
app: helloworld
version: v1
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx
@ -54,6 +32,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
namespace: foo
labels:
app: helloworld
version: v2
@ -69,7 +48,6 @@ spec:
app: helloworld
version: v2
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: httpd

View File

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: foo
spec:
host: helloworld.foo.svc.cluster.local # Full destination service, lil better for consistency
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

View File

@ -0,0 +1,15 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

View File

@ -0,0 +1,374 @@
---
gitea: none
include_toc: true
---
# Description
Based on the [previous example](../03-hello_world_1_service_2_deployments_managed_version), we create the previous deployments in a different namespace than the Istio VirtualService object, in this case we create them in the namespace `foo`.
This is example is based on the following post regarding [canary deployments on Istio](https://istio.io/latest/blog/2017/0.1-canary/).
This example configures:
Generic Kubernetes resources:
- 1 Namespace
- 1 Service
- 2 Deployments
Istio resources:
- 1 Gateway
- 1 Virtual Service
- 1 Destination rule
Additionally, for consistency, now the resources are being created in the `default` namespace.
On this example, the `service`, the `deployment`, and the Istio `DestinationRule` are being created in the namespace `foo`.
As well, on the [VirtualService section](#virtualservice), we are targeting the service `helloworld` by the full URL, where on previous examples it was targeted by `helloworld`, now it's targeted by `helloworld.default.svc.cluster.local`.
# Based on
- [03-hello_world_1_service_2_deployments_managed_version](../03-hello_world_1_service_2_deployments_managed_version)
# Configuration
## Namespace
Creates a namespace named `foo`.
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: foo
```
## 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.
The service is created in the namespace `foo`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
namespace: foo
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
### helloworld-v1
Deploys a Nginx server that listens for the port `80`.
On this deployment, we attributed the label `version` set to `v1`, this will be used by the [DestinationRule](#destinationrule) resource to target this deployment.
The deployment is created in the namespace `foo`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
namespace: foo
labels:
app: helloworld
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
```
### helloworld-v2
Deploys an Apache server that listens for the port `80`.
On this deployment, we attributed the label `version` set to `v2`, this will be used by the [DestinationRule](#destinationrule) resource to target this deployment.
The deployment is created in the namespace `foo`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
namespace: foo
labels:
app: helloworld
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v2
template:
metadata:
labels:
app: helloworld
version: v2
spec:
containers:
- name: helloworld
image: httpd
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
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
namespace: default
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld` located in the namespace `foo`.
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).
Also, there's been configured 2 destinations under the same rule, each one with a `subset` set, which will be used by the [DestinationRule](#destinationrule) object to manage the traffic from each destination.
As well, where each one of the destinations mentioned, has a `weight` set, this value will be used to distribute the incoming requests towards the specified subsets.
> **Note:**
> A 20% of the traffic will be sent to the `subset` v1, meanwhile 80% will be sent to the `subset` v2.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.foo.svc.cluster.local
port:
number: 80
subset: v1
weight: 20
- destination:
host: helloworld.foo.svc.cluster.local
port:
number: 80
subset: v2
weight: 80
rewrite:
uri: "/"
```
## DestinationRule
This `DestinationRule` interferes with the traffic with destination `helloworld.foo.svc.cluster.local`.
Contains 2 subsets defined, where each one will target a different backend.
A reminder that the `version: v1` was given to the Nginx backend, meanwhile the Apache backend had set `version: v2`.
This resource is created in the namespace `foo`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: foo
spec:
host: helloworld.foo.svc.cluster.local # Full destination service, lil better for consistency
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
```
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-v1 created
deployment.apps/helloworld-v2 created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the pods to be ready
Wait for the Apache and Nginx deployments to be up and ready.
```shell
watch -n 2 kubectl get deployment helloworld-v{1..2}
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-v1 1/1 1 1 58s
helloworld-v2 1/1 1 1 58s
```
## 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
As we can see, we can reach out to the service, now located in the namespace `foo`.
As well, if we check the ration on which we reached the backends, we can still see how the [VirtualService](#virtualservice) weight configured to the subsets is still being applied.
> Nginx: 3\
> Apache: 9
```text
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<h1>Welcome to nginx!</h1>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<h1>Welcome to nginx!</h1>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<h1>Welcome to nginx!</h1>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
$ 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
<html><body><h1>It works!</h1></body></html>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
namespace "foo" deleted
deployment.apps "helloworld-v1" deleted
deployment.apps "helloworld-v2" deleted
destinationrule.networking.istio.io "helloworld" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
namespace: foo
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld

View File

@ -0,0 +1,29 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.foo.svc.cluster.local
port:
number: 80
subset: v1
weight: 20
- destination:
host: helloworld.foo.svc.cluster.local
port:
number: 80
subset: v2
weight: 80
rewrite:
uri: "/"

45
01-Getting_Started/README.md Executable file
View File

@ -0,0 +1,45 @@
---
gitea: none
include_toc: true
---
# Getting Started
The idea of these examples is to get yourself familiarized with the basic elements used on Istio, allowing you to explore the documentation as well of proceeding with other examples or tests on your onw.
On these examples you will find the following Istio resources:
- Gateway
- VirtualService
- DestinationRule
# Examples
- 01-hello_world_1_service_1_deployment
- 02-hello_world_1_service_2_deployments_unmanaged
- 03-hello_world_1_service_2_deployments_managed_version
- 04-hello_world_1_service_2_deployments_managed_version_foo_namespace
# How to get started?
## Install Istio
Follow [this](https://istio.io/latest/docs/setup/getting-started/) guide to install the `default` profile.
Specifically, the steps of [Download Istio](https://istio.io/latest/docs/setup/getting-started/#download) and [Install Istio][https://istio.io/latest/docs/setup/getting-started/#install).
Once this is set, proceed with the rest of the installation.
## Setting up a Cluster?
Consider using this.
It's what I used to set up my labs for testing (which is the environment that I to do this repository/set of examples).
https://gitea.filterhome.xyz/ofilter/ansible_kubernetes_cluster
Also, I have added MetalLB to allow for my Load Balancers to get a Local IP and be available through the local network environment.

View File

@ -108,7 +108,7 @@ spec:
## DestinationRule
As seen in the example [02-Traffic_management/09-HTTPS-backend](../../02-Traffic_management/09-HTTPS-backend), where we configure Istio to use an `HTTPS` backend, the same configuration is applied on this case (yes, I am aware that a `ServiceEntry` is also a backend).
As seen in the example [02-Traffic_management/09-HTTPS-backend](../09-HTTPS-backend), where we configure Istio to use an `HTTPS` backend, the same configuration is applied on this case (yes, I am aware that a `ServiceEntry` is also a backend).
For such, we deploy a `DestinationRule` setting to expect to terminate the TLS traffic, for the traffic with resource destination `github.com`, and port `8443`, which matches the settings set in our [ServiceEntry](#serviceentry) deployed.
@ -169,7 +169,7 @@ I mean, we can use curl but it's certainly quite an ugly output, it works tho.
As performing the test through `curl` is ugly, here is a screenshot of the setting working correctly.
![github-screenshot.png](./src/github-screenshot.png)
![github-screenshot.png](src/github-screenshot.png)
## Cleanup

View File

@ -5,7 +5,7 @@ include_toc: true
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Simple/01-hello_world_1_service_1_deployment)
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
## Description

View File

@ -5,7 +5,7 @@ include_toc: true
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Simple/01-hello_world_1_service_1_deployment)
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
# Description

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -1,4 +1,3 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:

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