Preserve source IP address Istio Ingress gateway
Reference
Setup test environment
Install Istio
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
helm install istio-base istio/base -n istio-system --create-namespace --wait
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -; }
helm install istiod istio/istiod --namespace istio-system --set profile=ambient
helm install istio-ingressgateway istio/gateway -n istio-system
Create test resources
Firstly, make sure namespace is labeled with istio-injection=enabled.
kubectl label namespace default istio-injection=enabled
Then, create debug pod and service. (NOTE: Should not use nginx pod because it has some issue).
kubectl create deployment echo-server --image=mccutchen/go-httpbin
kubectl expose deployment echo-server --name=clusterip --port=80 --target-port=8080 --type=ClusterIP
Create a service entry for the service.
cat > config.yaml <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: clusterip-gateway
spec:
selector:
istio: ingressgateway # Choose the appropriate selector for your environment
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "clusterip.jimmysong.io" # Replace with the desired hostname
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: clusterip-virtualservice
spec:
hosts:
- "clusterip.jimmysong.io" # Replace with the same hostname as in the Gateway
gateways:
- clusterip-gateway # Use the name of the Gateway here
http:
- route:
- destination:
host: clusterip.default.svc.cluster.local # Replace with the actual hostname of your Service
port:
number: 80 # Port of the Service
EOF
kubectl apply -f config.yaml
Open 3 terminal to watch log from istio-ingressgateway and echo-server pod.
kubectl -n istio-system logs -l app=istio-ingressgateway -f
kubectl logs -l app=echo-server -f -c istio-proxy
kubectl logs -l app=echo-server -f
Open one more terminal to send request to the service.
watch -n 1 "curl -H \"Host: clusterip.jimmysong.io\" ________________" # Replace with the IP of the Istio Ingress Gateway
Expected output:
- All IP addresses to 2 pods are the same (load balancer IP).
Preserve source IP address
Firstly, enable proxy-protocol in LB to preserve source IP address.
kubectl annotate service -n istio-system istio-ingressgateway vks.vngcloud.vn/enable-proxy-protocol="*"
Then, update gateway to use PROXY protocol. Be careful, this command can OVERWRITE the current configuration.
kubectl patch deployment istio-ingressgateway -n istio-system -p '{"spec":{"template":{"metadata":{"annotations":{"proxy.istio.io/config":"{\"gatewayTopology\":{\"proxyProtocol\":{}}}"}}}}}'
Expected output:
- All IP addresses to 2 pods are same (source IP address of request).
Clean up
kubectl delete deployment echo-server
kubectl delete service clusterip
kubectl delete -f config.yaml
helm -n istio-system uninstall istio-base istiod istio-ingressgateway