Files rebasing

This commit is contained in:
savagebidoof
2023-05-10 10:15:00 +02:00
parent fb34758197
commit c7c1f8cb9c
72 changed files with 7 additions and 29 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,345 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../../03-Gateway_Ingress/08a-HTTPS-min-TLS-version)
# Description
This example contains a backend that serves HTTPS traffic and can be accessed from both `HTTP` and `HTTPS` requests through the gateway resource.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway is configured to listen to the port `80` for `HTTP` traffic, and to the port `443` for `HTTPS` traffic.
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`.
Any of the configured ports has limited the hosts.
```shell
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
mode: SIMPLE
```
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
## VirtualService
The rule that contains, will receive traffic from the port `443` and `80`.
This traffic will be directed towards destination of such is the service `helloworld.default.svc.cluster.local`, with port destination 8443.
This destination is the service that contains the `HTTPS` deployment, running over the port `8443`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-vs
match:
- port: 80
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## DestinationRule
This DestinationRule, will interject the traffic destined to the service `helloworld.default.svc.cluster.local` with port `8443`.
As mentioned in the [Virtual Service](#virtualservice) section, the destination is the `HTTPS` service.
By default, the call would be made with `HTTP` protocol, yet, as the destination is an `HTTPS` service, the request would result in the status code `400 Bad Request`, due sending HTTP traffic to an HTTPS service.
To avoid this, we need to specify that the destination handles HTTPS traffic.
By setting the `tls.mode` field with `simple`, it means that there will be an attempt to initialize a TLS handshake.
> **Note:**
> For more information about the TLS mode, refer to the [Istio official documentation from the DestinationRule object regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE
```
## Service
The service will forward incoming TCP traffic from the port `8443`, towards the deployment port `443`.
It's been specified the protocol expected to service, it being `HTTPS`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- name: https
port: 8443
targetPort: 443
protocol: TCP
appProtocol: HTTPS
selector:
app: helloworld
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentication
Due to the deployment having an `HTTPS`, and already initializing a TLS termination towards that service, we need to disable the **mTLS** tool for that specific service/deployment.
On the [Destination Rule](#destinationrule) section we set the `tls` to `simple`, meaning that the service is expecting to receive `HTTPS` traffic, if `mTLS` is enabled, it will perform the handshake with the `mTLS` service, instead of with the destination `HTTPS` service.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: default
spec:
mtls:
mode: DISABLE
```
> **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](../../08-AuthorizationPolicy/02-target-service-accounts), which shows how to target service accounts set to resources, limiting the scope of this rule set.
# 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
peerauthentication.security.istio.io/default-mtls created
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld created
```
## Test the service
### Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### curl HTTP gateway
Well, it works as expected.
```shell
curl --insecure 192.168.1.50 -I
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Tue, 25 Apr 2023 04:41:19 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: 28
```
### curl HTTPS gateway
Well, it works as expected.
```shell
curl --insecure https://192.168.1.50 -I
```
```text
HTTP/2 200
server: istio-envoy
date: Tue, 25 Apr 2023 04:42:07 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: 13
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
peerauthentication.security.istio.io "default-mtls" deleted
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#Gateway
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode

View File

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

View File

@ -0,0 +1,43 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,57 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-vs
match:
- port: 80
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE

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