Compare commits

..

145 Commits

Author SHA1 Message Date
a4419990ea Merge branch 'main' into dev 2024-01-15 21:45:39 +01:00
990bada6e1 Merge pull request 'dev2_Jan_15_2024' (#67) from dev2_Jan_15_2024 into dev
Reviewed-on: #67
2024-01-15 21:44:43 +01:00
e088cf6659 Merge branch 'dev' into dev2_Jan_15_2024 2024-01-15 21:44:34 +01:00
ee13b20458 Fixed lowercase typo on folder name.
Quick made the README.md
2024-01-15 21:36:27 +01:00
2582e15e1a Added couple relevant links to the topic, nothing else. 2024-01-15 21:32:45 +01:00
404c036883 Deleted/Moved to main 2024-01-15 21:32:29 +01:00
6cb3c9fa50 Added simple monitoring examples.
They are based off Helm PrometheusStack community Chart.
2024-01-15 21:32:14 +01:00
f86ac97255 Merge pull request 'dev - 2023/10/14' (#66) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/66
2023-10-14 13:06:28 +02:00
2fb608c5bd Merge branch 'main' into dev 2023-10-14 13:06:17 +02:00
942a3bf8ae Updated Global README.md 2023-10-14 13:03:28 +02:00
74e5b9d5f0 Inserted into the respective directory. 2023-10-14 13:01:46 +02:00
7e004697a9 Fixed link refference 2023-10-14 13:00:52 +02:00
c02a355a95 Renamed folder 2023-10-14 13:00:22 +02:00
d2b1dc2284 Speed documented 2023-10-14 12:59:07 +02:00
f0ce2ae68d Fixed format 2023-10-14 12:50:13 +02:00
b6657bdd4c Renamed files and deglossed it's contents. 2023-10-14 12:30:39 +02:00
68efcde1fa Added a section README.md to the sections:
- 90-MixConfigs
- 99-resources
2023-10-14 12:22:17 +02:00
1cf75d5902 Deglossed the files. 2023-10-14 12:21:42 +02:00
df8eea778c Documented examples from 11-Fault_Injection:
- 01-FaultInjection-delay
- 02-FaultInjection-abort

Added a section README.md to the section:

- 11-Fault_Injection
2023-10-14 12:11:34 +02:00
c1aec3ae4c Renamed file to capitalized first letter. 2023-10-14 11:21:30 +02:00
957dbfcf84 Updated global README.md 2023-10-14 11:19:29 +02:00
e883755680 Added section README.md for:
- 10-mTLS_PeerAuthentication

Renamed its files to use a capital letter at the start of the files.
2023-10-14 11:14:19 +02:00
0a1e36dcaf Added section README.md for:
- 09-Ingress
2023-10-14 11:08:51 +02:00
40fe16c040 Renamed folder 2023-10-14 11:06:55 +02:00
b440efb6b2 Renamed directories 2023-10-14 11:02:16 +02:00
4e66d65096 Fixed refference 2023-10-14 11:01:51 +02:00
16f7ab6178 Improved Readme slightly. 2023-10-14 11:00:10 +02:00
d117481a5b Documented Section Readme for:
- 08-AuthorizationPolicy

Also, (speed) documented its examples.
2023-10-14 10:59:33 +02:00
84b71d9751 Minor update to the global README.md file. 2023-10-14 10:27:11 +02:00
fd3f9b6e95 Didn't add the examples section. 2023-10-14 10:25:13 +02:00
de4ae7dd09 Documented 06_Envoy examples:
- 01-Envoy-add-response-headers
- 02-envoy-logging

Added section README.md to:
- 05-Sidecar
- 06-Envoy
2023-10-14 10:19:01 +02:00
6aa4cb2c03 Updated global README 2023-10-14 06:46:54 +02:00
8c1288f8d1 Set up the base of the README 2023-10-14 06:43:07 +02:00
23eb763524 Fixed typos in 3 section references. 2023-10-14 06:42:54 +02:00
87aab0c9be Proceeding with the README from each section. 2023-10-14 06:29:49 +02:00
6ff0ce9ee8 Quality improvements.
Fixed broken URL or typos in the directory references.

As well proceeding with the README from each section.
2023-10-14 06:21:26 +02:00
439d62b718 Merge remote-tracking branch 'origin/dev' into dev 2023-07-01 17:35:00 +02:00
73d4918f2c deleted doomy file. 2023-07-01 17:33:59 +02:00
93018487e6 deleted doomy file. 2023-07-01 17:33:20 +02:00
1542aaafcc Merge pull request 'dev - mid update' (#63) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/63
2023-07-01 14:21:59 +00:00
f8fd8c6ce5 Merge branch 'main' into dev 2023-07-01 14:21:19 +00:00
9d7cae15f8 deleted doomy file. 2023-07-01 16:17:57 +02:00
f068de7dcc quality improvement on the README.md 2023-07-01 16:07:15 +02:00
eb001e704a fixed README.md tree 2023-07-01 16:05:54 +02:00
f5b24a9a17 Added Undocumented Minecraft example. 2023-07-01 16:05:10 +02:00
78f09bdc08 Updated README.md 2023-07-01 16:03:58 +02:00
07bca8cce1 Renamed folder
Small quality improvement
2023-07-01 16:02:52 +02:00
e9af4daeee Renamed folder
Small quality improvement
2023-07-01 16:02:18 +02:00
be2375c14c Fixed link reference 2023-07-01 15:56:27 +02:00
b7de0f8205 Sorted some folders.
Quality improvements for 01-Service_Entry
2023-07-01 15:54:38 +02:00
918f480319 Seems like I moved some files around (it's been a while)
Also have documented the ingress example regarding installing a Istio Ingress Gateway Load Balancer.
2023-07-01 15:40:15 +02:00
703d380bca added a final dot... 2023-05-15 15:36:08 +02:00
4681d98ae7 fixed markdown checkboxes 2023-05-15 15:36:00 +02:00
fe4cfa88a6 Merge pull request '15/May/2023' (#62) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/62
2023-05-15 13:33:16 +00:00
88e71e8c5b Quality improvements. 2023-05-15 15:28:37 +02:00
747c3f1171 Documented 02-egress-proxy.
Not to brag, BUT I believe it's fairly godlike.
2023-05-15 15:22:43 +02:00
6c6f968097 Deleted a useless line. 2023-05-15 15:19:48 +02:00
8ba4495ea7 Documented 02-egress-proxy.
Not to brag, BUT I believe it's fairly godlike.
2023-05-15 15:19:28 +02:00
9dbcf712de Added a link.
Added the logs entry of `istio-proxy` container from a pod.
2023-05-15 02:48:49 +02:00
6153529f9a Added a link 2023-05-15 02:47:19 +02:00
38a7b70758 removed an space, wow 2023-05-11 23:23:46 +02:00
ca68dde6ea Merge remote-tracking branch 'origin/dev' into dev 2023-05-11 10:11:32 +02:00
57e858f416 01-ingress-proxy-forwarding documented. 2023-05-11 10:10:56 +02:00
faf8b08e77 Assigned the number 12 to CircuitBreaking 2023-05-11 08:24:21 +02:00
9fbc2c5f1f spelling fix 2023-05-11 08:21:42 +02:00
4940fdd3b7 renamed "Target_Namespaces" to 02-Restrict_Namespace, documented 2023-05-11 07:46:38 +02:00
4bd53c84de 02-Target_Namespace documented 2023-05-11 07:44:53 +02:00
5059a13888 01-Host_Based_Routing documented 2023-05-10 10:51:56 +02:00
c7c1f8cb9c Files rebasing 2023-05-10 10:15:00 +02:00
fb34758197 Files rebasing 2023-05-10 01:42:54 +02:00
54025a55dd 04-HTTPRedirect 2023-05-05 02:33:16 +02:00
6b0b62b6a9 04-HTTPRedirect 2023-05-05 02:32:06 +02:00
113ed75177 03-HTTPRewrite documented 2023-05-05 01:42:27 +02:00
f3fa2372fe Spelling correction 2023-05-05 01:41:47 +02:00
4e0f4ba05d 03-HTTPRewrite documented 2023-05-05 01:41:42 +02:00
b37c523c39 Spelling correction 2023-05-05 01:33:08 +02:00
f52e1125a7 Spelling correction 2023-05-05 01:26:51 +02:00
d3d730b34c Merge pull request 'Examples update 04/05/2023' (#48) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/48
2023-05-04 01:27:31 +00:00
73b4959b45 02-DirectResponse-HTTP-Body documented 2023-05-04 03:24:28 +02:00
138b3a01f2 Quality improvement 2023-05-04 03:12:54 +02:00
7e5c9a89a4 Quality improvement 2023-05-04 03:12:28 +02:00
1b1ca0dbd8 Quality improvement 2023-05-04 03:03:59 +02:00
adb600110d Renamed some folders.
Documented `01-header_routing`.

Smaller quality improvements in order files.
2023-05-04 03:01:27 +02:00
ce4cb196eb Merge pull request 'Cleanup and minimal documentation added.' (#46) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/Istio_Examples/pulls/46
2023-05-01 00:08:05 +00:00
b6f23cbbe6 Merge remote-tracking branch 'origin/dev' into dev 2023-05-01 02:06:18 +02:00
4bb925e1cd Merge branch 'main' into dev 2023-05-01 00:05:02 +00:00
0cc6c09c53 Added directories to the main README.md 2023-05-01 01:48:19 +02:00
309a9dded7 Temporal organization 2023-05-01 01:46:59 +02:00
3739cda159 04-hello_world_1_service_2_deployments_managed_version_foo_namespace documented 2023-05-01 01:41:26 +02:00
65e0afc0be 04-hello_world_1_service_2_deployments_managed_version_foo_namespace docummented 2023-05-01 01:39:56 +02:00
03a604c91e Refractoring and some documentation performed. 2023-05-01 01:06:33 +02:00
b48837e5c0 Small cleanup 2023-04-30 22:54:38 +02:00
14e987ea95 Small cleanup 2023-04-30 22:42:03 +02:00
6c9d5604e2 Merge pull request 'dev' (#39) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/kubexamples/pulls/39
2023-04-30 20:36:51 +00:00
78008fcfda Merge branch 'main' into dev 2023-04-30 20:36:35 +00:00
54538ebfac Circuit Breaking uploaded 2023-04-30 22:32:06 +02:00
e1749edab4 Example set and documented. 2023-04-28 06:06:32 +02:00
2d61bd8617 quality improvement. 2023-04-28 06:03:44 +02:00
953943925e quality improvement. 2023-04-28 05:41:10 +02:00
79f819272a fixed spelling mistake 2023-04-28 05:30:58 +02:00
a522803324 Added cleanup field 2023-04-28 05:29:00 +02:00
135d7afaf1 quality improvements 2023-04-28 05:25:41 +02:00
26d947610a Set and documented. 2023-04-28 05:23:58 +02:00
b506b32229 cleanup 2023-04-28 04:11:54 +02:00
a5c1039583 Documented the example 2023-04-28 04:11:49 +02:00
828c3beb11 temporal backup + moved a folder. 2023-04-27 19:03:03 +02:00
d9c3fa6c4c Disable mTLS set. 2023-04-27 07:33:20 +02:00
2498a559e9 renamed folder 2023-04-27 04:27:25 +02:00
6121d9c0c8 added some text 2023-04-27 03:47:41 +02:00
b9521a27d1 Replaced "changelog" for "configuration" 2023-04-27 03:27:12 +02:00
1d10285d3d added "GET LB IP" step 2023-04-27 03:26:58 +02:00
20d69656fd Added example about targeting deployments through the use of selectors (targeting labels) 2023-04-27 03:26:39 +02:00
9ee02f7713 Added example about targeting deployments through the use of selectors (targeting labels) 2023-04-27 03:26:32 +02:00
2be63317fa fixed spelling mistake 2023-04-27 03:25:22 +02:00
ab5b775534 Deleted audit, from my understanding I need some sort of stackdriver and dont' wanna bother with it rn 2023-04-27 03:24:52 +02:00
d7d3909499 Directory renaming 2023-04-26 02:36:34 +02:00
39a7c12450 Directory renaming 2023-04-26 02:36:23 +02:00
7ab9735f15 renamed folder 2023-04-26 02:21:59 +02:00
585a76de61 updated contents 2023-04-26 02:20:29 +02:00
8f730a311e Merge remote-tracking branch 'origin/dev' into dev 2023-04-26 02:09:45 +02:00
3d8f118dd7 HTTP to HTTPS documented. 2023-04-26 02:08:15 +02:00
2a523c32e8 Merge pull request 'dev' (#27) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/kubexamples/pulls/27
2023-04-25 06:17:58 +00:00
3d04f96b01 Merge branch 'main' into dev 2023-04-25 06:17:18 +00:00
27030b4c58 Deleted HTTP2 attempt.
Moving on.
2023-04-25 08:03:17 +02:00
9d0f6637b8 fixed link refference 2023-04-25 06:58:48 +02:00
3c9ea0d1f8 Fixed broken links (reference && dockerhub image). 2023-04-25 06:53:07 +02:00
5e0abdebd4 HTTPS backend documented, need to fix 2 refference links (unless I set them right already ) 2023-04-25 06:45:34 +02:00
2b7f83c208 TLS Passthrough documented. This commit has other files, I guess I did some minor slightly modifications and nothing relevant so far so all commited. 2023-04-25 05:46:03 +02:00
be18d7695b Reorganized the files a bit while I am documenting them. 2023-04-25 03:54:12 +02:00
000992a3d1 Replaced the classic get LB through listing svc and specifying the name, by using the istio label set in the gateway configuration. 2023-04-25 03:43:18 +02:00
cdff7c620c Documented 02-Traffic_management/09-TCP-FORWARDING 2023-04-25 03:42:10 +02:00
2899422462 Documented 02-Traffic_management/09-TCP-FORWARDING 2023-04-25 03:41:59 +02:00
2dab5274ca Removed old https-apache-demo for recent https-nginx-demo image. 2023-04-25 03:06:09 +02:00
73041ccc49 Residual cleanup, those where uploaded right after finishing the tests. 2023-04-25 03:05:24 +02:00
96ef03948d Upload 2023-04-25 03:05:00 +02:00
0ec26ba915 residual cleanup 2023-04-25 03:04:51 +02:00
68af7eccd1 Added a link of interest that I found relevant back in the day 2023-04-25 02:59:41 +02:00
31418fed6c Added some text 2023-04-25 02:59:20 +02:00
e76729c5de Documented the container.
Uploaded multiarch to dockerhub.

Might want to create a different repo to allow people to just clone it. Not my concern rn, nor for a while.
2023-04-25 02:58:47 +02:00
4bb07eebce small backup cause things work and scared of proceeding without modifying anything, also say hi to my registry at home 2023-04-25 00:16:52 +02:00
de80fadf2a Trying to get HTTP2 to work, tested a TCP LB, and it worked. 2023-04-24 06:03:45 +02:00
e6c265c74f added an example 2023-04-24 00:22:32 +02:00
d4fd40e7e3 fixed a typo 2023-04-24 00:22:19 +02:00
f9147a9065 Quality improvements 2023-04-23 08:57:44 +02:00
f5fb046ddb Merge pull request 'dev' (#19) from dev into main
Reviewed-on: https://gitea.filterhome.xyz/ofilter/kubexamples/pulls/19
2023-04-23 06:52:40 +00:00
297 changed files with 13017 additions and 4307 deletions

View File

@ -0,0 +1,3 @@
https://github.com/istio-ecosystem/wasm-extensions
https://github.com/istio-ecosystem/wasm-extensions/tree/master/extensions/basic_auth

View File

@ -1,11 +1,4 @@
# Continues from
- 01-hello_world_1_service_1_deployment
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.

View File

@ -4,6 +4,61 @@ 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
@ -39,48 +94,54 @@ istioctl analyze -n istio-operator
Info [IST0102] (Namespace istio-operator) The namespace is not enabled for Istio injection. Run 'kubectl label namespace istio-operator istio-injection=enabled' to enable it, or 'kubectl label namespace istio-operator istio-injection=disabled' to explicitly mark it as not needing injection.
```
## Example of spotting a misconfiguration
In this example, I have configured the gateway to listen to a port that currently is not open in the Isito Load Balancer selected.
```shell
istioctl analyze
```
```text
Warning [IST0104] (Gateway default/helloworld-gateway) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 81)
```
# Start the packet capture process on the istio-proxy container from a pod.
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 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
@ -160,4 +221,8 @@ InboundPassthroughClusterIpv4 - -
PassthroughCluster - - - ORIGINAL_DST
agent - - - STATIC
...
```
```
# Other links
## [Debugging with Istio](https://www.istioworkshop.io/12-debugging/01-istioctl-debug-command/)

View File

@ -1,17 +1,3 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:

View File

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

View File

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

View File

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

View File

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

View File

@ -1,25 +1,3 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -36,7 +14,6 @@ spec:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx
@ -63,7 +40,6 @@ spec:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: httpd

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,8 @@
# 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
namespace: default
spec:
hosts:
- "*"
@ -30,7 +15,17 @@ spec:
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: "/"

View File

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

View File

@ -1,29 +1,8 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
namespace: foo
labels:
app: helloworld
version: v1
@ -39,7 +18,6 @@ spec:
app: helloworld
version: v1
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx
@ -54,6 +32,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
namespace: foo
labels:
app: helloworld
version: v2
@ -69,7 +48,6 @@ spec:
app: helloworld
version: v2
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: httpd

View File

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

View File

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

View File

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

View File

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

View File

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

51
01-Getting_Started/README.md Executable file
View 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.

View File

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

View File

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

View File

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

View File

@ -0,0 +1,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.
![firefox.png](./src/firefox.png)
### 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/#

View File

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

View File

@ -1,19 +1,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: "/"

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,17 +1,3 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:

View File

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

View File

@ -0,0 +1,282 @@
---
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
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
It doesn't filter for any specific host.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host.
We configure 2 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

View File

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

View File

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

View File

@ -1,17 +1,3 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -0,0 +1,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
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
It doesn't filter for any specific host.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host.
We configure 2 HTTP rules.
The first rule will match when the requested path is `/helloworld`.
Internally, we will rewrite the URL path, from `/helloworld` to `/`, as otherwise it will result in status code 404 due not containing such destination in the service, since we are using the default Nginx image.
The second rule will math with the path `/norewrite`, and won't have the rewrite URL path setting configured. This rule will be used to compare behaviors.
Both rules will connect with the backend service `helloworld.default.svc.cluster.local` with port `80`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
- match:
- uri:
exact: /norewrite
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-nginx created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
gateway.networking.istio.io/helloworld-gateway created
```
## Wait for the pods to be ready
Wait for the Nginx deployment to be up and ready.
```shell
kubectl get deployment helloworld-nginx -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 2m47s
```
## Test the service
### Get LB IP
To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
On my environment, the IP is the `192.168.1.50`.
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### helloworld
Due to rewriting the URL path internally, we are able to connect to the backend root path (`/`)
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<h1>Welcome to nginx!</h1>
```
### norewrite
As expected, due the backend service not having a destination path named `/norewrite`, we receive a status code 404 as well of their pertinent service error page.
```shell
curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>"
```
```text
<center><h1>404 Not Found</h1></center>
```
## Cleanup`
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-nginx" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRewrite

View File

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

View File

@ -0,0 +1,26 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
- match:
- uri:
exact: /norewrite
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -0,0 +1,12 @@
# Description
This section involves the configuration of `Virtual Service` objects.
# Examples
- 01-header_routing
- 02-DirectResponse-HTTP-Body
- 03-HTTPRewrite
- 04-HTTPRedirect

View File

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

View File

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

View File

@ -0,0 +1,238 @@
---
gitea: none
include_toc: true
---
# Description
This example deploys the same infrastructure as the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), and restricts the access to the gateway based on the domain host from the destination URL.
The domain host targeted will be `my.domain`.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 1 Deployment
Istio resources:
- 1 Gateway
- 1 Virtual Service
> **Note:**\
> I don't intend to explain thing related to Kubernetes unless necessary.
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
The gateway only will allow the traffic that uses as a URL host: `my.domain`.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "my.domain"
```
## VirtualService
The Virtual Service resources are used to route and filter the received traffic from the gateway resources, and route it towards the desired destination.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld` (the full path URL equivalent would be `helloworld.$NAMESPACE.svc.cluster.local`).
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-vs created
```
## Wait for the deployment to be ready
Wait for the Nginx deployment to be up and ready.
```shell
kubectl get deployment helloworld-nginx -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 44s
```
## Test the service
### Get LB IP
To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
On my environment, the IP is the `192.168.1.50`.
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### Curl /helloworld
When performing a curl towards the destination path, as we are not using the domain host specified in the [gateway resource](#gateway), we are failing to match any rule.
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 404 Not Found
date: Wed, 10 May 2023 08:25:26 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl my.domain/helloworld
We can "fake" the destination domain by modifying the `Host` header.
After setting that up, and attempting to curl the destination, we receive a positive response from the Nginx backend.
```shell
curl 192.168.1.50/helloworld -s -HHOST:my.domain | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/gateway/

View File

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

View File

@ -0,0 +1,20 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

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

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

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

View File

@ -0,0 +1,294 @@
---
gitea: none
include_toc: true
---
# Description
This example deploys the same infrastructure as the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), and restrict which `VirtualService` Istio resources can access/select the `Gateway` Istio resource, based on the `VirtualService` namespace.
The domain host targeted will be `my.domain`.
This example configures:
Generic Kubernetes resources:
- 1 Service
- 1 Deployment
- 1 Namespace
Istio resources (`default` namespace):
- 1 Gateway
- Virtual Service
Istio resources (`foo`namespace):
- 1 Virtual Service
> **Note:**\
> I don't intend to explain thing related to Kubernetes unless necessary.
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
# Configuration
## Service
Creates a service named `helloworld`.
This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Deploys a Nginx server that listens for the port `80`.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
```
## Namespace
Creates a namespace named `foo`.
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: foo
```
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
The gateway won't target any specific host domain, yet limits the `VirtualService` Istio resources that can target this gateway, limiting its access to the `VirtualServices` Istio resources created in the `foo` namespace.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-b
protocol: HTTP
hosts:
- "foo/*"
```
## VirtualService
We will create two `VirtualServices` with the same configuration, only difference will be the namespace they are created onto (and the destination path), this will be used to test if the [`Gateway` namespace restriction configured](#gateway) is being applied to the `VirtualService` resources as desired.
On this example we select the gateway `helloworld-gateway`, which is the [gateway that 's described in the `Gateway` section](#gateway).
On this resource, we are also not limiting the incoming traffic to any specific host, allowing for all the incoming traffic to go through the rules set.
Additionally, there will be an internal URL rewrite set, as if the URL is not modified, it would attempt to reach to the `/helloworld` path from the Nginx deployment, which currently has no content and would result in an error code `404` (Not found).
## helloworld-foo
`VirtualService` created in the namespace `foo`.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/helloworld`.
This traffic will be forwarded to the port `80` of the destination service `helloworld.default.svc.cluster.local`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-foo
namespace: foo
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
```
## helloworld-default
`VirtualService` created in the namespace `default`.
Here we created a rule that will be applied on `HTTP` related traffic (including `HTTPS` and `HTTP2`) when the destination path is exactly `/failure`.
This traffic will be forwarded to the port `80` of the destination service `helloworld.default.svc.cluster.local`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-default
namespace: default
spec:
hosts:
- "*"
gateways:
- default/helloworld-gateway
http:
- match:
- uri:
exact: /failure
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy resources
Deploy the resources.
```shell
kubectl apply -f ./
```
```text
namespace/foo created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
virtualservice.networking.istio.io/helloworld-foo created
virtualservice.networking.istio.io/helloworld-default created
```
## Wait for the deployment to be ready
Wait for the Nginx deployment to be up and ready.
```shell
kubectl get deployment helloworld-nginx -w
```
```text
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 44s
```
## Test the service
### Get LB IP
To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
On my environment, the IP is the `192.168.1.50`.
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### Curl /helloworld
When performing a curl towards the destination path, as we are not using the domain host specified in the [gateway resource](#gateway), we are failing to match any rule.
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 404 Not Found
date: Wed, 10 May 2023 08:25:26 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl my.domain/helloworld
We can "fake" the destination domain by modifying the `Host` header.
After setting that up, and attempting to curl the destination, we receive a positive response from the Nginx backend.
```shell
curl 192.168.1.50/helloworld -s -HHOST:my.domain | grep "<title>.*</title>"
```
```text
<title>Welcome to nginx!</title>
```
## Cleanup
Finally, a cleanup from the resources deployed.
```shell
kubectl delete -f ./
```
```text
namespace "foo" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
virtualservice.networking.istio.io "helloworld-foo" deleted
virtualservice.networking.istio.io "helloworld-default" deleted
```
# Links of interest
- https://istio.io/latest/docs/reference/config/networking/gateway/

View File

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

View File

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

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

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

View File

@ -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
@ -147,6 +147,14 @@ x-envoy-upstream-service-time: 96
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
@ -154,12 +162,6 @@ gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
kubectl delete -f ./
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
rm -rv certfolder/
```

View File

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

View File

@ -0,0 +1,20 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -16,24 +16,3 @@ spec:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_3
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -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
@ -152,18 +152,19 @@ x-envoy-upstream-service-time: 13
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
secret "my-tls-cert-secret" deleted
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
rm -rv certfolder/
```
@ -175,4 +176,6 @@ removed directory 'certfolder/'
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://discuss.istio.io/t/minimum-tls-version/5541/3

View File

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

View File

@ -0,0 +1,20 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -16,24 +16,3 @@ spec:
mode: SIMPLE
credentialName: my-tls-cert-secret
maxProtocolVersion: TLSV1_2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -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
@ -15,6 +15,8 @@ The previous example was modified to limit and specify the maximum TLS version.
## Gateway
Gateway has been modified to limit the maximum TLS version to v1.2.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
@ -36,7 +38,6 @@ spec:
maxProtocolVersion: TLSV1_2
```
Gateway has been modified to limit the maximum TLS version to v1.2.
# Walkthrough
@ -149,17 +150,17 @@ curl: (35) OpenSSL/3.0.8: error:0A00042E:SSL routines::tlsv1 alert protocol vers
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
secret "my-tls-cert-secret" deleted
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
rm -rv certfolder/
@ -172,4 +173,6 @@ removed directory 'certfolder/'
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://discuss.istio.io/t/minimum-tls-version/5541/3

View File

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

View File

@ -0,0 +1,20 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -1,18 +1,3 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -31,10 +16,11 @@ spec:
spec:
containers:
- name: helloworld
image: nginx
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,20 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp-1
protocol: TCP
hosts:
- "*"
- port:
number: 443
name: tcp-2
protocol: TCP
hosts:
- "*"

View File

@ -0,0 +1,240 @@
---
gitea: none
include_toc: true
---
# Based on
- [04a-HTTPS-min-TLS-version](../04a-HTTPS-min-TLS-version)
# Description
The previous example was modified to set TCP forwarding towards the backend (HTTP and HTTPS backend).
The backend contains an HTTPS service, which is used to demonstrate how the TCP forwarding is working as intended (aka doesn't disturb HTTP traffic).
The same backend also contains the same service but running as HTTP, and for such has also been set in the gateway to display both working as intended.
Additionally, the backend used, has HTTP2 enable, which also will be used to confirm that it's working as intended.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway has been configured to listen both ports `80` and `443` through the TCP protocol, without any host specified.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp-1
protocol: TCP
hosts:
- "*"
- port:
number: 443
name: tcp-2
protocol: TCP
hosts:
- "*"
```
## Virtual service
Virtual service have 2 rules that perform the same behavior, on different ports.
The rules will receive the traffic and forward it to the destination service and port.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
tcp:
- match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- match:
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## Service
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```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: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentication
```yaml
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```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 HTTP
```shell
curl http://192.168.1.50 -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n'
```
```text
http_version: 1.1
status_code: 426
```
#### curl HTTPS
This already confirms that `HTTP2` is working as intended.
```shell
curl https://192.168.1.50 -ks -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http1.1
```
```text
http_version: 2
status_code: 200
```
#### Curl HTTP2
The previous example already displayed that `HTTP2` is working as intended.
This example is maintained due being explicitly to confirm the `HTTP2` feature.
```shell
curl https://192.168.1.50 -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http2 -sk -o=/dev/null
```
```text
http_version: 2
status_code: 200
```
#### Curl HTTP1.1
We can confirm that `HTTP1.1` also works over `TCP forwarding`.
```shell
curl https://192.168.1.50 -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http1.1 -sk -o=/dev/null
```
```text
http_version: 1.1
status_code: 200
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
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/gateway/#Gateway

View File

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

View File

@ -0,0 +1,24 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
tcp:
- match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- match:
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443

View File

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

View File

@ -0,0 +1,17 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: PASSTHROUGH

View File

@ -0,0 +1,221 @@
---
gitea: none
include_toc: true
---
# Based on
- [05-TCP-FORWARDING](../05-TCP-FORWARDING)
# Description
The previous example was modified set TLS Forwarding for the HTTPS, meaning that the TLS will be terminated by the backend containing a service capable of such.
This requires a deployment with a service HTTPS (as it will need to handle the TLS termination ...).
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway was configured to listen the port `443` for `HTTPS` traffic protocol.
The tls was configured as `PASSTHROUGH`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: PASSTHROUGH
```
## Virtual service
Virtual service expected to receive traffic with designation, the host `lb.net`.
The rule that contains, will receive traffic from the port `443`, with host destination `lb.net`.
The destination of such is the service `helloworld.default.svc.cluster.local`, with port destination 8443.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "lb.net"
gateways:
- helloworld-gateway
tls:
- match:
- port: 443
sniHosts: ["lb.net"]
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## Service
The service will forward incoming TCP traffic from the port `8443`, towards the deployment port `443`.
It's been specified the protocol expected to service, it being `HTTPS`.
```yaml
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
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```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: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```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 HTTPS
Well, it just works.
The `--resolve` flag it's used to "fake" the traffic to match the filters we specified in the `Virtual Service`, specifically the `host` and `hostSNI` fields.
```shell
curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net
```
```text
<h2>Howdy</h2>
```
### curl HTTPS (HEAD)
Here we can spot the following sentence:
- `server: nginx/1.23.4`
This means that the TLS was handled by Nginx (verifying that the `TLS Passthrough` was performed correctly).
If it had been managed by Istio, it would say:
- `server: istio-envoy`
```shell
curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net --HEAD
```
```text
HTTP/2 200
server: nginx/1.23.4
date: Tue, 25 Apr 2023 02:49:33 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
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/gateway/#Gateway
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode

View File

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

View File

@ -0,0 +1,19 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "lb.net"
gateways:
- helloworld-gateway
tls:
- match:
- port: 443
sniHosts: ["lb.net"]
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443

View File

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

View File

@ -0,0 +1,218 @@
---
gitea: none
include_toc: true
---
# Based on
- [03-HTTPS-Gateway-Simple-TLS](../03-HTTPS-Gateway-Simple-TLS)
# Description
This example adds `HTTP` to `HTTPS` redirect at the port `80` of the gateway, which listens for HTTP traffic.
Also contains a listens for `HTTPS` traffic at the port 443, with a self-signed certificate. This will be used to ensure that the redirect is working correctly.
> **NOTE:**\
> This example is kept at minimal, without the need of containing a `Virtual Service`, a `Service` nor a `Deployment/Pod`.
# Configuration applied
## Gateway
The port `80` listens for any host, expecting `HTTP` traffic.\
As `tls.httpsRedirect` is set to `true`, the incoming traffic will be redirected to `HTTPS`, effectively enabling the `HTTP` to `HTTPS` redirect.
The port `443` is expecting traffic that use the `HTTPS` protocol, without being limited to specific hosts.\
The TLS configuration is set to simple, and the credentials (the object that contains the certificates/TLS configuration) is set to `my-tls-cert-secret`.
```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:
- "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
```
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
gateway.networking.istio.io/helloworld-gateway created
```
## Test the service
### Get LB IP
```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 --HEAD
We receive the status message `301 Moved Permanently`.
This points that we are being redirected somewhere. By default, `curl` doesn't follow the redirects.
To confirm the redirect is being performed towards the `HTTPS` service, we allow `curl` to follow redirects.
```shell
curl http://192.168.1.50 -I
```
```text
HTTP/1.1 301 Moved Permanently
location: https://192.168.1.50/
date: Tue, 25 Apr 2023 23:59:34 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl --HEAD follow redirects
Allowing `curl` to follow redirects, we notice the following output:
- First we receive the same message from before, as we connected to the same service.
- Afterwards we are met with a status code `404`, which is expected as we don't have any service configured behind this gateway.
> **NOTE:**\
> Due using a self-signed certificate, had to allow accessing "insecure" `HTTPS` destinations.
```shell
curl http://192.168.1.50 -I -L -k
```
```text
HTTP/1.1 301 Moved Permanently
location: https://192.168.1.50/
date: Wed, 26 Apr 2023 00:05:24 GMT
server: istio-envoy
transfer-encoding: chunked
HTTP/2 404
date: Wed, 26 Apr 2023 00:05:24 GMT
server: istio-envoy
```
## Cleanup
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
gateway.networking.istio.io "helloworld-gateway" deleted
```
```shell
rm -rv certfolder/
```
```text
removed 'certfolder/istio.cert.key'
removed 'certfolder/istio.cert.crt'
removed directory 'certfolder/'
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings

View File

@ -0,0 +1,12 @@
# Description
This section focuses (but not limited to) on the configuration of `gateway` objects, providing examples of instances regarding how to limit to which `VirtualService` objects a `Gateway` object can connect to, regarding how to configure a HTTP to HTTPS redirect, or it's TLS configuration.
# Examples
- 01-header_routing
- 02-DirectResponse-HTTP-Body
- 03-HTTPRewrite
- 04-HTTPRedirect

View File

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

View File

@ -0,0 +1,205 @@
# Description
This example uses a resource `ServiceEntry` to "integrate" external resources into our `Istio Service Mesh`.
It also explores the different behaviors between specifying the destination URL on the headers or not.
The following page has been used for testing purposes:
- info.cern.ch
> **Quick disclaimer**:\
> I have no relation with that page.
# Configuration
## ServiceEntry
This `ServiceEntry` resource, defines as a destination the URL `info.cern.ch`.
Note that location is set to `MESH_EXTERNAL` and that the resolution is set to `DNS`, this means that the resource is external to ou `Istio Service Mesh`, and the URL will be resolved through `DNS`
Bear in mind that when Istio is communicating with resources externals to the mesh, `mTLS` is disabled.
Also, policy enforcement is performed in the client side instead of the server side.
> **Note:**/
> For more information regarding the `resolution` field or the `location` field, refer to the following official Istio documentations:\
> - [ServiceEntry.Location](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location)\
> - [ServiceEntry.Resolution](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Resolution)
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-cern-service
spec:
hosts:
- info.cern.ch
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
```
## Gateway
Listens for `HTTP` traffic at the port `80` without limiting to any host.
```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
There has been configured 2 paths:
- "/external"
- "/external-noh"
Both routes will forward the request towards the destination URL `info.cern.ch`.
Highlight that the destination is `info.cern.ch`, which is the same as the contents set on the field `host` from the [ServiceEntry resource configured above](#serviceentry).
The difference between `/external` and `/external-noh` is that the first path will contain a header named `HOST`, with the contents set to `info.cern.ch`, it being the URL from the external service.
On the [Walkthrough](#walkthrough) section we will observe the different behaviors of these paths, being the only difference the header attributed.
Also, we have set a timeout of 3 seconds towards the external services.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
headers:
request:
set:
HOST: "info.cern.ch"
- name: https-external-service-without-headers
timeout: 3s
match:
- uri:
exact: "/external-noh"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
serviceentry.networking.istio.io/external-cern-service created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```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
```
### /external
We can visualize the page contents without issues, nothing to highlight.
```shell
curl 192.168.1.50/external
```
```text
<html><head></head><body><header>
<title>http://info.cern.ch</title>
</header>
<h1>http://info.cern.ch - home of the first website</h1>
<p>From here you can:</p>
<ul>
<li><a href="http://info.cern.ch/hypertext/WWW/TheProject.html">Browse the first website</a></li>
<li><a href="http://line-mode.cern.ch/www/hypertext/WWW/TheProject.html">Browse the first website using the line-mode browser simulator</a></li>
<li><a href="http://home.web.cern.ch/topics/birth-web">Learn about the birth of the web</a></li>
<li><a href="http://home.web.cern.ch/about">Learn about CERN, the physics laboratory where the web was born</a></li>
</ul>
</body></html>
```
### /external-noh
We don't receive any output.
Even if we resolve the destination IP for the URL `info.cern.ch`, the destination might have a **Reverse Proxy** or any other ingress resource that could condition handling this request.
Due to the `HOST` field not being modified after we set the request, it might not be able to pass the filtering rules set on the destination server, on this scenario being the service responsible for receiving requests with the URL `info.cern.ch`.
```shell
curl 192.168.1.50/external-noh
```
```text
</pre></body></html>
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
serviceentry.networking.istio.io "external-cern-service" deleted
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/service-entry/#ServiceEntry-Location

View File

@ -0,0 +1,13 @@
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-cern-service
spec:
hosts:
- info.cern.ch
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL

View File

@ -0,0 +1,39 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
headers:
request:
set:
HOST: "info.cern.ch"
- name: https-external-service-without-headers
timeout: 3s
match:
- uri:
exact: "/external-noh"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

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

View File

@ -0,0 +1,338 @@
---
gitea: none
include_toc: true
---
# Description
Based on the previous example where we configured an external service through a `ServiceEntry` object, this example compares the behavior between setting up the MeshConfig `OutboundTrafficPolicy.mode` setting to `REGISTRY_ONLY` and `ALLOW_ANY`.
- ALLOW_ANY: Allows all egress/outbound traffic from the mesh.
- REGISTRY_ONLY: Restricted to services that figure in the service registry a and the ServiceEntry objects.
More info regarding this configuration at the pertinent documentation (https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode)
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Based on
- [01-Service_Entry](../01-Service_Entry)
# Configuration
## Gateway
Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
It doesn't filter for any specific host.
The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
```shell
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
## VirtualService
This configuration hosts 2 backends, 1 being the deployed service `helloworld.default.svc.cluster.local`, which will be accessible through the URL path `/helloworld`.
The second service will be accessible through the URL path `/external`, and will use as a backend the deployed `ServiceEntry` object, as well it has a timeout setting of 3 seconds.
This destination is the service that contains the `HTTPS` deployment, running over the port `8443`
```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: "/"
- timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: help.websiteos.com
port:
number: 80
rewrite:
uri: "/websiteos/example_of_a_simple_html_page.htm"
headers:
request:
set:
HOST: "help.websiteos.com"
```
## Service
The service will forward incoming HTTP TCP traffic from the port `80`, towards the deployment port `80`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
```
## Deployment
Nginx deployment listens to 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
```
### ServiceEntry
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc
spec:
hosts:
- help.websiteos.com
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
```
## ServiceEntry
This `ServiceEntry` resource, defines as a destination the URL `help.websiteos.com`.
Note that location is set to `MESH_EXTERNAL` and that the resolution is set to `DNS`, this means that the resource is external to ou `Istio Service Mesh`, and the URL will be resolved through `DNS`
Bear in mind that when Istio is communicating with resources externals to the mesh, `mTLS` is disabled.
Also, policy enforcement is performed in the client side instead of the server side.
> **Note:**/
> For more information regarding the `resolution` field or the `location` field, refer to the following official Istio documentations:\
> - [ServiceEntry.Location](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location)\
> - [ServiceEntry.Resolution](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Resolution)
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc
spec:
hosts:
- help.websiteos.com
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
```
# Walkthrough
## Set ALLOW_ANY outbound traffic policy
First step will be to have the cluster with the `meshConfig.outboundTrafficPolicy.mode` setting set to `ALLOW_ANY`.
In case you are not using a "free to destroy" sandbox, you should update the setting through the `IstioOperator` object.
```shell
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
```
## Deploy resources
```shell
kubectl apply -f ./
```
```text
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
service/helloworld created
serviceentry.networking.istio.io/external-svc created
virtualservice.networking.istio.io/helloworld-vs created
```
## Get LB IP
```shell
kubectl get svc istio-ingressgateway -n istio-system
```
```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
```
## Test deployments
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 14 Oct 2023 10:53:45 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 15 Aug 2023 17:03:04 GMT
etag: "64dbafc8-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 53
```
```shell
curl 192.168.1.50/external -I
```
```text
HTTP/1.1 200 OK
date: Sat, 14 Oct 2023 10:54:13 GMT
content-type: text/html
content-length: 5186
last-modified: Mon, 17 Mar 2014 17:25:03 GMT
expires: Thu, 31 Dec 2037 23:55:55 GMT
cache-control: max-age=315360000
x-envoy-upstream-service-time: 306
server: istio-envoy
```
## Test egress the helloworld deployment
It returns a 301 code, meaning that it was able to reach the destination, and it was attempted to redirect the traffic from HTTP to HTTPS.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl wikipedia.com -I
```
```text
HTTP/1.1 301 Moved Permanently
server: envoy
date: Sat, 14 Oct 2023 10:54:34 GMT
content-type: text/html
content-length: 169
location: https://wikipedia.com/
x-envoy-upstream-service-time: 61
```
## Set REGISTRY_ONLY outbound traffic policy
```shell
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
```
In case you are not using a "free to destroy" sandbox, you should update the setting through the `IstioOperator` object.
## Test (again) egress the helloworld deployment
It returns a 502 code, meaning that it wasn't able to reach the destination.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl wikipedia.com -I
```
```text
HTTP/1.1 502 Bad Gateway
date: Thu, 20 Apr 2023 18:08:37 GMT
server: envoy
transfer-encoding: chunked
```
This allowed us to confirm how the setting `outboundTrafficPolicy.mode` influences the reachability of the traffic.
## Cleanup
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
service "helloworld" deleted
serviceentry.networking.istio.io "external-svc" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of Interest
- https://istio.io/latest/docs/tasks/traffic-management/egress/egress-control/#controlled-access-to-external-services
- https://istio.io/latest/docs/tasks/traffic-management/egress/egress-control/#envoy-passthrough-to-external-services

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