Compare commits
94 Commits
14e987ea95
...
main
Author | SHA1 | Date | |
---|---|---|---|
2f87a19545 | |||
a4419990ea | |||
990bada6e1 | |||
e088cf6659 | |||
ee13b20458 | |||
2582e15e1a | |||
404c036883 | |||
6cb3c9fa50 | |||
f86ac97255 | |||
2fb608c5bd | |||
942a3bf8ae | |||
74e5b9d5f0 | |||
7e004697a9 | |||
c02a355a95 | |||
d2b1dc2284 | |||
f0ce2ae68d | |||
b6657bdd4c | |||
68efcde1fa | |||
1cf75d5902 | |||
df8eea778c | |||
c1aec3ae4c | |||
957dbfcf84 | |||
e883755680 | |||
0a1e36dcaf | |||
40fe16c040 | |||
b440efb6b2 | |||
4e66d65096 | |||
16f7ab6178 | |||
d117481a5b | |||
84b71d9751 | |||
fd3f9b6e95 | |||
de4ae7dd09 | |||
6aa4cb2c03 | |||
8c1288f8d1 | |||
23eb763524 | |||
87aab0c9be | |||
6ff0ce9ee8 | |||
439d62b718 | |||
73d4918f2c | |||
93018487e6 | |||
1542aaafcc | |||
f8fd8c6ce5 | |||
9d7cae15f8 | |||
f068de7dcc | |||
eb001e704a | |||
f5b24a9a17 | |||
78f09bdc08 | |||
07bca8cce1 | |||
e9af4daeee | |||
be2375c14c | |||
b7de0f8205 | |||
918f480319 | |||
703d380bca | |||
4681d98ae7 | |||
fe4cfa88a6 | |||
88e71e8c5b | |||
747c3f1171 | |||
6c6f968097 | |||
8ba4495ea7 | |||
9dbcf712de | |||
6153529f9a | |||
38a7b70758 | |||
ca68dde6ea | |||
57e858f416 | |||
faf8b08e77 | |||
9fbc2c5f1f | |||
4940fdd3b7 | |||
4bd53c84de | |||
5059a13888 | |||
c7c1f8cb9c | |||
fb34758197 | |||
54025a55dd | |||
6b0b62b6a9 | |||
113ed75177 | |||
f3fa2372fe | |||
4e0f4ba05d | |||
b37c523c39 | |||
f52e1125a7 | |||
d3d730b34c | |||
73b4959b45 | |||
138b3a01f2 | |||
7e5c9a89a4 | |||
1b1ca0dbd8 | |||
adb600110d | |||
ce4cb196eb | |||
b6f23cbbe6 | |||
4bb925e1cd | |||
0cc6c09c53 | |||
309a9dded7 | |||
3739cda159 | |||
65e0afc0be | |||
03a604c91e | |||
b48837e5c0 | |||
6c9d5604e2 |
3
.placeholder/13-WASM_Modules/README.md
Normal file
3
.placeholder/13-WASM_Modules/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
https://github.com/istio-ecosystem/wasm-extensions
|
||||
|
||||
https://github.com/istio-ecosystem/wasm-extensions/tree/master/extensions/basic_auth
|
54
.placeholder/text.md
Normal file
54
.placeholder/text.md
Normal 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"
|
||||
```
|
@ -3,6 +3,63 @@ gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
|
||||
# Logs
|
||||
|
||||
> **Note:**\
|
||||
> Remember that you can use the command `watch` or `watch -n 5` (where 5 refers every 5 seconds) in case of being interested on execute this commands periodically.
|
||||
|
||||
## Istiod
|
||||
|
||||
```shell
|
||||
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.
|
||||
|
||||
```shell
|
||||
kubectl logs -n istio-system services/istio-ingressgateway
|
||||
```
|
||||
#### Invalid TLS context has neither subject CN nor SAN names
|
||||
|
||||
The TLS certificate specified don't have the field CN or the field SAN.
|
||||
|
||||
To address this issue, issue a new certificate that has at least one of those fields.
|
||||
|
||||
#### initial fetch timed out for type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secretthread
|
||||
|
||||
This is due not being able to retrieve the TLS configuration assigned to the gateway.
|
||||
|
||||
It's Important that the secret is located in the same namespace as the Istio Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Istioctl analyze
|
||||
|
||||
`istioctl analyze` reviews the current configuration set.
|
||||
@ -52,50 +109,39 @@ 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
|
||||
...
|
||||
```
|
||||
|
||||
# Logs
|
||||
|
||||
> **Note:**\
|
||||
> Remember that you can use the command `watch` or `watch -n 5` (where 5 refers every 5 seconds) in case of being interested on execute this commands periodically.
|
||||
|
||||
## Istiod
|
||||
# Istioctl proxy-status
|
||||
> **Note:** Shorthand is `ps`
|
||||
|
||||
```shell
|
||||
kubectl logs -n istio-system -f deployments/istiod
|
||||
istioctl ps
|
||||
```
|
||||
```text
|
||||
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
|
||||
helloworld-6798765f88-ql26n.default Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-dbf5ff64-9kxxs 1.17.2
|
||||
helloworld2-dc9cb5db6-m47x7.default Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-dbf5ff64-9kxxs 1.17.2
|
||||
istio-egressgateway-676bf68b54-d28fn.istio-system Kubernetes SYNCED SYNCED SYNCED NOT SENT NOT SENT istiod-dbf5ff64-9kxxs 1.17.2
|
||||
istio-ingressgateway-8d56c999d-nv7ph.istio-system Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-dbf5ff64-9kxxs 1.17.2
|
||||
```
|
||||
|
||||
## Ingress
|
||||
|
||||
The service targeted, `istio-ingressgateway`, is an Ingress Load Balancer service from Istio.
|
||||
|
||||
```shell
|
||||
kubectl logs -n istio-system services/istio-ingressgateway
|
||||
```
|
||||
#### Invalid TLS context has neither subject CN nor SAN names
|
||||
|
||||
The TLS certificate specified don't have the field CN or the field SAN.
|
||||
|
||||
To address this issue, issue a new certificate that has at least one of those fields.
|
||||
|
||||
#### initial fetch timed out for type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secretthread
|
||||
|
||||
This is due not being able to retrieve the TLS configuration assigned to the gateway.
|
||||
|
||||
It's Important that the secret is located in the same namespace as the Istio Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
|
||||
|
||||
# Istioctl proxy-config
|
||||
> **Note:** Shorthand is `pc`
|
||||
|
||||
|
||||
## Check listeners
|
||||
|
||||
@ -175,4 +221,8 @@ InboundPassthroughClusterIpv4 - -
|
||||
PassthroughCluster - - - ORIGINAL_DST
|
||||
agent - - - STATIC
|
||||
...
|
||||
```
|
||||
```
|
||||
|
||||
# Other links
|
||||
|
||||
## [Debugging with Istio](https://www.istioworkshop.io/12-debugging/01-istioctl-debug-command/)
|
||||
|
@ -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:
|
@ -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:
|
||||
- "*"
|
236
01-Getting_Started/01-hello_world_1_service_1_deployment/README.md
Executable file
236
01-Getting_Started/01-hello_world_1_service_1_deployment/README.md
Executable 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, therefore, the request was able to reach Istio and received a response from it.
|
||||
|
||||
## 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
|
||||
```
|
@ -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
|
@ -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
|
@ -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
|
@ -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:
|
||||
- "*"
|
306
01-Getting_Started/02-hello_world_1_service_2_deployments_unmanaged/README.md
Executable file
306
01-Getting_Started/02-hello_world_1_service_2_deployments_unmanaged/README.md
Executable 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
|
||||
```
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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:
|
||||
- "*"
|
@ -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
|
@ -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
|
@ -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: 80
|
||||
- destination:
|
||||
# host: helloworld (OLD)
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v2
|
||||
weight: 20
|
||||
rewrite:
|
||||
uri: "/"
|
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: foo
|
@ -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
|
@ -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
|
@ -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:
|
||||
- "*"
|
@ -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
|
||||
```
|
@ -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
|
@ -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: "/"
|
51
01-Getting_Started/README.md
Executable file
51
01-Getting_Started/README.md
Executable file
@ -0,0 +1,51 @@
|
||||
---
|
||||
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
|
||||
|
||||
## Requirements:
|
||||
|
||||
- A Kubernetes cluster (with a CNI network plugin, on my environment I have used [Calico](https://docs.tigera.io/calico/))
|
||||
|
||||
- Istio installed
|
||||
|
||||
# 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.
|
@ -1,120 +0,0 @@
|
||||
##### https://github.com/istio/istio/tree/master/samples/helloworld
|
||||
|
||||
### Base simple template
|
||||
|
||||
# Simple Hello World
|
||||
|
||||
- 1 Service
|
||||
- 1 Deployment
|
||||
|
||||
I think that by default uses `RANDOM`.
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/destination-rule/#TrafficPolicy-PortTrafficPolicy
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings
|
||||
|
||||
> Contains service account configurations, yet they are commented as not "necessary".
|
||||
|
||||
|
||||
## Files
|
||||
|
||||
- deployment.yaml
|
||||
- gateway.yaml
|
||||
|
||||
## deployment.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Service
|
||||
|
||||
- helloworld
|
||||
|
||||
#### Deployments
|
||||
|
||||
- helloworld-nginx (Nginx container)
|
||||
|
||||
## gateway.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Gateway
|
||||
|
||||
##### helloworld-gateway
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yml
|
||||
port: 80
|
||||
istio-ingress: ingressgateway
|
||||
hosts: "*"
|
||||
```
|
||||
|
||||
#### VirtualService
|
||||
|
||||
##### helloworld-vs
|
||||
|
||||
###### Configuration
|
||||
|
||||
|
||||
|
||||
```yaml
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
||||
```
|
||||
- Allows the traffic that have as a destination any domain.
|
||||
|
||||
- Only allows traffic that has as a destination the directory/path `/helloworld`.
|
||||
|
||||
- `rewrite.uri` allows to redirect the traffic towards the root directory of the service, as the service(s) used don't have any directory named `helloworld` but are configured to work at the root base level.
|
||||
|
||||
- Traffic request is sent to the service named `helloworld`, to the service port 80.
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
## Wait for the deployment to be ready
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment helloworld-nginx -w
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
helloworld-nginx 1/1 1 1 44s
|
||||
```
|
||||
|
||||
## Test the service
|
||||
|
||||
### Get LB IP
|
||||
|
||||
```shell
|
||||
$ kubectl get svc -l istio=ingressgateway -A
|
||||
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>
|
||||
```
|
@ -1,142 +0,0 @@
|
||||
##### https://github.com/istio/istio/tree/master/samples/helloworld
|
||||
|
||||
# Simple Hello World
|
||||
|
||||
- 1 Service
|
||||
- 2 Versions
|
||||
|
||||
Iterates between the versions without any specific policy. (actually doesn't use the version for anything)
|
||||
|
||||
By default uses `Round Robin`
|
||||
|
||||
https://istio.io/latest/docs/concepts/traffic-management/#load-balancing-options
|
||||
|
||||
> Contains service account configurations, yet they are commented as not "necessary".
|
||||
|
||||
|
||||
# Changes
|
||||
|
||||
## File
|
||||
|
||||
- deployment.yaml
|
||||
- gateway.yaml
|
||||
|
||||
> Files used maintains from the last version
|
||||
|
||||
## deployment.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Service
|
||||
|
||||
- helloworld
|
||||
|
||||
> Service used maintains from the last version
|
||||
|
||||
#### Deployments
|
||||
|
||||
- helloworld-v1 (Nginx)
|
||||
- helloworld-v2 (Apache)
|
||||
|
||||
> Renamed the old deployment from `helloworld-nginx` to `helloworld-v1`.\
|
||||
> Created a secondary deployment using apache named `helloworld-v2`.
|
||||
|
||||
## gateway.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Gateway
|
||||
|
||||
##### helloworld-gateway
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yml
|
||||
port: 80
|
||||
istio-ingress: ingressgateway
|
||||
hosts: "*"
|
||||
```
|
||||
|
||||
#### VirtualService
|
||||
|
||||
##### helloworld-vs
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yaml
|
||||
hosts: "*"
|
||||
uri: "/helloworld"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Run example
|
||||
|
||||
## Deploy resources
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f ./
|
||||
service/helloworld created
|
||||
deployment.apps/helloworld-v1 created
|
||||
deployment.apps/helloworld-v2 created
|
||||
deployment.apps/helloworld-v2 unchanged
|
||||
gateway.networking.istio.io/helloworld-gateway created
|
||||
virtualservice.networking.istio.io/helloworld-vs created
|
||||
```
|
||||
|
||||
## Wait for the pods to be ready
|
||||
|
||||
(I think it deploys 2 pods as there is the Envoy Proxy pod besides the Nginx deployment)
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment helloworld-v{1..2} -w
|
||||
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
|
||||
|
||||
```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
|
||||
|
||||
Iterates randomly between Nginx and Apache
|
||||
|
||||
```shell
|
||||
$ 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>
|
||||
|
||||
$ 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>
|
||||
|
||||
$ 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>
|
||||
```
|
@ -1,36 +0,0 @@
|
||||
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
@ -1,261 +0,0 @@
|
||||
##### https://github.com/istio/istio/tree/master/samples/helloworld
|
||||
|
||||
https://istio.io/latest/blog/2017/0.1-canary/
|
||||
|
||||
|
||||
# Continues from
|
||||
|
||||
- 01-hello_world_1_service_1_deployment
|
||||
|
||||
# Simple Hello World
|
||||
|
||||
- 1 Service
|
||||
- 2 Versions
|
||||
|
||||
Iterates between the versions without any specific policy. (actually doesn't use the version for anything)
|
||||
|
||||
|
||||
> Contains service account configurations, yet they are commented as not "necessary".
|
||||
|
||||
## Quick note
|
||||
|
||||
On this version I have "started" to use the full service name instead of the shorten version, aka:
|
||||
|
||||
```yaml
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
```
|
||||
|
||||
Will be:
|
||||
|
||||
```yaml
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
```
|
||||
|
||||
It's overall a good practice to have, so not much of a reason to not do it.
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/destination-rule/#DestinationRule
|
||||
|
||||
|
||||
# Changes
|
||||
|
||||
## File
|
||||
|
||||
- deployment.yaml
|
||||
- gateway.yaml
|
||||
|
||||
> Files used maintains from the last version
|
||||
|
||||
## deployment.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Service
|
||||
|
||||
- helloworld
|
||||
|
||||
> Service used maintains from the last version
|
||||
|
||||
#### Deployments
|
||||
|
||||
- helloworld-v1 (Nginx)
|
||||
- helloworld-v2 (Apache)
|
||||
|
||||
> Renamed the old deployment from `helloworld-nginx` to `helloworld-v1`.\
|
||||
> Created a secondary deployment using apache named `helloworld-v2`.
|
||||
|
||||
## gateway.yaml
|
||||
|
||||
#### VirtualService
|
||||
|
||||
##### helloworld-vs
|
||||
|
||||
###### Configuration
|
||||
|
||||
|
||||
|
||||
```yaml
|
||||
...
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v1
|
||||
weight: 20
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v2
|
||||
weight: 80
|
||||
...
|
||||
```
|
||||
|
||||
> Distributed the traffic between 2 versions (`subsets`), setting a `25%` to the subset `v1` and a `75%` to the subset `v2`.
|
||||
|
||||
> As previously mentioned, the section `http.route.host` points to `helloworld.default.svc.cluster.local`, which is the service we created, on the `default` namespace.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Destination Rule
|
||||
|
||||
###### Declaration configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld.default.svc.cluster.local # Destination that will "interject"
|
||||
```
|
||||
|
||||
> Here we need to put the `path/destination/service` that we want this rule to interject and manage.
|
||||
|
||||
###### Traffic Configuration
|
||||
|
||||
```yaml
|
||||
host: helloworld.default.svc.cluster.local
|
||||
subsets:
|
||||
- name: v1
|
||||
labels:
|
||||
version: v1
|
||||
- name: v2
|
||||
labels:
|
||||
version: v2
|
||||
```
|
||||
|
||||
> On the `Destination Rule` declared the subsets. Each subset has different labels. This will be used to select the deployments within the destination service.
|
||||
|
||||
# Run example
|
||||
|
||||
## Deploy resources
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f ./
|
||||
service/helloworld created
|
||||
deployment.apps/helloworld-v1 created
|
||||
deployment.apps/helloworld-v2 created
|
||||
gateway.networking.istio.io/helloworld-gateway created
|
||||
virtualservice.networking.istio.io/helloworld-vs created
|
||||
destinationrule.networking.istio.io/helloworld-destinationrule created
|
||||
```
|
||||
|
||||
## Wait for the pods to be ready
|
||||
|
||||
(I think it deploys 2 pods as there is the Envoy Proxy pod besides the Nginx deployment)
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment helloworld-v{1..2} -w
|
||||
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
|
||||
|
||||
```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
|
||||
|
||||
Iterates between Nginx and Apache. Somwhat close to the ratio configured.
|
||||
|
||||
> Nginx instances (v1): 2 \
|
||||
> Apache instances (v2): 9
|
||||
|
||||
```shell
|
||||
$ 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 configs
|
||||
|
||||
```sh
|
||||
$ istioctl x describe pod `kubectl get pod -l app=helloworld,version=v1 -o jsonpath='{.items[0].metadata.name}'`
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
```shell
|
||||
$ istioctl x describe pod `kubectl get pod -l app=helloworld,version=v2 -o jsonpath='{.items[0].metadata.name
|
||||
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
|
||||
```
|
@ -1,62 +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
|
||||
# host: helloworld
|
||||
port:
|
||||
number: 80
|
||||
subset: v1
|
||||
weight: 20
|
||||
- destination:
|
||||
# host: helloworld
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v2
|
||||
weight: 80
|
||||
rewrite:
|
||||
uri: "/"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
# name: helloworld
|
||||
name: helloworld.default.svc.cluster.local # Destination that will "interject"
|
||||
spec:
|
||||
# host: helloworld # destination service
|
||||
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: v1
|
||||
labels:
|
||||
version: v1
|
||||
- name: v2
|
||||
labels:
|
||||
version: v2
|
@ -1,8 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: defaultnt
|
||||
labels:
|
||||
istio-injection: "false"
|
||||
# istio-injection: "enabled"
|
||||
---
|
@ -1,123 +0,0 @@
|
||||
##### https://github.com/istio/istio/tree/master/samples/helloworld
|
||||
|
||||
https://istio.io/latest/blog/2017/0.1-canary/
|
||||
|
||||
|
||||
# Simple Hello World
|
||||
|
||||
- 1 Service
|
||||
- 2 Versions
|
||||
|
||||
Iterates between the versions without any specific policy. (actually doesn't use the version for anything)
|
||||
|
||||
I think that by default uses `RANDOM`.
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/destination-rule/#TrafficPolicy-PortTrafficPolicy
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings
|
||||
|
||||
|
||||
Manually allows the sidecar injection through the label in the pod
|
||||
|
||||
|
||||
https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#controlling-the-injection-policy
|
||||
|
||||
## Files
|
||||
|
||||
- deployment.yaml
|
||||
- gateway.yaml
|
||||
|
||||
## deployment.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Service
|
||||
|
||||
- helloworld
|
||||
|
||||
#### Deployments
|
||||
|
||||
- helloworld-v1 (Nginx)
|
||||
- helloworld-v2 (Apache)
|
||||
|
||||
## gateway.yaml
|
||||
|
||||
### Creates
|
||||
|
||||
#### Gateway
|
||||
|
||||
##### helloworld-gateway
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yml
|
||||
port: 80
|
||||
istio-ingress: ingressgateway
|
||||
hosts: "*"
|
||||
```
|
||||
|
||||
#### VirtualService
|
||||
|
||||
##### helloworld-vs
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yaml
|
||||
hosts: "*"
|
||||
uri: "/helloworld"
|
||||
versions:
|
||||
v1:
|
||||
weight: "50%"
|
||||
v2:
|
||||
weight: "50%"
|
||||
```
|
||||
|
||||
#### Destination Rule
|
||||
|
||||
###### Configuration
|
||||
|
||||
```yaml
|
||||
host: helloworld.defaultnt.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: v1
|
||||
labels:
|
||||
version: v1
|
||||
- name: v2
|
||||
labels:
|
||||
version: v2
|
||||
```
|
||||
|
||||
|
||||
# Run example
|
||||
|
||||
## Deploy resources
|
||||
|
||||
```shell
|
||||
$
|
||||
```
|
||||
|
||||
## Wait for the pods to be ready
|
||||
|
||||
(I think it deploys 2 pods as there is the Envoy Proxy pod besides the Nginx deployment)
|
||||
|
||||
```shell
|
||||
|
||||
```
|
||||
|
||||
## 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 "<h1>.*</h1>"
|
||||
<html><body><h1>It works!</h1></body></html>
|
||||
```
|
@ -1,61 +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
|
||||
namespace: defaultnt
|
||||
spec:
|
||||
selector:
|
||||
istio: istio-ingress # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
namespace: defaultnt
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.defaultnt.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v1
|
||||
weight: 50
|
||||
- destination:
|
||||
host: helloworld.defaultnt.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: v2
|
||||
weight: 50
|
||||
rewrite:
|
||||
uri: "/"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld
|
||||
namespace: defaultnt
|
||||
spec:
|
||||
host: helloworld.defaultnt.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: v1
|
||||
labels:
|
||||
version: v1
|
||||
- name: v2
|
||||
labels:
|
||||
version: v2
|
@ -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
|
@ -1,38 +0,0 @@
|
||||
# Simple examples
|
||||
|
||||
|
||||
# Traffic path
|
||||
|
||||
## Istio Ingress Controller ---> Gateway -> Virtual Service (-> Destination Route) -> Ingress -> Deployment
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
ALL NEEDS DOCUMENTATION
|
||||
|
||||
- 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_defaultnt_namespace
|
||||
|
||||
- 05-hello_world_1_Service_Entry
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
do HTTPS ingress
|
||||
|
||||
tcp ingress to minecraft/factorio/zomboid
|
||||
|
||||
Service Entry with outbound policy set to `REGISTRY_ONLY`
|
||||
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
|
||||
(no funca)
|
@ -1,11 +0,0 @@
|
||||
##### https://github.com/istio/istio/tree/master/samples/helloworld
|
||||
|
||||
https://istio.io/latest/blog/2017/0.1-canary/
|
||||
|
||||
# Note, VirtualService match rule order MATTERS
|
||||
|
||||
Leave the "default/wildcard" rule at the bottom
|
||||
|
||||
# Continues from
|
||||
|
||||
- 03-hello_world_1_service_1_deployment
|
@ -1,18 +1,3 @@
|
||||
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
@ -0,0 +1,16 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld.default.svc.cluster.local # Destination that will "interject"
|
||||
spec:
|
||||
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: default
|
||||
labels:
|
||||
version: v0
|
||||
- name: nginx
|
||||
labels:
|
||||
version: v1
|
||||
- name: apache
|
||||
labels:
|
||||
version: v2
|
14
02-Traffic_management/01-header_routing/Gateway.yaml
Executable file
14
02-Traffic_management/01-header_routing/Gateway.yaml
Executable 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:
|
||||
- "*"
|
456
02-Traffic_management/01-header_routing/README.md
Executable file
456
02-Traffic_management/01-header_routing/README.md
Executable file
@ -0,0 +1,456 @@
|
||||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
# Description
|
||||
|
||||
The [previous example](../../01-Getting_Started/03-hello_world_1_service_2_deployments_managed_version), we use the values set in the headers from the `HTTP` request received to route the traffic to different backends.
|
||||
|
||||
Additionally, we configure a default rule where the unmatched traffic will go.
|
||||
|
||||
This example configures:
|
||||
|
||||
Generic Kubernetes resources:
|
||||
- 1 Namespace
|
||||
- 1 Service
|
||||
- 3 Deployments
|
||||
|
||||
Istio resources:
|
||||
- 1 Gateway
|
||||
- 1 Virtual Service
|
||||
- 1 Destination rule
|
||||
|
||||
# Based on
|
||||
|
||||
- [03-hello_world_1_service_2_deployments_managed_version](../../01-Getting_Started/03-hello_world_1_service_2_deployments_managed_version)
|
||||
|
||||
# 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
|
||||
|
||||
We will create 3 different deployments where the traffic will be distributed, targeting the labels set to the pods.
|
||||
|
||||
Deployments created:
|
||||
|
||||
- helloworld-v0
|
||||
- helloworld-v1
|
||||
- helloworld-v2
|
||||
|
||||
### helloworld-v0
|
||||
|
||||
Deploys a Whoami server that listens for the port `80`.
|
||||
|
||||
On this deployment, we attributed the label `version` set to `v0`, this will be used by the [DestinationRule](#destinationrule) resource to target this deployment.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: helloworld-v0
|
||||
labels:
|
||||
app: helloworld
|
||||
version: v0
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helloworld
|
||||
version: v0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: helloworld
|
||||
version: v0
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
||||
image: containous/whoami
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
### 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
|
||||
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
|
||||
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 configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host.
|
||||
|
||||
We will create 3 rules that target `HTTP` (including `HTTPS` and `HTTP2` traffic), which are declared with the following names:
|
||||
|
||||
- firefox
|
||||
- curl
|
||||
- default
|
||||
|
||||
The `firefox` rule is intended to receive traffic coming from a Firefox web browser.
|
||||
|
||||
The `curl` rule is intended to receive traffic coming from the `curl` command line package/command.
|
||||
|
||||
The `default` rule is intended to receive traffic not matched by the 2 rules of above (as long meets certain criteria).
|
||||
|
||||
All the rules created will match on the following topics:
|
||||
|
||||
- The path directory will be `/helloworld`.
|
||||
|
||||
- The destination service will be `helloworld.default.svc.cluster.local` to the port `80`.
|
||||
|
||||
- Rewrite URL path to `/` to not create conflicts with the backend.
|
||||
|
||||
The rules will differ on the following topics:
|
||||
|
||||
- Each rule will target a specific content from the header `user-agent`, except of default.
|
||||
|
||||
- Each rule will target a different `subset` to distribute the traffic between the [Deployment resources created](#deployment).
|
||||
|
||||
> **Note**\
|
||||
> If you usage not familiar with the usage of `subsets`, I strongly recommend to check the following example:
|
||||
> - [03-hello_world_1_service_2_deployments_managed_version](../../01-Getting_Started/03-hello_world_1_service_2_deployments_managed_version)
|
||||
|
||||
> **Note**\
|
||||
> The declaration order from the resources is important, as the elements created further above on the list will have priority over the rules set under them.\
|
||||
> This would mean that if we declared the `default` matching rule first, it would overtake the traffic meant to reach the rules `firefox` and `curl`.
|
||||
> For more information regarding this matter, refer to the following Official Istio documentation regarding [the HttpMatchRequest field from Istio VirtualServices](https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest).
|
||||
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- name: firefox
|
||||
match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
headers:
|
||||
user-agent:
|
||||
regex: '.*Firefox.*'
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: nginx
|
||||
rewrite:
|
||||
uri: "/"
|
||||
- name: curl
|
||||
match:
|
||||
- headers:
|
||||
user-agent:
|
||||
regex: '.*curl.*'
|
||||
uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: apache
|
||||
rewrite:
|
||||
uri: "/"
|
||||
- name: default
|
||||
match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
subset: default
|
||||
rewrite:
|
||||
uri: "/"
|
||||
```
|
||||
|
||||
## DestinationRule
|
||||
|
||||
This `DestinationRule` interferes with the traffic with destination `helloworld.default.svc.cluster.local`.
|
||||
|
||||
Contains 3 subsets defined, where each one will target a different backend.
|
||||
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld.default.svc.cluster.local # Destination that will "interject"
|
||||
spec:
|
||||
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: default
|
||||
labels:
|
||||
version: v0
|
||||
- name: nginx
|
||||
labels:
|
||||
version: v1
|
||||
- name: apache
|
||||
labels:
|
||||
version: v2
|
||||
```
|
||||
|
||||
# Walkthrough
|
||||
|
||||
## Deploy resources
|
||||
|
||||
Deploy the resources.
|
||||
|
||||
```shell
|
||||
kubectl apply -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps/helloworld-v0 created
|
||||
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, Nginx and Whoami deployments to be up and ready.
|
||||
|
||||
```shell
|
||||
watch -n 2 kubectl get deployment helloworld-v{0..2}
|
||||
```
|
||||
```text
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
helloworld-v0 1/1 1 1 23s
|
||||
helloworld-v1 1/1 1 1 23s
|
||||
helloworld-v2 1/1 1 1 23s
|
||||
```
|
||||
|
||||
## Test the service
|
||||
|
||||
Now it's time to test the rules created in the [VirtualService configuration](#virtualservice), for such reminder that:
|
||||
|
||||
- Curl should return traffic from the Apache deployment.
|
||||
- Firefox should return traffic from the Nginx deployment.
|
||||
- The rest of the traffic should return us a response from the Whoami deployment. (as long it matches the rest of criteria set in the rule).
|
||||
|
||||
### 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
|
||||
|
||||
Using the command `curl`, results in receiving content from the Apache deployment.
|
||||
|
||||
```text
|
||||
curl 192.168.1.50/helloworld -s
|
||||
```
|
||||
```text
|
||||
<html><body><h1>It works!</h1></body></html>
|
||||
```
|
||||
|
||||
### Firefox browser
|
||||
|
||||
Through using the Firefox web browser, the page accessed is the Nginx deployment.
|
||||
|
||||

|
||||
|
||||
### Default
|
||||
To trigger the "default" rule, you can be quite creative there, like using another browser some other tool.
|
||||
|
||||
In my case I will be using the package `wget` as it is more simple for myself.
|
||||
|
||||
|
||||
```shell
|
||||
wget 192.168.1.50/helloworld -O /dev/stdout -q
|
||||
```
|
||||
|
||||
```text
|
||||
Hostname: helloworld-v0-64fc7d6ccb-vdljp
|
||||
IP: 127.0.0.1
|
||||
IP: ::1
|
||||
IP: 172.17.247.19
|
||||
IP: fe80::dc11:59ff:fe15:f6c3
|
||||
RemoteAddr: 127.0.0.6:51179
|
||||
GET / HTTP/1.1
|
||||
Host: 192.168.1.50
|
||||
User-Agent: Wget/1.21.3
|
||||
Accept: */*
|
||||
Accept-Encoding: identity
|
||||
X-B3-Parentspanid: 7a17876e5182b4a1
|
||||
X-B3-Sampled: 0
|
||||
X-B3-Spanid: 0aa085397844c696
|
||||
X-B3-Traceid: 3c9474b384a9f33c7a17876e5182b4a1
|
||||
X-Envoy-Attempt-Count: 1
|
||||
X-Envoy-Internal: true
|
||||
X-Envoy-Original-Path: /helloworld
|
||||
X-Forwarded-Client-Cert: By=spiffe://cluster.local/ns/default/sa/default;Hash=bf05b3ab5654afeecc50ea6b136708517bcfdec088978a2a675759d52aa207aa;Subject="";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account
|
||||
X-Forwarded-For: 192.168.1.10
|
||||
X-Forwarded-Proto: http
|
||||
X-Request-Id: 46d7dbe8-ba46-4703-b1a3-cdecf2f93d1e
|
||||
```
|
||||
|
||||
|
||||
## Cleanup
|
||||
|
||||
Finally, a cleanup from the resources deployed.
|
||||
|
||||
```shell
|
||||
kubectl delete -f ./
|
||||
```
|
||||
```text
|
||||
deployment.apps "helloworld-v0" deleted
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Links of interest
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/virtual-service/
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#
|
13
02-Traffic_management/01-header_routing/Service.yaml
Normal file
13
02-Traffic_management/01-header_routing/Service.yaml
Normal 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
|
39
02-Traffic_management/01-2_deployments_method/gateway.yaml → 02-Traffic_management/01-header_routing/VirtualService.yaml
Executable file → Normal file
39
02-Traffic_management/01-2_deployments_method/gateway.yaml → 02-Traffic_management/01-header_routing/VirtualService.yaml
Executable file → Normal file
@ -1,19 +1,3 @@
|
||||
# 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:
|
||||
@ -56,8 +40,8 @@ spec:
|
||||
uri: "/"
|
||||
- name: default
|
||||
match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
@ -65,21 +49,4 @@ spec:
|
||||
number: 80
|
||||
subset: default
|
||||
rewrite:
|
||||
uri: "/"
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld.default.svc.cluster.local # Destination that will "interject"
|
||||
spec:
|
||||
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
|
||||
subsets:
|
||||
- name: default
|
||||
labels:
|
||||
version: v0
|
||||
- name: nginx
|
||||
labels:
|
||||
version: v1
|
||||
- name: apache
|
||||
labels:
|
||||
version: v2
|
||||
uri: "/"
|
BIN
02-Traffic_management/01-header_routing/src/firefox.png
Normal file
BIN
02-Traffic_management/01-header_routing/src/firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
@ -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:
|
@ -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:
|
||||
- "*"
|
@ -1,7 +1,282 @@
|
||||
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPDirectResponse
|
||||
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPBody
|
||||
---
|
||||
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 return a specific response to the client with the contents of our choice.
|
||||
|
||||
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)
|
||||
|
||||
# Configuration
|
||||
|
||||
## Service
|
||||
|
||||
Creates a service named `helloworld`.
|
||||
|
||||
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
selector:
|
||||
app: helloworld
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
Deploys a Nginx server that listens for the port `80`.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: helloworld-nginx
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helloworld
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: helloworld
|
||||
spec:
|
||||
containers:
|
||||
- name: helloworld
|
||||
image: nginx
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent #Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
## Gateway
|
||||
|
||||
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
|
||||
|
||||
It doesn't filter for any specific host.
|
||||
|
||||
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
|
||||
|
||||
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use istio default controller
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
```
|
||||
|
||||
## VirtualService
|
||||
|
||||
The configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host.
|
||||
|
||||
We configure 2 rules for HTTP traffic (this includes `HTTPS` and `HTTP2`, this will be my last warning about this).
|
||||
|
||||
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`.
|
||||
|
||||
The second rule, which will manage the rest of the traffic, will return a response with status code `404`, and body content set to `Page Not Found`.
|
||||
|
||||
Additionally, for consistency and good practices purposes, we also specified the content type of the page to `text/plain`.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- name: helloworld
|
||||
match:
|
||||
- uri:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
||||
uri: "/"
|
||||
- name: default
|
||||
directResponse:
|
||||
status: 404
|
||||
body:
|
||||
string: "Page Not Found"
|
||||
headers:
|
||||
response:
|
||||
set:
|
||||
content-type: "text/plain"
|
||||
```
|
||||
|
||||
# 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 pods to be ready
|
||||
|
||||
Wait for the Apache and Nginx deployments 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 9s
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
As expected, we receive the contents from the Nginx contents
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
|
||||
```
|
||||
```text
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
### other paths
|
||||
|
||||
#### /
|
||||
|
||||
We receive the contents "Page Not Found".
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/
|
||||
```
|
||||
|
||||
```text
|
||||
Page Not Found
|
||||
```
|
||||
|
||||
Checking the headers, we also can see the status code is set to `404`, as well of the content-type we specified on the [VirtualService configuration](#virtualservice).
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/ -I
|
||||
```
|
||||
|
||||
```text
|
||||
HTTP/1.1 404 Not Found
|
||||
content-type: text/plain
|
||||
content-length: 14
|
||||
date: Thu, 04 May 2023 01:18:50 GMT
|
||||
server: istio-envoy
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### /found
|
||||
|
||||
We can confirm that this behavior applies to other paths (as it is matching the "default" rule we set in [VirtualService configuration]).
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/found
|
||||
```
|
||||
|
||||
```text
|
||||
Page Not Found
|
||||
```
|
||||
|
||||
```shell
|
||||
curl 192.168.1.50/found -I
|
||||
```
|
||||
|
||||
```text
|
||||
HTTP/1.1 404 Not Found
|
||||
content-type: text/plain
|
||||
content-length: 14
|
||||
date: Thu, 04 May 2023 01:20:40 GMT
|
||||
server: istio-envoy
|
||||
```
|
||||
|
||||
|
||||
## 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/virtual-service/#HTTPDirectResponse
|
||||
|
||||
- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPBody
|
||||
|
@ -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
|
@ -1,19 +1,3 @@
|
||||
# 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/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
@ -30,7 +14,7 @@ spec:
|
||||
exact: /helloworld
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 80
|
||||
rewrite:
|
@ -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
|
@ -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:
|
@ -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
|
||||
|
13
02-Traffic_management/03-HTTPRewrite/Service.yaml
Normal file
13
02-Traffic_management/03-HTTPRewrite/Service.yaml
Normal 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
|
26
02-Traffic_management/03-HTTPRewrite/VirtualService.yaml
Normal file
26
02-Traffic_management/03-HTTPRewrite/VirtualService.yaml
Normal 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
|
@ -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
|
@ -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: "/"
|
14
02-Traffic_management/04-HTTPRedirect/Gateway.yaml
Executable file
14
02-Traffic_management/04-HTTPRedirect/Gateway.yaml
Executable 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:
|
||||
- "*"
|
@ -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/
|
||||
```
|
||||

|
||||
|
||||
### /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
|
||||
```
|
||||
|
||||

|
||||
|
||||
```shell
|
||||
firefox 192.168.1.50/wiki/Gitea
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
33
02-Traffic_management/04-HTTPRedirect/VirtualService.yaml
Normal file
33
02-Traffic_management/04-HTTPRedirect/VirtualService.yaml
Normal 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"
|
@ -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
|
@ -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"
|
BIN
02-Traffic_management/04-HTTPRedirect/src/img.png
Normal file
BIN
02-Traffic_management/04-HTTPRedirect/src/img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 279 KiB |
BIN
02-Traffic_management/04-HTTPRedirect/src/img_1.png
Normal file
BIN
02-Traffic_management/04-HTTPRedirect/src/img_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
02-Traffic_management/04-HTTPRedirect/src/img_2.png
Normal file
BIN
02-Traffic_management/04-HTTPRedirect/src/img_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
@ -1,7 +0,0 @@
|
||||
# Continues from
|
||||
|
||||
- 01-hello_world_1_service_1_deployment
|
||||
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Delay
|
||||
|
@ -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
|
@ -1,11 +0,0 @@
|
||||
# Continues from
|
||||
|
||||
- 05a-FaultInjection-delay
|
||||
|
||||
|
||||
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Abort
|
||||
|
||||
|
||||
|
||||
curl 192.168.1.50/helloworld -I
|
||||
|
@ -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
|
@ -1,57 +0,0 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: helloworld-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "*"
|
||||
- port:
|
||||
number: 443
|
||||
name: https
|
||||
protocol: HTTPS
|
||||
hosts:
|
||||
- "*"
|
||||
tls:
|
||||
credentialName: my-tls-cert-secret
|
||||
mode: SIMPLE
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: helloworld-vs
|
||||
spec:
|
||||
hosts:
|
||||
- "*"
|
||||
gateways:
|
||||
- helloworld-gateway
|
||||
http:
|
||||
- name: https-vs
|
||||
match:
|
||||
- port: 80
|
||||
- port: 443
|
||||
route:
|
||||
- destination:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
port:
|
||||
number: 8443
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: helloworld
|
||||
namespace: default
|
||||
spec:
|
||||
host: helloworld.default.svc.cluster.local
|
||||
trafficPolicy:
|
||||
portLevelSettings:
|
||||
- port:
|
||||
number: 8443
|
||||
tls:
|
||||
mode: SIMPLE
|
@ -1,46 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- port: 8080
|
||||
name: http-web
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
- port: 8443
|
||||
name: https-web
|
||||
targetPort: 443
|
||||
protocol: TCP
|
||||
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: oriolfilter/https-nginx-demo
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 443
|
@ -1,73 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helloworld
|
||||
labels:
|
||||
app: helloworld
|
||||
service: helloworld
|
||||
spec:
|
||||
ports:
|
||||
- name: https
|
||||
port: 8443
|
||||
targetPort: 443
|
||||
protocol: TCP
|
||||
appProtocol: HTTPS
|
||||
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: oriolfilter/https-nginx-demo
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
imagePullPolicy: Always #Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 443
|
||||
#---
|
||||
#apiVersion: apps/v1
|
||||
#kind: Deployment
|
||||
#metadata:
|
||||
# name: nginx
|
||||
# labels:
|
||||
# app: nginx
|
||||
# version: v1
|
||||
#spec:
|
||||
# replicas: 1
|
||||
# selector:
|
||||
# matchLabels:
|
||||
# app: nginx
|
||||
# version: v1
|
||||
# template:
|
||||
# metadata:
|
||||
# labels:
|
||||
# app: nginx
|
||||
# version: v1
|
||||
# spec:
|
||||
# # serviceAccountName: istio-helloworld
|
||||
# containers:
|
||||
# - name: nginx
|
||||
# image: nginx
|
||||
# resources:
|
||||
# requests:
|
||||
# cpu: "100m"
|
||||
# imagePullPolicy: IfNotPresent
|
||||
# ports:
|
||||
# - containerPort: 80
|
@ -1,23 +1,12 @@
|
||||
# Description
|
||||
|
||||
This section involves the configuration of `Virtual Service` objects.
|
||||
|
||||
# Examples
|
||||
|
||||
(almost) ALL NEEDS DOCUMENTATION / REVIEW
|
||||
|
||||
- 01-2_deployments_method
|
||||
- 01-header_routing
|
||||
- 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.
|
||||
|
||||
|
@ -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:
|
14
03-Gateway_Ingress/01-Host_Based_Routing/Gateway.yaml
Normal file
14
03-Gateway_Ingress/01-Host_Based_Routing/Gateway.yaml
Normal 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"
|
238
03-Gateway_Ingress/01-Host_Based_Routing/README.md
Executable file
238
03-Gateway_Ingress/01-Host_Based_Routing/README.md
Executable 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/
|
13
03-Gateway_Ingress/01-Host_Based_Routing/Service.yaml
Normal file
13
03-Gateway_Ingress/01-Host_Based_Routing/Service.yaml
Normal 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
|
20
03-Gateway_Ingress/01-Host_Based_Routing/VirtualService.yaml
Executable file
20
03-Gateway_Ingress/01-Host_Based_Routing/VirtualService.yaml
Executable 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: "/"
|
4
03-Gateway_Ingress/02-Restrict_Namespaces/01-namespace.yaml
Executable file
4
03-Gateway_Ingress/02-Restrict_Namespaces/01-namespace.yaml
Executable file
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: foo
|
25
03-Gateway_Ingress/02-Restrict_Namespaces/Deployment.yaml
Executable file
25
03-Gateway_Ingress/02-Restrict_Namespaces/Deployment.yaml
Executable 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
|
14
03-Gateway_Ingress/02-Restrict_Namespaces/Gateway.yaml
Normal file
14
03-Gateway_Ingress/02-Restrict_Namespaces/Gateway.yaml
Normal 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/*"
|
294
03-Gateway_Ingress/02-Restrict_Namespaces/README.md
Executable file
294
03-Gateway_Ingress/02-Restrict_Namespaces/README.md
Executable 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/
|
13
03-Gateway_Ingress/02-Restrict_Namespaces/Service.yaml
Normal file
13
03-Gateway_Ingress/02-Restrict_Namespaces/Service.yaml
Normal 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
|
43
03-Gateway_Ingress/02-Restrict_Namespaces/VirtualService.yaml
Executable file
43
03-Gateway_Ingress/02-Restrict_Namespaces/VirtualService.yaml
Executable 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: "/"
|
25
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Deployment.yaml
Executable file
25
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Deployment.yaml
Executable 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
|
17
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Gateway.yaml
Executable file
17
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Gateway.yaml
Executable 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
|
@ -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_Started/01-hello_world_1_service_1_deployment)
|
||||
|
||||
# Description
|
||||
|
13
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Service.yaml
Normal file
13
03-Gateway_Ingress/03-HTTPS-Gateway-Simple-TLS/Service.yaml
Normal 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
|
@ -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: "/"
|
25
03-Gateway_Ingress/04a-HTTPS-min-TLS-version/Deployment.yaml
Executable file
25
03-Gateway_Ingress/04a-HTTPS-min-TLS-version/Deployment.yaml
Executable 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
|
@ -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: "/"
|
@ -5,7 +5,7 @@ include_toc: true
|
||||
|
||||
# Based on
|
||||
|
||||
- [07-HTTPS-Gateway-Simple-TLS](../07-HTTPS-Gateway-Simple-TLS)
|
||||
- [03-HTTPS-Gateway-Simple-TLS](../03-HTTPS-Gateway-Simple-TLS)
|
||||
|
||||
# Description
|
||||
|
13
03-Gateway_Ingress/04a-HTTPS-min-TLS-version/Service.yaml
Normal file
13
03-Gateway_Ingress/04a-HTTPS-min-TLS-version/Service.yaml
Normal 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
|
@ -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: "/"
|
25
03-Gateway_Ingress/04b-HTTPS-max-TLS-version/Deployment.yaml
Executable file
25
03-Gateway_Ingress/04b-HTTPS-max-TLS-version/Deployment.yaml
Executable 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
|
@ -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: "/"
|
@ -5,7 +5,7 @@ include_toc: true
|
||||
|
||||
# Based on
|
||||
|
||||
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
|
||||
- [04a-HTTPS-min-TLS-version](../04a-HTTPS-min-TLS-version)
|
||||
|
||||
# Description
|
||||
|
13
03-Gateway_Ingress/04b-HTTPS-max-TLS-version/Service.yaml
Normal file
13
03-Gateway_Ingress/04b-HTTPS-max-TLS-version/Service.yaml
Normal 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
|
@ -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: "/"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user