Istio is an open source service mesh that lets you run distributed, microservices-based apps anywhere. It helps you manage and connect the different microservices in your Scaleway Kubernetes cluster, making it easier to build and maintain complex applications.
This tutorial describes the steps required to deploy Istio on a Scaleway Kubernetes Kapsule cluster, and configure it to support Proxy Protocol v2. This enables connection information from a client (e.g. their IP address) to be passed through the cluster's Load Balancer onto the target pod or service, via the Istio service mesh.
Before you startTo complete the actions presented below, you must have:
Add the Istio Helm repository:
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
Create a Kubernetes namespace for Istio:
kubectl create namespace istio-system
Install the Istio base and control plane into the previously created namesapce:
helm install istio-base istio/base -n istio-system
helm install istiod istio/istiod -n istio-system --wait
Install the Istio ingress Gateway:
helm install istio-ingressgateway istio/gateway -n istio-system --wait
Deploy a simple application to test how Istio works with a Load Balancer. In this tutorial we use httpbin
as test application.
Create and label a new namespace for the test application:
kubectl create namespace test-app
kubectl label namespace test-app istio-injection=enabled
Apply the following configuration using kubectl
:
kubectl apply -n test-app -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
spec:
selector:
app: httpbin
ports:
- name: http
port: 80
targetPort: 80
EOF
Define a Gateway and a VirtualService to expose the application via the Istio IngressGateway.
kubectl
:kubectl apply -n test-app -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: httpbin-gateway
namespace: test-app
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
# virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: test-app
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- route:
- destination:
host: httpbin
port:
number: 80
EOF
Run the following command to retrieve the IP of your Load Balancer and save it in the $LB_IP
variable:
export LB_IP=$(kubectl get svc -n istio-system istio-ingressgateway -o
jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $LB_IP
Run the following command to do a test before proxy forward is configured:
curl -v http://$LB_IP/get
You will get an output similar to the following example:
curl -v
http://$LB_IP/get
* Trying 51.159.112.157:80...
* Connected to 51.159.112.157 (51.159.112.157) port 80
> GET /get HTTP/1.1
> Host: 51.159.112.157
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Mon, 24 Feb 2025 09:06:45 GMT
< content-type: application/json
< content-length: 491
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 19
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "51.159.112.157",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-Internal": "true",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/testapp/sa/default;Hash=ddf3ba6fee32a74f9a83efd752df7960c9f3139fa1fe979370becddad3def062;Subject=\"\";URI=spiffe://cluster.local/ns/istiosystem/sa/istio-ingressgateway"
},
"origin": "172.16.16.5",
"url": "http://51.159.112.157/get"
}
* Connection #0 to host 51.159.112.157 left intact
When you deploy a LoadBalancer service in Kubernetes, Scaleway automatically creates a Load Balancer and associates it with your service. You now need to activate Proxy Protocol V2
for this Load Balancer.
Modify the istio-ingressgateway
service to add the necessary annotations:
kubectl annotate -n istio-system services istio-ingressgateway \
service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2=true
kubectl annotate -n istio-system services istio-ingressgateway \
service.beta.kubernetes.io/scw-loadbalancer-use-hostname=true
Configure Proxy protocol and the X-Forwarded-For header to retrieve the source IP
Create an EnvoyFilter
to enable Proxy Protocol support:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: proxy-protocol
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: LISTENER
patch:
operation: MERGE
value:
listener_filters:
- name: envoy.filters.listener.proxy_protocol
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
- name: envoy.filters.listener.tls_inspector
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
EOF
Run the curl -v http://$LB_IP/get
command again and watch the output. You will get an output similar to the following example:
curl -v http://$LB_IP/get
* Trying 51.159.112.157:80...
* Connected to 51.159.112.157 (51.159.112.157) port 80
> GET /get HTTP/1.1
> Host: 51.159.112.157
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Mon, 24 Feb 2025 09:11:46 GMT
< content-type: application/json
< content-length: 510
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 4
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "51.159.112.157",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "62.210.16.37",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/test-app/sa/default;Hash=ddf3ba6fee32a74f9a83efd752df7960c9f3139fa1fe979370becddad3def062;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway"
},
"origin": "62.210.16.37",
"url": "http://51.159.112.157/get"
}
* Connection #0 to host 51.159.112.157 left intact
Configure Istio using kubectl
to ensure that the source IP is correctly transmitted via the X-Forwarded-For
header.
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ingressgateway-settings
namespace: istio-system
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
patch:
operation: MERGE
value:
name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
skip_xff_append: false
use_remote_address: true
xff_num_trusted_hops: 1
EOF
You will get an output similar to the following one, after you have configured proxy forward and X-Forward-For
curl -v http://$LB_IP/get
* Trying 51.159.112.157:80...
* Connected to 51.159.112.157 (51.159.112.157) port 80
> GET /get HTTP/1.1
> Host: 51.159.112.157
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Mon, 24 Feb 2025 09:14:32 GMT
< content-type: application/json
< content-length: 522
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 2
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "51.159.112.157",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "62.210.16.37",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/test-app/sa/default;Hash=7e20594ba5421aa9df88b0d025498a5c51d02b0224daa3faea319c13a106d8b6;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway"
},
"origin": "62.210.16.37,100.64.2.46",
"url": "http://51.159.112.157/get"
}
* Connection #0 to host 51.159.112.157 left intact
Once you have added the configurations, you may need to restart the IngressGateway pods so that the changes to take effect.
Run the following command to delete the existing pods using kubectl
. Kubernetes will spin up new ones automatically after you launch the command:
kubectl delete pod -n istio-system -l istio=ingressgateway
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4