dev #39

Merged
ofilter merged 27 commits from dev into main 2023-04-30 22:36:52 +02:00
56 changed files with 3043 additions and 499 deletions

View File

@ -1,11 +1,204 @@
# Continues from
# Description
- 01-hello_world_1_service_1_deployment
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:
- "*"
```
https://github.com/istio/istio/issues/29463
## 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.
This could be due, 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 set, weather it is security wise, for example, requiring such field to allow the request; or it being a routing condition, which due not having this field specified, it's not able to route the request towards the destination desired.
```shell
curl 192.168.1.50/external-noh
```
```text
```
## 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
Funny example I guess.
Q

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

@ -1,4 +1,3 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
@ -24,29 +23,32 @@ spec:
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
- timeout: 3s
- name: http-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: help.websiteos.com
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/websiteos/example_of_a_simple_html_page.htm"
uri: "/"
headers:
request:
set:
HOST: "help.websiteos.com"
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,188 @@
# Description
This example configures an `ServiceEntry` service pointing to a URL external to our `Istio Service Mesh`.
The main difference with the previous example, is that on this example the resource selected requires `HTTPS` communication.
The page used as a destination is my own [GitHub page](https://github.com/).
# Based on
- [05-hello_world_1_Service_Entry](../05-hello_world_1_Service_Entry)
# Configuration
## ServiceEntry
This `ServiceEntry` resource, defines as a destination the URL `github.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`
This resource listens for the port `8443`, and will connect to its destination with the port `443`, intending to handle `HTTPS` protocol traffic.
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-github-service
spec:
hosts:
- github.com
ports:
- number: 8443
name: https
protocol: HTTPS
targetPort: 443
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
The path `/external` will forward the request towards the destination URL `github.com`, and path `/OriolFilter`.
Highlight that the destination is `github.com`, which is the same as the contents set on the field `host` from the [ServiceEntry resource configured above](#serviceentry).
As seen [in the previous example, where the host that didn't have the `HOST` header wasn't able to receive a response by the destination](../05-hello_world_1_Service_Entry/#external-noh), we configured the `HOST` header to match the URL from the external service.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: "github.com"
port:
number: 8443
rewrite:
uri: "/OriolFilter/"
headers:
request:
set:
HOST: "github.com"
```
## DestinationRule
As seen in the example [02-Traffic_management/09-HTTPS-backend](../../02-Traffic_management/09-HTTPS-backend), where we configure Istio to use an `HTTPS` backend, the same configuration is applied on this case (yes, I am aware that a `ServiceEntry` is also a backend).
For such, we deploy a `DestinationRule` setting to expect to terminate the TLS traffic, for the traffic with resource destination `github.com`, and port `8443`, which matches the settings set in our [ServiceEntry](#serviceentry) deployed.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: github.com
namespace: default
spec:
host: github.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
serviceentry.networking.istio.io/external-github-service created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/github.com 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
...
I mean, we can use curl but it's certainly quite an ugly output, it works tho.
...
```
As performing the test through `curl` is ugly, here is a screenshot of the setting working correctly.
![github-screenshot.png](./src/github-screenshot.png)
## Cleanup
```shell
kubectl delete -f ./
```
```text
serviceentry.networking.istio.io "external-github-service" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "github.com" deleted
```
# Links of interest:
- https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location

View File

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-github-service
spec:
hosts:
- github.com
ports:
- number: 8443
name: https
protocol: HTTPS
targetPort: 443
resolution: DNS
location: MESH_EXTERNAL

View File

@ -0,0 +1,55 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: "github.com"
port:
number: 8443
rewrite:
uri: "/OriolFilter/"
headers:
request:
set:
HOST: "github.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: github.com
namespace: default
spec:
host: github.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

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

View File

@ -84,7 +84,7 @@ spec:
## Service
The service will forward incoming traffic from the service port 8443, that will be forwarded towards the port 443 from the deployment.
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment.
```yaml

View File

@ -160,6 +160,7 @@ kubectl get svc -l istio=ingressgateway -A
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### curl HTTPS
Well, it just works.

View File

@ -0,0 +1,218 @@
---
gitea: none
include_toc: true
---
# Based on
- [07-HTTPS-Gateway-Simple-TLS](../07-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,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

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

View File

@ -5,7 +5,6 @@ include_toc: true
# Continues from
[//]: # (- [01-hello_world_1_service_1_deployment]&#40;../../01-simple/01-hello_world_1_service_1_deployment&#41;)
- [06-mTLS](../../02-Traffic_management/06-mTLS)
## Description
@ -14,7 +13,7 @@ Bla bla bla
Configuration targeting namespaces
# Changelog
# Configuration
## Authentication configuration deployed
@ -123,7 +122,7 @@ namespace/foo created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-from-istio-system created
authorizationpolicy.security.istio.io/allow-get-from-default created
authorizationpolicy.security.istio.io/allow-head-from-default created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
@ -198,7 +197,7 @@ x-envoy-upstream-service-time: 91
It works.
Due to the rule `allow-get-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, the request is allowed.
Due to the rule `allow-head-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, the request is allowed.
@ -254,7 +253,7 @@ x-envoy-upstream-service-time: 65
#### helloworld towards byeworld/secret
Due to the configuration set on the rule `allow-get-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
Due to the configuration set on the rule `allow-head-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
This causes the traffic to not be allowed.

View File

@ -6,7 +6,7 @@ include_toc: true
# Continues from
[//]: # (- [01-hello_world_1_service_1_deployment]&#40;../../01-simple/01-hello_world_1_service_1_deployment&#41;)
- [01-namespaces](../01-namespaces)
- [01-target-namespaces](../01-target-namespaces)
> **Note:**\
> On this example there is minimal changes to the configuration to involve targeting service accounts.

View File

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

View File

@ -0,0 +1,382 @@
---
gitea: none
include_toc: true
---
# Continues from
- [01-target-namespaces](../01-target-namespaces)
> **Note:**\
> On this example there is minimal changes to the configuration to involve targeting the deployment resources through label filtering.
## Description
Bla bla bla
In this example we will be targeting the labels set to the deployments, while keeping part of the previous AuthorizationPolicy configuration to maintain its behavior.
[//]: # (For such, it's important to check the labels set in the Istio ingress that we will be using.)
[//]: # ()
[//]: # (On my case, in the gateway I will be targeting/using the Istio ingress `ingressgateway`.)
[//]: # ()
[//]: # (I would **strongly** recommend checking yours through the following command, as to proceed we should be aware of which are our possible labels options.)
[//]: # ()
[//]: # (```shell)
[//]: # (kubectl get deployments -A -l istio=ingressgateway -o jsonpath='{.items[].spec.template.metadata.labels}'| jq)
[//]: # (```)
[//]: # (```json)
[//]: # ({)
[//]: # ( "app": "istio-ingressgateway",)
[//]: # ( "chart": "gateways",)
[//]: # ( "heritage": "Tiller",)
[//]: # ( "install.operator.istio.io/owning-resource": "unknown",)
[//]: # ( "istio": "ingressgateway",)
[//]: # ( "istio.io/rev": "default",)
[//]: # ( "operator.istio.io/component": "IngressGateways",)
[//]: # ( "release": "istio",)
[//]: # ( "service.istio.io/canonical-name": "istio-ingressgateway",)
[//]: # ( "service.istio.io/canonical-revision": "latest",)
[//]: # ( "sidecar.istio.io/inject": "false")
[//]: # (})
[//]: # (```)
[//]: # ()
[//]: # (Based on the list displayed, I would suggest focusing on the following options:)
[//]: # ()
[//]: # (```json)
[//]: # ({)
[//]: # ("istio": "ingressgateway",)
[//]: # ("operator.istio.io/component": "IngressGateways",)
[//]: # ("app": "istio-ingressgateway",)
[//]: # (})
[//]: # (```)
[//]: # ()
[//]: # (The label `"service.istio.io/canonical-revision": "latest"` could be reasonable to use, in very specific situations, as depending on the implementation/environment or procedures that we might use in the future, it's something to keep in mind in case of being configured.)
[//]: # ()
[//]: # ()
# Configuration
## AuthorizationPolicy
### Allow nothing (deny all not matched)
#### default namespace
If the action is not specified, it will deploy the rule as "ALLOW".
Here we are deploying a rule that allows the traffic that it matches, yet as it has no conditions, it will never match.
```yaml
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
```
Citing the [Authorization Policy documentation from Istio](https://istio.io/latest/docs/reference/config/security/authorization-policy), regarding the evaluation behavior of these rules:
1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.
2. If there are any DENY policies that match the request, deny the request.
3. If there are no ALLOW policies for the workload, allow the request.
4. If any of the ALLOW policies match the request, allow the request.
5. Deny the request.
On this scenario, as we don't have any DENY or CUSTOM rule, we skip right into the 3rd scenario.
This rule is being applied to the workload (due being a rule that affects the whole namespace), and for such the 3rd scenario is not being applied either.
On the 4rth, scenario, as the rule deployed, even if it's on ALLOW mode, has no conditions, it won't allow the traffic either.
And finally, as any of the above scenarios allowed the traffic of the request, it ends getting denied.
For such, the creation of this "empty" rule, has set the authorization mode on the not explicitly allowed request to "DENY ALL".
#### foo namespace
Same behavior as above, this time applied to the namespace `foo`
```yaml
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
```
## ALLOW
#### byeworld-allow-from-istio-system
As we have a service deployed, and the traffic will come through the Istio Load Balancer (at least on my environment). I have set a rule that will allow all the traffic coming from a resource located in the namespace `istio-system`.
This rule will be applied to the deployments that have set the following label `app: byeworld`, and deployed in the namespace `istio-system`.
> **Note:**\
> As this rule will be deployed in the root namespace `istio-system` (it's my root namespace in **MY** environment, review your Istio configuration to ensure which is **YOUR** root namespace).\
> By deploying the rule in the root namespace, it gets applied to all namespaces, I have set this to ensure that there are minor differences on the configuration in comparison on which example this is based on. As well this will allow us to confirm tha the labels are being applied correctly.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-from-istio-system
namespace: istio-system
spec:
selector:
matchLabels:
app: byeworld
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
```
#### byeworld-allow-head-from-default
I have set a new rule, that will allow the traffic coming from the namespace `default`, as long the method used is `HEAD` and is not targeting the path `/secret`.
This rule will be applied to the deployments that have set the following label `app: byeworld`, and deployed in the namespace `istio-system`.
> **Note:**\
> This will be deployed in the root namespace `istio-system` (it's my root namespace in **MY** environment, review your Istio configuration to ensure which is **YOUR** root namespace).\
> By deploying the rule in the root namespace, it gets applied to all namespaces, I have set this to ensure that there are minor differences on the configuration in comparison on which example this is based on. As well this will allow us to confirm tha the labels are being applied correctly.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-head-from-default
namespace: istio-system
spec:
action: ALLOW
selector:
matchLabels:
app: byeworld
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
namespace/foo created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/byeworld-allow-from-istio-system created
authorizationpolicy.security.istio.io/byeworld-allow-head-from-default created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
deployment.apps/byeworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs create
```
## Test resources
### Curl / LB requests / requests from external traffic
#### 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
```
#### helloworld
Due to the rule `allow-nothing` created on the namespace `istio-system`, which is being applied to all the namespaces, we are not hitting any rule that explicitly allows us, and for such, the traffic is being denied.
For such we receive the status code `403` (**Forbidden**)
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:20:06 GMT
server: istio-envoy
x-envoy-upstream-service-time: 108
```
#### byeworld
As we created the rule `byeworld-allow-from-istio-system` created in the namespace `foo`, which allows all the traffic coming from a resource located in the namespace `istio-system`, and the load balancer used is located in the namespace `istio-system`, the traffic is allowed.
For such we receive the code `200`.
```shell
curl 192.168.1.50/byeworld --head
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Thu, 27 Apr 2023 01:20:49 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 104
```
### Connectivity between the deployments
> **NOTE:**\
> The command `curl`, when uses the flag `--head` or `-I`, the request sent will be a `HEAD` request.
>
> It's important to be aware of that due the rule configured, where one of the targets was the method used, specifically targeted the method `HEAD`.
>
> On this example, all request will be done with the method `HEAD` unless specified otherwise.
#### helloworld towards byeworld
It works.
Due to the rule `byeworld-allow-head-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, the request is allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090 --head
```
```text
HTTP/1.1 200 OK
server: envoy
date: Thu, 27 Apr 2023 01:20:58 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 86
```
#### helloworld towards byeworld (GET REQUEST)
This example is made on base on the last comand executed, where the request sent uses the `HEAD` method.
On this example the flag `--head` is removed, which causes the command `curl` to send a request of method `GET`.
As the rule created required the method to be `HEAD`, it causes the request to not be allowed, and finally as there are no rules that allow this request, it results in failure.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090
```
```text
RBAC: access denied%
```
#### byeworld towards helloworld
It fails.
As expected, like when accessing through the Load Balancer, we receive the status code `403` (**Forbidden**).
The `HEAD` request is irrelevant on this scenario, yet using it as I like this output more.
```shell
kubectl exec -i -n foo -t "$(kubectl get pod -n foo -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080 --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:21:10 GMT
server: envoy
x-envoy-upstream-service-time: 96
```
#### helloworld towards byeworld/secret
Due to the configuration set on the rule `byeworld-allow-head-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
This causes the traffic to not be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/secret --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:21:18 GMT
server: envoy
x-envoy-upstream-service-time: 3
```
#### helloworld towards byeworld/not-found
On this example, we can notice how even if the request was allowed due meeting all the requirements, it still results in the error code `404` (Not Found).
This 404 error is raised by the destination service, yet before being able to handle such request, firstly the traffic required to be allowed, meaning that even if we target as a destination path a non-existent resource, we will need to match the requirements for the traffic to be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/not-found --head
```
```text
HTTP/1.1 404 Not Found
server: envoy
date: Thu, 27 Apr 2023 01:21:31 GMT
content-type: text/html
content-length: 153
x-envoy-upstream-service-time: 56
```
# Links of interest
- https://istio.io/latest/docs/reference/config/security/authorization-policy/

View File

@ -0,0 +1,43 @@
---
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-from-istio-system
namespace: istio-system
spec:
selector:
matchLabels:
app: byeworld
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-head-from-default
namespace: istio-system
spec:
action: ALLOW
selector:
matchLabels:
app: byeworld
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]

View File

@ -1,4 +1,3 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
@ -8,8 +7,9 @@ metadata:
service: helloworld
spec:
ports:
- port: 80
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
@ -35,23 +35,6 @@ spec:
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc
spec:
hosts:
- help.websiteos.com
# /websiteos/example_of_a_simple_html_page.htm
# - http://help.websiteos.com/websiteos/example_of_a_simple_html_page.htm
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
---

View File

@ -0,0 +1,42 @@
apiVersion: v1
kind: Service
metadata:
name: byeworld
labels:
app: byeworld
service: byeworld
namespace: foo
spec:
ports:
- port: 9090
name: http
targetPort: 80
selector:
app: byeworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: byeworld-nginx
labels:
app: byeworld
namespace: foo
spec:
replicas: 1
selector:
matchLabels:
app: byeworld
template:
metadata:
labels:
app: byeworld
spec:
containers:
- name: byeworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -1,8 +1,7 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
@ -17,36 +16,30 @@ spec:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
- helloworld-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
- match:
- uri:
exact: /helloworld
route:
- destination:
host: productpage
host: helloworld.default.svc.cluster.local
port:
number: 9080
number: 8080
rewrite:
uri: "/productpage"
uri: "/"
- match:
- uri:
exact: /byeworld
route:
- destination:
host: byeworld.foo.svc.cluster.local
port:
number: 9090
rewrite:
uri: "/"

View File

@ -10,7 +10,15 @@
- Audit / logs (should be the 3th)
JWT seems important, refer to source.requestPrincipals
https://istio.io/latest/docs/tasks/security/authentication/
https://istio.io/latest/docs/tasks/security/authentication/
Per deployment:
```yaml
selector:
matchLabels:
app: myapi
```

View File

@ -1,6 +0,0 @@
# Based on
- [02-Traffic_management/09-HTTPS-backend (pending document)](../../02-Traffic_management/09-HTTPS-backend%20(pending%20document))
On the previous example only uses a HTTPS backend, here boards both HTTP and HTTPS backends.

View File

@ -1,8 +0,0 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: default
spec:
mtls:
mode: DISABLE

View File

@ -0,0 +1,2 @@
https://raw.githubusercontent.com/istio/istio/release-1.17/samples/httpbin/sample-client/fortio-deploy.yaml

View File

@ -119,7 +119,7 @@ virtualservice.networking.istio.io/helloworld-vs created
### Deploy deployment
```shell
kubectl apply -f deployment.yaml
kubectl apply -f deployment-nomtls.yaml
```
```text
service/helloworld created
@ -161,7 +161,7 @@ x-envoy-upstream-service-time: 15
[Yeah no idea, gl with that.](https://stackoverflow.com/a/55731730)
```shell
kubectl delete -f ./deployment.yaml
kubectl delete -f ./deployment-nomtls.yaml
kubectl delete -f ./gateway.yaml
```
```text

View File

@ -0,0 +1,637 @@
---
gitea: none
include_toc: true
---
# Description
On this example we disable the mTLS for the service deployed, and observe which is the behavior, and one possible environment where it might be required to disable mTLS.
This example uses the `selector` field to target labels set to the deployments.
Also explores the behavior of accessing an `HTTPS` backend using the tls `STRICT` mode, when using `mTLS` and when `mTLS` is disabled.
To explore the different behaviors, [2 deployments](#deployments) where used, both under the same [Service](#service), and the traffic will be distributed through subsets in the [Destination Rule](#destination-rule) set.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
Listens for `HTTP` traffic without limiting any host.
```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:
- "*"
```
## Virtual Service
Without limiting to any host, listens for traffic at port 80, and only has a very specific URL paths available to match.
- /http-mTLS
- /https-mTLS
- /http-no-mTLS
- /https-no-mTLS
Depending on the path used, the traffic will be distributed between 2 subsets from the same service:
- mtls
- nomtls
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: mtls
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 80
uri:
exact: "/https-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: mtls
rewrite:
uri: "/"
- name: http-no-mTLS
match:
- port: 80
uri:
exact: "/http-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: nomtls
rewrite:
uri: "/"
- name: https-no-mTLS
match:
- port: 80
uri:
exact: "/https-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: nomtls
rewrite:
uri: "/"
```
## Destination Rule
Interfering with the service URL `helloworld.default.svc.cluster.local`, it specifies 2 subsets:
- mtls
- nomtls
Additionally, specifies that the traffic with port destination 8443, will attempt to proceed with TLS termination, as it is required to connect with an `HTTPS` backend.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
subsets:
- name: mtls
labels:
mtls: "true"
- name: nomtls
labels:
mtls: "false"
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend
```
## Service
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment, which contains an `HTTPS` service.
Also listens for `HTTP` traffic at the port `8080`, and will be forwarded to the deployment port `80`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
```
## Deployments
There's been configured 2 deployments with the same service and settings, besides the label `mtls`, which will contain `true` or `false` based on the deployment.
This label is used for the [Destination Rule](#destination-rule) to distribute the traffic between the 2 deployments under the same service.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
### helloworld-mtls
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-mtls
labels:
app: helloworld
mtls: "true"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "true"
template:
metadata:
labels:
app: helloworld
mtls: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
### helloworld-nomtls
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nomtls
labels:
app: helloworld
mtls: "false"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "false"
template:
metadata:
labels:
app: helloworld
mtls: "false"
spec:
containers:
- name: helloworld-nomtls
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentications
Deployed 2 Peer Authentication rules, which use the `selector` field to target the deployments.
Both point to the same application, yet also specify the `mtls` label set in the deployments above, allowing the rules to target each deployment individually.
These rules are deployed in the `default` namespace.
### disable-mtls
This rule will disable `mTLS` for that deployment.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: disable-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "false"
mtls:
mode: DISABLE
```
### force-mtls
This rule forces the deployment to communicate exclusively through `mTLS`, in case this rule is not endorsed, the traffic won't be allowed to proceed further.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: force-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "true"
mtls:
mode: STRICT
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
peerauthentication.security.istio.io/disable-mtls created
peerauthentication.security.istio.io/force-mtls created
deployment.apps/helloworld-mtls created
deployment.apps/helloworld-nomtls created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
```
## 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
```
## Analyze the different behaviours
> **DISCLAIMER**:\
> For some reason, during the packet captures, I required to execute the curl 2 times in order for the output to be updated.\
> During the tests, feel free to perform the curl twice in a row.
This steps will be structured on 3 parts:
- Starting the packet capture.
- Using `curl` to send a request to the destination. This step can also be performed through a web browser.
- Observing the information captured in the packet capture.
All this steps will be performed for each one of the environments, each environment being formed by 2 backend destinations.
Environments:
- mTLS disabled
- mTLS enabled
Backend destinations in each one of the environments:
- HTTP
- HTTPS
### mTLS disabled
#### HTTP
##### Start the packet capture for the port 80
Start the packet capture and proceed with another shell or browser to send traffic requests to the right destination.
```shell
PORT=80 && MTLS="false" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
Nothing to higlight so far, we can access the service.
```shell
curl 192.168.1.50/http-no-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to having the mTLS disabled, the traffic is not encrypted, and for such we can see its context in plain text.
This scenario should be avoided unless it is required due the application being used, as mTLS allows an extra layer of security.
```text
04:25:47.757900 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.60966 > helloworld-nomtls-66d8499c5c-298vw.http: Flags [P.], seq 3134140617:3134142280, ack 2649160847, win 501, options [nop,nop,TS val 1425864700 ecr 2534833629], length 1663: HTTP: GET / HTTP/1.1
E....t@.?.....yX..yx.&.P..0.........Q......
T.....}.GET / HTTP/1.1
host: 192.168.1.50
user-agent: curl/8.0.1
accept: */*
x-forwarded-for: 192.168.1.10
x-forwarded-proto: http
x-envoy-internal: true
x-request-id: 65b60be7-da98-48f3-9ed6-13112cdd14f0
x-envoy-decorator-operation: helloworld.default.svc.cluster.local:8080/http-no-mTLS
x-envoy-peer-metadata: ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgwaCkt1YmVybmV0ZXMKHwoMSU5TVEFOQ0VfSVBTEg8aDTE3Mi4xNy4xMjEuODgKGQoNSVNUSU9fVkVSU0lPThIIGgYxLjE3LjIKnAMKBkxBQkVMUxKRAyqOAwodCgNhcHASFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKEwoFY2hhcnQSChoIZ2F0ZXdheXMKFAoIaGVyaXRhZ2USCBoGVGlsbGVyCjYKKWluc3RhbGwub3BlcmF0b3IuaXN0aW8uaW8vb3duaW5nLXJlc291cmNlEgkaB3Vua25vd24KGQoFaXN0aW8SEBoOaW5ncmVzc2dhdGV3YXkKGQoMaXN0aW8uaW8vcmV2EgkaB2RlZmF1bHQKMAobb3BlcmF0b3IuaXN0aW8uaW8vY29tcG9uZW50EhEaD0luZ3Jlc3NHYXRld2F5cwoSCgdyZWxlYXNlEgcaBWlzdGlvCjkKH3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLW5hbWUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0CiIKF3NpZGVjYXIuaXN0aW8uaW8vaW5qZWN0EgcaBWZhbHNlChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAovCgROQU1FEicaJWlzdGlvLWluZ3Jlc3NnYXRld2F5LTg2NGRiOTZjNDctZjZscWQKGwoJTkFNRVNQQUNFEg4aDGlzdGlvLXN5c3RlbQpdCgVPV05FUhJUGlJrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvaXN0aW8tc3lzdGVtL2RlcGxveW1lbnRzL2lzdGlvLWluZ3Jlc3NnYXRld2F5ChcKEVBMQVRGT1JNX01FVEFEQVRBEgIqAAonCg1XT1JLTE9BRF9OQU1FEhYaFGlzdGlvLWluZ3Jlc3NnYXRld2F5
x-envoy-peer-metadata-id: router~172.17.121.88~istio-ingressgateway-864db96c47-f6lqd.istio-system~istio-system.svc.cluster.local
x-envoy-attempt-count: 1
x-envoy-original-path: /http-no-mTLS
x-b3-traceid: 36e7d48757f2ce26eaa6e1959f3b1221
x-b3-spanid: eaa6e1959f3b1221
x-b3-sampled: 0
```
#### HTTPS
##### Start the packet capture for the port 443
```shell
PORT=443 && MTLS="false" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
So good so far.
```shell
curl 192.168.1.50/https-no-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to the configuration set in the [Destination Rule](#destination-rule), where we set the `tls.mode` setting to `SIMPLE`, the traffic will be TLS terminated with the backend.
For such, the traffic captured is encrypted, even tho we displayed the `mTLS` configuration for this deployment.
Yet, there are still a couple readable lines, where we can see that the request was initialized by the host `stio-ingressgateway.istio-system.svc.cluster.local`, through the egress port `39884`, using as destination `helloworld-nomtls-66d8499c5c-298vw`, and the port defined with name `https`, which, if we reviewed the configuration from the [Service](#service), we would observe that it was the port `8443`.
```text
k 496, win 505, options [nop,nop,TS val 1425943341 ecr 2534945802], length 0
E..4..@.?.....yX..yx.......;........K......
T.+-..4
04:27:06.400101 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39884 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 809, win 503, options [nop,nop,TS val 1425943342 ecr 2534945803], length 0
E..4..@.?.....yX..yx.......;........K......
T.+...4.
04:27:13.439290 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39826 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [P.], seq 1997:3684, ack 2200, win 501, options [nop,nop,TS val 1425950381 ecr 2534942622], length 1687
E.....@.?..+..yX..yx....pI.+,U+.....Q......
T.F...'......,.SuD..a....`..]....j..v[tF$y.<......&..m.E.p.Y.-....w..V..T.....g..a~$.Q'.c#......qj..8.|......M.J.....\".>...R...M..k|..f^,.....E.....+.Y.6..].u.g<r...0.eE...QSM 0Q...05......y......h6fbW.HdFp....../..(F\.U.pSn...2 .-.X/.8...P....~4anH.h....e....../.3@(....x...{.4.j@[.....P.6.......%.M.EGo.Q~@.
Z............/$..@....&.8..... f...ip.z]....p..}.....f.=......'......Koz.3..d.@..;....)}...>.m....Z..~o.IL.......D.]h.G.... .....F/..V......}.v.^N.P.C.G.......1..T.....w....?..]:........D...;q?...W..cI.).O......3..X14P..B.).',.N...B.../q..)\.. GW.".... .`.....[9.IS......1y.J]...d..}...B.n...C.........e6..B..[w.\.3.l.HU....5%......p.irW.@s..!1\u./.~..[.g..W.........'W..,m};._../S2\..c.9..8..rg"f..35a.A.;..T....>`..Zv.L.8....hZ".*r...0..*.%K.?.. .P]DKve/E.J.....\....t.e.9#-..3.$).....Q.Z.....m].". q. *.OW...f.=l...K.o:.D.......+.a..h?{h.?..T.....7\N.....M.`..Ob1`.....3d.aq..0...q.r.*j....KE./.O...T%..r.......'..9.W1J^^TU8.$...Y."~..~ZH.......G..?......Q4..=|.{.d/..^_....`.pjJ+p.........R."..Y-.`1....{....k...]ib.+m.....6..k...U.P.T........wU...}......`.z..#..[1.@9.z+R.3pAW).......m...Px4..9^ X..ux.EVO.o.%./+.....|4..!s......g.1...9%.... B.....{.6..].-?.../..n..y...2..sLc..|x.
,.t..'...7.............|...........?..&}........@...=.|#.+...........u.3....m.X..... QrW?............u`-k....Q.o^{........$..h.....R.#...k...o.7~.*.tE.C...I<"......k..czN.DJ.y...R.....hx.he.r}0.82....6.J...)..3.f.G=Ky|f.L.).=.hlN!..D..J..g.V.?.......#...fQ..d.......9.9.-....j..O...Pd..E.da/..b} .}.Qx.......I..[+....>.5....p.9....K2M s(.a..K6.]..m.?...%..</.S.9......[.P./.1.I. ...k.'.`V........^O.....q.. <...H..=mZZ...........@.VR..x.....U..t....s!.......M.m.........u...:.....V.1X...2.T..~...
04:27:13.440468 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39826 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 2513, win 501, options [nop,nop,TS val 1425950382 ecr 2534952843], length 0
E..4..@.?.....yX..yx....pI..,U,.....K......
T.F...O.
04:27:20.932653 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [S], seq 3645561416, win 64800, options [mss 1440,sackOK,TS val 1425957874 ecr 0,nop,wscale 7], length 0
E..<..@.?.f>..yX..yx.....J.H....... K".........
T.c.........
04:27:20.933038 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 840930767, win 507, options [nop,nop,TS val 1425957875 ecr 2534960336], length 0
E..4..@.?.fE..yX..yx.....J.I2.......K......
T.c...l.
04:27:20.933916 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [P.], seq 0:517, ack 1, win 507, options [nop,nop,TS val 1425957876 ecr 2534960336], length 517
E..9..@.?.d?..yX..yx.....J.I2.......M......
T.c...l..............#.."H..\..\A*...5.../m.....wV. ;.......>..`..k.t.b.O.U
e(?.X...........+.../...,.0..............
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... J7.y.............
..<.Ma.v}.*3LI.-.....+........................)......./.....`.............3.. .[....N.,......i.9;.9V9A..1..J.......W.....o.%.%.<uep.Z"X...6...;|.........f.5AyieJ...+..q...T......x....jO.T$.D!x.pe.....D,.P1.. .a..t..r.x#.J.z...y.q...i:....43..3[/;..P0..\*>#ev..f.....! ........FHc..r...6...e.'J.&..T.p
04:27:20.937464 IP 172-17-1
```
### mTLS enabled
#### HTTP
##### Start the packet capture for the port 80
```shell
PORT=80 && MTLS="true" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
We can access the service.
```shell
curl 192.168.1.50/http-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to mTLS being enabled, the traffic captured is encrypted, and for such we cannot explore the contents of such.
We can notice the following lines `outbound_.8080_.mtls_.helloworld.default.svc.cluster.local`, and further deep in the sea of text `1.1.istio.http/1.1` referring that `mTLS` termination was performed through the HTTP version `HTTP1.1`.
```text
04:21:48.543118 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [S], seq 4217286528, win 64800, options [mss 1440,sackOK,TS val 1478647369 ecr 0,nop,wscale 7], length 0
E..<..@.>..x..yX...,. .P.^......... ...........
X"^I........
04:21:48.544529 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [.], ack 3797925086, win 507, options [nop,nop,TS val 1478647370 ecr 861329182], length 0
E..4..@.>.....yX...,. .P.^..._.............
X"^J3V..
04:21:48.545045 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 0:2216, ack 1, win 507, options [nop,nop,TS val 1478647371 ecr 861329182], length 2216: HTTP
E.....@.>.....yX...,. .P.^..._.......v.....
X"^K3V................~5pO...T`.|..{. .........Q..e .}..,....q...n....=...'.a7....=r.........+.../...,.0...D...?.=..:outbound_.8080_.mtls_.helloworld.default.svc.cluster.local..........
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... #.g....m............l....`.KE.>J.-.....+........).k.F.@O..)z.l.....8b......}.2....77.?.......J..T0....]..\....R.W.]....x..W....;.[....x...."Wy.Q.{.c.Fo..W%7....
. .].m..>......2\V._(&........;.....&K.b..};R.._A.$)s....2.gC.....d..>Q.x{.uw...s....<|O.:T...d.........j..O...d2..;...S.&. s.l..v..G........B..|g..!....@6fdG..]....=e..>.2..*}%*..>..u..y.B....vq99:....IT..)I5........`......BG...[5m.../7..
v........R.1...l.S2W{M.7.._w..D....j.,.....O-;6.q....<..P....s
..0..:.....Oq..cX..=.k`Q.X.x.E.E`T.<...Y..tPG.:..z.#p.)$..)@...W..g]Q..W......I..:....~..... .....;Y.YG....+.o.,.....8t...l.q.&.........1..w.{.[.U..B...]a up..8:\....:5......../o.5..[.,+xA(.........
...`.M...>...mor.o........`x\.1......:..s.h..r....Mm*..w.Q. ..d..W..&..0[bi.u.F}4...SP=....j\.H._1....6..f....=.\.$.. pD1.6@.>..4YT.D..e".}=.c..,O..M.eC*?...w..R..LZ..f.._.q..bR.t.-I..=,....%"...*...].m..d5..W...3.k...k.s...[ANc._.....V ...z._.b{I...(r.)..v......H.?......*|./h A|.l.(2..&-..} ...V....D..........g.vA.P/@...._`...M...}..}kF..g.,.rs7...^.0.:W"....8.(.Rr.O{..#I.d.CL....(.D.....L..4..)I3.F.l..kD..`.x<8Z.`..a'.u.
_.^RMn.w.. ..?y...R.T.P.c...9...Q.....w.._.T..;...... .l...?..w!.T.._.,...p
..I.zG....x.^p.........X......7v.'.pp..u....ab^Q_
pS.........B...6....s;......
. ..Q....nRw.\HG.H]......l.....G._..4% .{.<...a..p.5\...0......86..Al........&..;....\.V....d.U.......-.Y.<WH...^..."4..... .._ .ov....V....;.h..d.C.0.&.3...s...-....9.....>....B..v.9...k...]S.)....V]C8.<....0..V..fP.oe..{........ .....8:.{tU..`]...@_.H.t.a...9.}......eE...F..6........!S=....)..W4.;...?..C.... ....t.D..IU....RU.X'V.....t...M.j.'-...^p..1...S.9. ...o.J..8v..C2..%..d.T..GU..-.?...F"`....z.../........s.N....$I..F'0....#........B.4..S.M...#..)...Sx.....E....f.).....m.k.G1..I..$=.Q..^n.[..tn..y4.g.}.7...&..}..JXRk..<...S%r..."]#.......O..;.Rt......2.v..~e.E.{t.F.b...4..-:......6..CrE#.....^]~.k5.@..*.^.K..G.k..(dc.#L..z...L..8..._........d..gXl.......! |r?....%Z&!]n....C7...c.([6u....
04:21:48.550098 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [.], ack 219, win 506, options [nop,nop,TS val 1478647376 ecr 861329188], length 0
E..4..@.>..|..yX...,. .P.^.)._.............
X"^P3V.$
04:21:48.551427 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 2216:2280, ack 219, win 506, options [nop,nop,TS val 1478647378 ecr 861329188], length 64: HTTP
E..t..@.>..;..yX...,. .P.^.)._.......7.....
X"^R3V.$..........5k)...o...^D......3..........WC.|...@...zwS...z.@yA.c
04:21:48.551870 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 2280:3959, ack 219, win 506, options [nop,nop,TS val 1478647378 ecr 861329188], length 1679: HTTP
E.....@.>.....yX...,. .P.^.i._.......].....
X"^R3V.$......zb5...o.....x.....a..-....B^4...K.m.
..Z..z..(.f3aG......r...$9
```
#### HTTPS
##### Start the packet capture for the port 443
```shell
PORT=443 && MTLS="true" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
On this scenario, we met a fatal error, not allowing us to access the service, unlike the previous attempts.
From my understanding, not only from this interaction, but from investigating through Istio forums (yet I don't have the link handy, so take this words with some grains of salt), **the traffic cannot be double terminated**, for such if we have an `HTTPS` backend, we might require to disable `mTLS` in order to communicate with it. We also would need to set a [Destination Rule like we did further above](#destination-rule), to specify that the traffic must be terminated with the backend (`tls.mode: STRICT`).
Yet this depends on which would be our architecture, due also being able to set up [TLS Passthrough](../../02-Traffic_management/11-TLS-PASSTHROUGH), or use a [TCP Forwarding](../../02-Traffic_management/10-TCP-FORWARDING).
```shell
curl 192.168.1.50/https-mTLS
```
```text
upstream connect error or disconnect/reset before headers. reset reason: connection termination
```
##### Reviewing pcap output
Not much to highlight as there isn't much available text for us to be able to read.
```text
04:22:15.813163 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [S], seq 693161527, win 64800, options [mss 1440,sackOK,TS val 1478674639 ecr 0,nop,wscale 7], length 0
E..<..@.>.}Z..yX...,....)P.7....... ...........
X"..........
04:22:15.814619 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 609580424, win 507, options [nop,nop,TS val 1478674641 ecr 861356452], length 0
E..4..@.>.}a..yX...,....)P.8$Uu......x.....
X"..3WA.
04:22:15.815126 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 0:246, ack 1, win 507, options [nop,nop,TS val 1478674641 ecr 861356452], length 246
E..*..@.>.|j..yX...,....)P.8$Uu............
X"..3WA.............#j..S..(.j....4\v.h_ N......S.O e....U.....oM.j.....l...t......T.........+.../...,.0..............
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... ..t.i.=..1...[i..
FQF.....8d..}..-.....+.......
04:22:15.831747 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 2165, win 499, options [nop,nop,TS val 1478674658 ecr 861356470], length 0
E..4..@.>.}_..yX...,....)P..$U}............
X"..3WA.
04:22:15.834886 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 246:318, ack 2165, win 501, options [nop,nop,TS val 1478674661 ecr 861356470], length 72
E..|..@.>.}...yX...,....)P..$U}.....+......
X"..3WA...........=d..Vv.s..."..Dc.p...T...s...3........i.'-Sc..0p|)...!. T~...)
04:22:15.835307 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 318:1999, ack 2165, win 501, options [nop,nop,TS val 1478674661 ecr 861356470], length 1681
E.....@.>.v...yX...,....)P.v$U}......_.....
X"..3WA.......7..t...*.U.....,...]...l..=.x....jH..*......[..._...._..l..+......T..9.}$CO.[...b.Fx0...X.2.......V.U.%.^.%.}?... ...$..G.\0G..=.9.X....jA...ks^r.H.*H.....2H........Im
...........@..D!O0...a..G.i/1..W-.....A..yd..`...h.'Y...&.Po..T.4..B........$..t...M.....D..Y..6z.....8I-....e.3.....4.$Y.C_R...'V......C...&.\....."...U.[T....nW..}......!......L..j..ov...~.....r..
B..B.gRp
R..xLTm..af_.X.2.......|.,.Wi.....F@.0.'...
.>.8.'t.....r.Xi....#*..l.bO.V.......G.[:....7.2.(U....R,#.>!..<.o..w..R|.T..:_..i.. iJs.-.>...B..~.mOH0+N.....-.b...5.._.9%....u&..y.S...8A...*.=....MJS.m........u..Ic....s}Y....{.8d.....<..P-;V[......\.....+..S.8k..r&...dT..K..y].t..3..BU,.<......:IH......-..\j.g...\:..[........(.S......"..0|-.p"Z..:..>6..b..x.....M..;K2AT|Ah.....3z.+..><.&........)E.C ..4....X1.p} .@...@n.........\..R...H........5...+h-...q.|.(....]o.. jw..(....=..
..+(nY{......6..@..c.^.........o..:.V|..0.... N*..e*...G.,{...wb...-y..g.k7...,tI.|..........H....4E.2..!b........K..&q1..0.us|z...he/.T+6b.}.L........q...F....nTs.Vp!.........W.F..j...X
./.gIv..6G(Ze.h`.......<..w...........@!E..N.>..^.[..IO$T.]6.D..K%m.....LD @.
.......f!O....5 ...K...Y..}.I.o.]q0`..H&...d.aZ.1...P.......R.. C.jfM....;9........y.h.E)...r.....B....#.\......Q..fX..~....ixh ..t.q.y....BkR.nr.k5.`@.8..Z5_Gl.l.
...'t....q...... ....t8......_`.....:4>.H....S.e/=!.V.. .6...X.o..K.H...S@.3...a.....].j-.$Q.6..{..kr.....=a.....-.......-2....D.....&......:..y.DJQ.0....E....,Uc......H..6.`.u.....).f..R.xp.H....(.c.9..a.*.P$d..KD..;.x.$,....L.......`..x...p.[..d...z.,jV.[0....j.r."\..._....[......].o..5.Q*.Y.....b0.......-..B...^..)9....S.l...Ek?..~9......`....^...../G{Q14......7......SVV.A.>8..].
04:22:15.835726 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 2189, win 501, options [nop,nop,TS val 1478674662 ecr 861356474], length 0
E..4..@.>.}[..yX...,....)P..$U~............
X"..3WA.
04:22:15.835912 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.505
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
peerauthentication.security.istio.io "disable-mtls" deleted
peerauthentication.security.istio.io "force-mtls" deleted
deployment.apps "helloworld-mtls" deleted
deployment.apps "helloworld-nomtls" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld.default.svc.cluster.local" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/security/peer_authentication/#PeerAuthentication-MutualTLS-Mode
- https://istio.io/latest/docs/tasks/security/authentication/mtls-migration/
- https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication
- https://istio.io/latest/docs/reference/config/security/peer_authentication/

View File

@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---

View File

@ -0,0 +1,25 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: disable-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "false"
mtls:
mode: DISABLE
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: force-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "true"
mtls:
mode: STRICT

View File

@ -1,42 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
name: helloworld-mtls
labels:
app: helloworld
mtls: "true"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "true"
template:
metadata:
labels:
app: helloworld
sidecar.istio.io/inject: "true"
mtls: "true"
spec:
containers:
- name: helloworld
@ -44,7 +23,7 @@ spec:
resources:
requests:
cpu: "100m"
imagePullPolicy: Always #Always
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
@ -52,28 +31,29 @@ spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
name: helloworld-nomtls
labels:
app: nginx
version: v1
app: helloworld
mtls: "false"
spec:
replicas: 1
selector:
matchLabels:
app: nginx
version: v1
app: helloworld
mtls: "false"
template:
metadata:
labels:
app: nginx
version: v1
app: helloworld
mtls: "false"
spec:
containers:
- name: nginx
image: nginx
- name: helloworld-nomtls
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,100 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: mtls
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 80
uri:
exact: "/https-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: mtls
rewrite:
uri: "/"
- name: http-no-mTLS
match:
- port: 80
uri:
exact: "/http-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: nomtls
rewrite:
uri: "/"
- name: https-no-mTLS
match:
- port: 80
uri:
exact: "/https-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: nomtls
rewrite:
uri: "/"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
subsets:
- name: mtls
labels:
mtls: "true"
- name: nomtls
labels:
mtls: "false"
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend
---

View File

@ -0,0 +1,385 @@
---
gitea: none
include_toc: true
---
# Based on
- [01-disable-mTLS](../01-disable-mTLS)
# Description
Based on the previous example that disabled mTLS, and explored how it affected the behavior of the services, on `HTTP` and `HTTPS` backends, this example aims to, through the usage of `portLevelMtls`, configure the `mTLS` behavior based on the destination port.
Through this, we can apply multiple `mTLS` behaviors under a single deployment, unlike the [previous example](../01-disable-mTLS) that required to create 2 different deployments under a single service, and as well implement `Destination Rules` as well of `subsets` to route the traffic between the 2 deployments.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## 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
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## Virtual Service
Without limiting to any host, listens for traffic at port 80, and only has a very specific URL paths available to match.
The path `/http` will be routed to the `HTTP` service set in our backend.
The path `/http` will be routed to the `HTTPS` service set in our backend.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 80
uri:
exact: "/https"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
rewrite:
uri: "/"
```
## Destination Rule
Interfering with the service URL `helloworld.default.svc.cluster.local`, the traffic with port destination `8443`, will attempt to proceed with TLS termination, as it is required to connect with an `HTTPS` backend.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend
```
## Service
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment, which contains an `HTTPS` service.
Also listens for `HTTP` traffic at the port `8080`, and will be forwarded to the deployment port `80`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
```
## Deployment
The deployment listen to the port `80` and `443`, hosting an `HTTP` and `HTTPS` service respectively to the aforementioned ports.
> **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
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
Deployed a rule that sets a "global" mTLS mode to `STRICT`, meaning that the traffic require mTLS termination in order to proceed further with the request.
Also, at a specific port configuration, the port `443` has the mTLS mode disabled, as the deployment contains an `HTTPS` service we required to disable it in order of the request to be successful.
Through the use of the `selector.matchLabels` field, we targeted our deployment pods, limiting the target of this rule.
> **Note**:\
> In order to use the `portLevelMtls` field, the selector field is required, otherwise it won't take effect.\
> For more information regarding this behavior, refer to the [official Istio documentation regarding PeerAuthentication](https://istio.io/latest/docs/reference/config/security/peer_authentication/#PeerAuthentication)
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: helloworld-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls:
mode: STRICT
portLevelMtls:
443:
mode: DISABLE
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
peerauthentication.security.istio.io/helloworld-mtls created
deployment.apps/helloworld created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
```
## 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
```
## Test resources and analyze behaviors
[//]: # (> **DISCLAIMER**:\)
[//]: # (> For some reason, during the packet captures, I required to execute the curl 2 times in order for the output to be updated.\)
[//]: # (> During the tests, feel free to perform the curl twice in a row.)
### HTTP
#### Start the packet capture for the port 80
Start the packet capture and proceed with another shell or browser to send traffic requests to the right destination.
```shell
PORT=80 && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
Nothing to higlight so far, we can access the service.
```shell
curl 192.168.1.50/http
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
As we can observe, the traffic is encrypted, proving that the mTLS is taking effect terminating the connection with the `HTTP` backend.
```text
02:00:10.511593 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [S], seq 3999274711, win 64800, options [mss 1440,sackOK,TS val 2646430461 ecr 0,nop,wscale 7], length 0
E..<..@.>..I..yX...=.|.P.`......... .z.........
..R.........
02:00:10.512773 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [.], ack 134781521, win 507, options [nop,nop,TS val 2646430462 ecr 2887117842], length 0
E..4..@.>..P..yX...=.|.P.`.....Q...........
..R.....
02:00:10.512988 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [P.], seq 0:517, ack 1, win 507, options [nop,nop,TS val 2646430462 ecr 2887117842], length 517: HTTP
E..9..@.>..J..yX...=.|.P.`.....Q...........
..R.................a7.i..v{
.Nr.0.Yex..C7..k.6...d .......z._ikW3.C.H.....5..Yk.&.c.........+.../...,.0.......;.9..6outbound_.8080_._.helloworld.default.svc.cluster.local..........
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... .....M4...^9V........d_..+J."..Z.-.....+.......................................................................................................................................................................................................................
02:00:10.530088 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [.], ack 2164, win 499, options [nop,nop,TS val 2646430479 ecr 2887117859], length 0
E..4..@.>..N..yX...=.|.P.`...........3.....
..S....#
02:00:10.551166 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [P.], seq 517:2501, ack 2164, win 501, options [nop,nop,TS val 2646430500 ecr 2887117859], length 1984: HTTP
E.....@.>.....yX...=.|.P.`.................
..S$...#...........D.W_....+..v{..Q.3....^..m~..aU.+~t..%b....O.X|.).....=.w.z...'....`.2._...7.N..9.y..V.y.&..*vBx..z)B.g.D...1...x....V.J.*!....5.......#.......9.....V.Y..kes.&:+..j;.X5C.I...h+.SO0V....A..b,?.d.@YOy.`x.......o.EcTf}n.0....!N..Qh?.uK#?.Nx..q.&..9|?.)".qpg.]..O2.;O.x...J...$0.......I......1.X2.......2..=.UG.h'pA.CKX........
. . 7W.v...q..?IW.M:..'d....!2..Y......I.P..).Y..~..>.:k..y..Z?....w.D.Y<s. 3tg.wv...(.8.'.Nd..T...U...\.L.rM9..v........b...d..3...`..2....*. ...Qh...5.J
]. G...3..s..9.4....M..J..s..u.n..j....@.;.8.-LZD#t...z.;..2..M+.2.#.......E.....F.+.u.1.... l4..`......@..{......[.{
%[.R.e.v........@V....1...f*O$..V
pu........Zl...@.%......b..................}.J.....H...h?@[...T>..M.B.MXH.HDa...(.].B......k...{..c&.0...S3..]..2.a\.......?.#..........]3...~...Q|w...l."Z;.4..!.1..,X.>YE..3Yw..9.....#|.....[`...qq..@v.m..1.|V.j$t.C..&.Ww...5e....?.|Q."..obR.a...^...D8;...=.1.....S[.90...ss....-.@..q.JI........$.8..)skW.....G....3:.qb..#/....#...'/n.~F...(Y[.k..EEz}...cgR..6...P..)'.X..e..z....Tv0>....l.t.O=D.vc..}.a.ct.....E/.*..]-`.....O.hY..j..u...."(QZ.^.......f.1.LZ.O.L.9}..m.1_sC....x.*`D..ny.......):.V.."n..t.0....T.S..u[._v%...q`._.....W.w_.q...........O.:J.....[S.a$...l.[. ..cP..zF..~..+..|.....l.. [.l.."/
.....D6f....9:..i............N........o.....;...%v.0@...n^..."OSN.o*.:ap.C#C.Hc..r..MD.
.-..2....
..`...."..I...Wh9.L...r:.4M...b+q
...8f...*.^.K.k.?7:.\..O... ..cD.<t.%$.U..^(..............J.Y..0.[..Z..g.Ok..6/.{.-zjY.K2.Z...)\..RH..*i...=d..z....Dk.n7.0S.).6..D!Y... 2.DnP.9...Gz.:)..D.1.......*...(+...+G)...e.......].qi..eFO..h[.`..4..uk..%..U.........F.......-X.)g..w.=..Q/.f...?+.[\..9.......UW.]..y...e.....ENDG....M.K......~.-.'.....&.-7...k...M..y.8..&.yq.m...`.E...X..67}..L.........Y,F.iS...X.f..Fa.l.'.u.&.x.....2...c.....aw
......}..~.!....pj....m
....5.V......o....{U..M.......q.%.E..$j......Fo.|m......pR...r...v.P<V.!....;.... ...r....&....D...,{.U...?,F..(........y}..G......sfFE....9o...q>.c........jM....;......k....
02:00:10.551752 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.54396 > helloworld-6798765f88-76r6c.http: Flags [P.], seq 2501:4170, ack 2164, wi
```
#### HTTPS
##### Start the packet capture for the port 443
```shell
PORT=443 && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
Even tho, we have set in the [PeerAuthentication configuration](#peerauthentication) mode to `STRICT`, unlike in the [previous example](../01-disable-mTLS/#https-1), where the mode was also set to `STRICT`, in this example we configured the `portLevelMtls` field for the port `443`, successfully disabling `mTLS` for this port, and allowing to proceed with the request towards the `HTTPS` backend; which was performed without the need of disabling `mTLS` for the whole deployment.
```shell
curl 192.168.1.50/https
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to the configuration set in the [Destination Rule](#destination-rule), where we set the `tls.mode` setting to `SIMPLE`, the traffic will be TLS terminated with the backend.
For such, the traffic captured is encrypted, even tho we displayed the `mTLS` configuration for this deployment.
Yet, there are still a couple readable lines, where we can see that the request was initialized by the host `stio-ingressgateway.istio-system.svc.cluster.local`, through the egress port `39884`, using as destination `helloworld-nomtls-66d8499c5c-298vw`, and the port defined with name `https`, which, if we reviewed the configuration from the [Service](#service), we would observe that it was the port `8443`.
```text
02:02:41.616839 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [S], seq 1052122243, win 64800, options [mss 1440,sackOK,TS val 2646581565 ecr 0,nop,wscale 7], length 0
E..<.y@.>.....yX...=....>.......... ...........
...=........
02:02:41.618256 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [.], ack 1254443190, win 507, options [nop,nop,TS val 2646581567 ecr 2887268947], length 0
E..4.z@.>.....yX...=....>...J.H............
...?..:S
02:02:41.618902 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [P.], seq 0:246, ack 1, win 507, options [nop,nop,TS val 2646581568 ecr 2887268947], length 246
E..*.{@.>.....yX...=....>...J.H.....T......
...@..:S............
.B.L(....I....`O.#.$-..f..y.'. :.&.....1oX.i.J.W.CD.-.l.|...y...........+.../...,.0..............
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... .vw..q|H[6.HQp.zn[. m...M0yL..]g.-.....+.......
02:02:41.637813 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [.], ack 1377, win 501, options [nop,nop,TS val 2646581587 ecr 2887268967], length 0
E..4.|@.>.....yX...=....>..zJ.N......4.....
...S..:g
02:02:41.641084 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [P.], seq 246:310, ack 1377, win 501, options [nop,nop,TS val 2646581590 ecr 2887268967], length 64
E..t.}@.>..M..yX...=....>..zJ.N............
...V..:g..........5D\..yfI.....]iyu.:........m!Ev.....*..-..`.'*.......g
02:02:41.642627 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [.], ack 1632, win 501, options [nop,nop,TS val 2646581592 ecr 2887268972], length 0
E..4.~@.>.....yX...=....>...J.O............
...X..:l
02:02:41.642884 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [.], ack 1887, win 501, options [nop,nop,TS val 2646581592 ecr 2887268972], length 0
E..4..@.>.....yX...=....>...J.P............
...X..:l
02:02:41.643146 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.58752 > helloworld-6798765f88-76r6c.https: Flags [P.], seq 310:1981, ack 1887, win 501, options [nop,nop,TS val 2646581592 ecr 2887268972], length 1671
E.....@.>.....yX...=....>...J.P......f.....
...X..:l...............*t\o.....z^=.=\....cq..../.9eKL..`.C....."....q{...*..0;^n7.o:,...a..-.W8:.1..c........Z..b.......i...4....B.. .-2...+3$i.!.......7..._.T..G`...Ar.D.a.....U..^....^.Q.h.._.p.H..9.*O.5)-T_....7}8.>."...j..)e.^..-.'.L....Y9.6d...Z...<.....hygo.z\H.11...q{.*T....V.>K.9\HJ...7.....m.r:.(...s.'5|_...F..X&..>#(..]...H.6.V....(.4z..3,...e.P.r..H..A<a*:&..".7)......$.kv...y.....;....#.b.3.8....dVQ....]*Nk{.....T...o. .../...o5......=.!_..:....L.......S.J..u)\.*....$...I..-...!...kAK%.s.t.*.<.j.......w.z.'.7t....K-:.....:.?....GmA$.j.....@D...q.wE]..').........J.'....
..).p.[..._..6.'Dg.h..,(8:...%_.%....ES_.g.O.Q{.*...=..6{.Tx_.[..d.g...?# .Yk./..Zl.hX.....T....R...z.Y..A/.,......p<G..L'.FN.....O.n...Fz.7Tl}.%0`....].;<.-.$S..#...r.7..7b.0v.>.[...[....S.YNp......C..LN.....z.r.....6.J..".H...%=T.f.O...84........(..r@O#.3C...9.G..m.D.J...a.w....).GuC?.,.].9a..4...1....MoG8l..u..hV.h.6....Z`....+..9.aAW.]..,_7.@...y..._{.....buwy).q.\L.L....E2..~....',.J............Z.._...G......4,....o.w2
...`....qp.. .g..iP.Vdw...W9.B...q..<...F...j..-G.!\..3r+\.T....{d$....Ys..4.J....D.["..-
(E.l..H7.iw.....?....?p..cI#qu...mK.T...qp.[g..%.2...|....7O...u.K..........?....s.......J.#%...;._.....>..Z......7DA...P.fg.......N..Oz..+....3........y..+...r..*.....[...xT...J...}..n...n...V ..P...<..y..U.^.....90.......4..'..p.E..F2.....~.GBG.....@v<....;m dd..z~..>\..T$.i..Da...M.!xR......x6.h...l...m.I.Zl ..t
.g..c..w...EEtq.s.......8...x.E.|..%e..n..b.FA'..w..
..
.H.d... ...H>K.......O..#'.`....q..0.K>...".c.~.\.......N..$.
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
peerauthentication.security.istio.io "helloworld-mtls" deleted
deployment.apps "helloworld" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld.default.svc.cluster.local" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/security/peer_authentication/#PeerAuthentication

View File

@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---

View File

@ -0,0 +1,14 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: helloworld-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls:
mode: STRICT
portLevelMtls:
443:
mode: DISABLE

View File

@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
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

View File

@ -12,16 +12,6 @@ spec:
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
@ -33,38 +23,40 @@ spec:
gateways:
- helloworld-gateway
http:
- name: http-vs
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- name: https-vs
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 443
- port: 80
uri:
exact: "/https"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
rewrite:
uri: "/"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: default
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8080
tls:
mode: SIMPLE
- port:
number: 8443
tls:
mode: SIMPLE
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend

View File

@ -33,4 +33,31 @@ Internal and external authentication should be set together.
https://istio.io/latest/docs/ops/diagnostic-tools/proxy-cmd/
https://istio.io/latest/docs/ops/deployment/deployment-models/
## Services port names
Istio allows to specify which protocol will run through a port.
It requires the name of the port to be set to a specific format `name: <protocol>(-<suffix>)`.
Starting from Kubernetes 1.18, it also can be specified through the `appProtocol` field in the port, resulting in `appProtocol: <protocol>`.
This means that port names should respect this format to avoid issues, and for such be cautious when setting up the name of the ports.
This applies to multiple Istio elements, but as well to `kind: Services` from default Kubernetes.
For more information about this behavior, refer to:
https://istio.io/latest/docs/ops/configuration/traffic-management/protocol-selection/#explicit-protocol-selection
# Workload selector is cool
- https://istio.io/latest/docs/reference/config/type/workload-selector/#WorkloadSelector
# Links of interest
- https://istiobyexample.dev/

View File

@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
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

View File

@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100

View File

@ -0,0 +1,50 @@
# https://raw.githubusercontent.com/istio/istio/release-1.17/samples/httpbin/sample-client/fortio-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: fortio
labels:
app: fortio
service: fortio
spec:
ports:
- port: 8080
name: http
selector:
app: fortio
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fortio-deploy
spec:
replicas: 1
selector:
matchLabels:
app: fortio
template:
metadata:
annotations:
# This annotation causes Envoy to serve cluster.outbound statistics via 15000/stats
# in addition to the stats normally served by Istio. The Circuit Breaking example task
# gives an example of inspecting Envoy stats via proxy config.
proxy.istio.io/config: |-
proxyStatsMatcher:
inclusionPrefixes:
- "cluster.outbound"
- "cluster_manager"
- "listener_manager"
- "server"
- "cluster.xds-grpc"
labels:
app: fortio
spec:
containers:
- name: fortio
image: fortio/fortio
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: http-fortio
- containerPort: 8079
name: grpc-ping

View File

@ -0,0 +1,382 @@
---
gitea: none
include_toc: true
---
## Description
This example displays how to configure a `circuit breaking` in Istio, as well on how to test it and trigger the limits sets.
## Based on
This example is based on the [ **OFFICIAL** Istio documentation example regarding circuit breaking](https://istio.io/latest/docs/tasks/traffic-management/circuit-breaking/).
## Fortio
aka. `Fortio` allows you to send traffic requests meanwhile being allowed to have some degree of control over them.
This is useful as we will try to reach/trigger the limits set in the DestinationRule configuration.
# Configuration
## Service
The service will forward incoming traffic from the service port `8080`, that will be forwarded towards the port `80` from the deployment, which contains an `HTTP` service.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
selector:
app: helloworld
```
## Deployment
The deployment listen to the port `80` and `443`, hosting an `HTTP` and `HTTPS` service respectively to the aforementioned ports.
> **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
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
```
## Destination rule
This destination rule configures and sets limits to the traffic with host destination `helloworld.default.svc.cluster.local`.
- `connectionPool.tcp.maxConnections` being set to 1, limits the amount of simultaneous maximum number of connections to 1.
- `connectionPool.http.http1MaxPendingRequests`: Number of queued requests.
- `connectionPool.http.maxRequestsPerConnection`: Limits the amount of connections to the backend by source of the request, if 1 is set in this field (which is our scenario), it disables the keep alive configuration.
- `outlierDetection.consecutive5xxErrors`: Number of status codes `5XX` required before a host is ejected from the connection pool.
- `outlierDetection.interval`: Time between each analysis.
- `outlierDetection.baseEjectionTime`: Minimum of time that a host is ejected from the connection pool.
- `outlierDetection.maxEjectionPercent`: Maximum of hosts available to be ejected, as we set it to 100%, and as well we have only 1 deployment, whenever this rule is required to be triggered, it will allow the trigger to proceed to remove the host from the connection pool, finally resulting in all the hosts to be ejected.
> **Note:**/
> For more information regarding `DestinationRules` and their configuration fields, reffer to the following [official Istio documentation regarding `DestinationRules`](https://istio.io/latest/docs/reference/config/networking/destination-rule/).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld created
service/fortio created
deployment.apps/fortio-deploy created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
```
## Test deployments
### helloworld.default.svc.cluster.local
#### Check connectivity from `fortio` to `helloworld`
We will use the package `/usr/bin/fortio` to send a `curl` request towards the `helloworld` service deployment.
If it doesn't work, ensure that the URL And IP are the right ones, as well if there isn't a `AuthorizationPolicy` that limits the traffic (also ensure that the deployments are ready `kubectl get deployments -w -n default -owide`).
```shell
kubectl exec -n default "$(kubectl get pod -n default -l app=fortio -o jsonpath={.items..metadata.name})" -- /usr/bin/fortio curl -quiet helloworld.default.svc.cluster.local:8080
```
```text
HTTP/1.1 200 OK
server: envoy
date: Sat, 29 Apr 2023 04:12:37 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
x-envoy-upstream-service-time: 100
<h2>Howdy</h2>
```
#### Perform a stress test of the resources deployed
Through the `Fortio` container, we will execute the following command `fortio load -c 2 -qps 0 -n 20`:
- `fortio`: The package used.
- `load`: It's used to gather statistics.
- `-c 2`: Number of simultaneous connections.
- `-qps 0`: Queries per second, if it's set to `0`, means that there is no limit and will try to send it as fast/maximum as possible.
- `-n 20`: Send 20 queries.
> **Note:**\
> For more information regarding the available possible command configurations, refer to the respective [Fortio documentation on Github](https://github.com/fortio/fortio#command-line-arguments)
```shell
kubectl exec -n default "$(kubectl get pod -n default -l app=fortio -o jsonpath={.items..metadata.name})" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning helloworld.default.svc.cluster.local:8080
```
```text
04:16:28 I logger.go:183> Log level is now 3 Warning (was 2 Info)
Fortio 1.54.2 running at 0 queries per second, 8->8 procs, for 20 calls: helloworld.default.svc.cluster.local:8080
04:16:28 W http_client.go:170> Assuming http:// on missing scheme for 'helloworld.default.svc.cluster.local:8080'
Starting at max qps with 2 thread(s) [gomax 8] for exactly 20 calls (10 per thread + 0)
04:16:28 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
04:16:28 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
Ended after 259.87612ms : 20 calls. qps=76.96
Aggregated Function Time : count 20 avg 0.02460594 +/- 0.02677 min 0.0010981 max 0.090700113 sum 0.492118798
# range, mid point, percentile, count
>= 0.0010981 <= 0.002 , 0.00154905 , 15.00, 3
> 0.002 <= 0.003 , 0.0025 , 20.00, 1
> 0.003 <= 0.004 , 0.0035 , 25.00, 1
> 0.005 <= 0.006 , 0.0055 , 30.00, 1
> 0.007 <= 0.008 , 0.0075 , 40.00, 2
> 0.011 <= 0.012 , 0.0115 , 45.00, 1
> 0.012 <= 0.014 , 0.013 , 55.00, 2
> 0.016 <= 0.018 , 0.017 , 60.00, 1
> 0.018 <= 0.02 , 0.019 , 65.00, 1
> 0.025 <= 0.03 , 0.0275 , 75.00, 2
> 0.03 <= 0.035 , 0.0325 , 80.00, 1
> 0.05 <= 0.06 , 0.055 , 85.00, 1
> 0.07 <= 0.08 , 0.075 , 95.00, 2
> 0.09 <= 0.0907001 , 0.0903501 , 100.00, 1
# target 50% 0.013
# target 75% 0.03
# target 90% 0.075
# target 99% 0.0905601
# target 99.9% 0.0906861
Error cases : count 8 avg 0.012249498 +/- 0.01797 min 0.0010981 max 0.054279663 sum 0.097995986
# range, mid point, percentile, count
>= 0.0010981 <= 0.002 , 0.00154905 , 37.50, 3
> 0.002 <= 0.003 , 0.0025 , 50.00, 1
> 0.003 <= 0.004 , 0.0035 , 62.50, 1
> 0.005 <= 0.006 , 0.0055 , 75.00, 1
> 0.025 <= 0.03 , 0.0275 , 87.50, 1
> 0.05 <= 0.0542797 , 0.0521398 , 100.00, 1
# target 50% 0.003
# target 75% 0.006
# target 90% 0.0508559
# target 99% 0.0539373
# target 99.9% 0.0542454
# Socket and IP used for each connection:
[0] 6 socket used, resolved to 10.99.49.188:8080, connection timing : count 6 avg 0.00037803967 +/- 0.0001574 min 0.000231869 max 0.00069415 sum 0.002268238
[1] 4 socket used, resolved to 10.99.49.188:8080, connection timing : count 4 avg 0.00045579175 +/- 9.155e-05 min 0.0003847 max 0.000612777 sum 0.001823167
Connection time (s) : count 10 avg 0.0004091405 +/- 0.0001403 min 0.000231869 max 0.00069415 sum 0.004091405
Sockets used: 10 (for perfect keepalive, would be 2)
Uniform: false, Jitter: false, Catchup allowed: true
IP addresses distribution:
10.99.49.188:8080: 10
Code 200 : 12 (60.0 %)
Code 503 : 8 (40.0 %)
Response Header Sizes : count 20 avg 167.7 +/- 136.9 min 0 max 280 sum 3354
Response Body/Total Sizes : count 20 avg 273.1 +/- 26.21 min 241 max 295 sum 5462
All done 20 calls (plus 0 warmup) 24.606 ms avg, 77.0 qps
```
#### Information to highlight
From the output received, I would like to focus in the following entry, which states that 60% of the traffic was successful (returning a status code `200`), meanwhile 40% failed (returning status code `503`).
```text
Code 200 : 12 (60.0 %)
Code 503 : 8 (40.0 %)
```
### Check Fortio istio-proxy logs (`pilot-agent request GET stats`)
Check (Fortio's app) istio-proxy logs
```shell
kubectl exec "$(kubectl get pod -n default -l app=fortio -o jsonpath={.items..metadata.name})" -c istio-proxy -- pilot-agent request GET stats | grep helloworld | grep pending
```
```text
cluster.outbound|8080||helloworld.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1
cluster.outbound|8080||helloworld.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|8080||helloworld.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|8080||helloworld.default.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|8080||helloworld.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
cluster.outbound|8080||helloworld.default.svc.cluster.local.upstream_rq_pending_overflow: 3
cluster.outbound|8080||helloworld.default.svc.cluster.local.upstream_rq_pending_total: 18
```
If we review the field `upstream_rq_pending_overflow`, where it states that the value is set to `3`, it means that 3 entries where flagged for circuit breaking.
## helloworld.default
### Test destination URL `helloworld.default`
Same procedure as the step [Perform a stress test of the resources deployed](#perform-a-stress-test-of-the-resources-deployed), but instead of using the destination URL `helloworld.default.svc.cluster.local`, we will be using the URL `helloworld.default` to confirm if the destination rule is still being applied even if the full URL doesn't match.
```shell
kubectl exec -n default "$(kubectl get pod -n default -l app=fortio -o jsonpath={.items..metadata.name})" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning helloworld.default:8080
```
```text
20:01:10 I logger.go:183> Log level is now 3 Warning (was 2 Info)
Fortio 1.54.2 running at 0 queries per second, 8->8 procs, for 20 calls: helloworld.default:8080
20:01:10 W http_client.go:170> Assuming http:// on missing scheme for 'helloworld.default:8080'
Starting at max qps with 2 thread(s) [gomax 8] for exactly 20 calls (10 per thread + 0)
20:01:10 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [1] Non ok http code 503 (HTTP/1.1 503)
20:01:10 W http_client.go:1058> [0] Non ok http code 503 (HTTP/1.1 503)
Ended after 162.18683ms : 20 calls. qps=123.31
Aggregated Function Time : count 20 avg 0.014704745 +/- 0.01561 min 0.001096933 max 0.044131073 sum 0.294094897
# range, mid point, percentile, count
>= 0.00109693 <= 0.002 , 0.00154847 , 30.00, 6
> 0.003 <= 0.004 , 0.0035 , 35.00, 1
> 0.004 <= 0.005 , 0.0045 , 45.00, 2
> 0.005 <= 0.006 , 0.0055 , 50.00, 1
> 0.006 <= 0.007 , 0.0065 , 55.00, 1
> 0.011 <= 0.012 , 0.0115 , 60.00, 1
> 0.014 <= 0.016 , 0.015 , 65.00, 1
> 0.016 <= 0.018 , 0.017 , 70.00, 1
> 0.018 <= 0.02 , 0.019 , 75.00, 1
> 0.035 <= 0.04 , 0.0375 , 90.00, 3
> 0.04 <= 0.0441311 , 0.0420655 , 100.00, 2
# target 50% 0.006
# target 75% 0.02
# target 90% 0.04
# target 99% 0.043718
# target 99.9% 0.0440898
Error cases : count 11 avg 0.0029070851 +/- 0.001827 min 0.001096933 max 0.006039404 sum 0.031977936
# range, mid point, percentile, count
>= 0.00109693 <= 0.002 , 0.00154847 , 54.55, 6
> 0.003 <= 0.004 , 0.0035 , 63.64, 1
> 0.004 <= 0.005 , 0.0045 , 81.82, 2
> 0.005 <= 0.006 , 0.0055 , 90.91, 1
> 0.006 <= 0.0060394 , 0.0060197 , 100.00, 1
# target 50% 0.00190969
# target 75% 0.004625
# target 90% 0.0059
# target 99% 0.00603507
# target 99.9% 0.00603897
# Socket and IP used for each connection:
[0] 6 socket used, resolved to 10.98.152.137:8080, connection timing : count 6 avg 0.00047558633 +/- 0.0001364 min 0.000294869 max 0.000739941 sum 0.002853518
[1] 7 socket used, resolved to 10.98.152.137:8080, connection timing : count 7 avg 0.000457311 +/- 0.0001076 min 0.000320826 max 0.000596445 sum 0.003201177
Connection time (s) : count 13 avg 0.00046574577 +/- 0.0001221 min 0.000294869 max 0.000739941 sum 0.006054695
Sockets used: 13 (for perfect keepalive, would be 2)
Uniform: false, Jitter: false, Catchup allowed: true
IP addresses distribution:
10.98.152.137:8080: 13
Code 200 : 9 (45.0 %)
Code 503 : 11 (55.0 %)
Response Header Sizes : count 20 avg 125.9 +/- 139.2 min 0 max 280 sum 2518
Response Body/Total Sizes : count 20 avg 265.2 +/- 26.76 min 241 max 295 sum 5304
All done 20 calls (plus 0 warmup) 14.705 ms avg, 123.3 qps
```
As we can see, the rules are still being applied, this time resulting in a 45% of the traffic receiving a successful status code (`200`), meanwhile a 55% received a failure status code (`503`).
This confirms that, even if the full URL is not the same as the configured in the [DestinationRule](#destination-rule), the DestinationRule is still being enforced.
## Cleanup
```shell
kubectl delete -f ./
```
```text
deployment.apps "helloworld" deleted
destinationrule.networking.istio.io "helloworld.default.svc.cluster.local" deleted
service "fortio" deleted
deployment.apps "fortio-deploy" deleted
service "helloworld" deleted
```
## Links of interest
- https://raw.githubusercontent.com/istio/istio/release-1.17/samples/httpbin/sample-client/fortio-deploy.yaml
- https://istio.io/latest/docs/tasks/traffic-management/circuit-breaking/#adding-a-client
- https://github.com/fortio/fortio
- https://github.com/fortio/fortio#command-line-arguments
- https://istio.io/latest/docs/reference/config/networking/destination-rule/
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-TCPSettings
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-HTTPSettings

View File

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
selector:
app: helloworld
---

View File

@ -1 +0,0 @@
# Example from istio, storing it for testing purposes

View File

@ -1,343 +0,0 @@
# Copyright Istio Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##################################################################################################
# This file defines the services, service accounts, and deployments for the Bookinfo sample.
#
# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
#
# Alternatively, you can deploy any resource separately:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
##################################################################################################
##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
---