network topology
client --> google cloud Network (Passthrough) TCP Load balancing --> traefik --> k3s pods
How to install it
I used several virtual machines to build a K3S cluster, and Traefik was installed directly through K3S
traefik version
rancher/mirrored-library-traefik:2.11.10
k3s ingress && middlewares
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: proxy-headers
namespace: prod
resourceVersion: '622452'
spec:
headers:
customRequestHeaders:
Host: '{Host}'
X-Forwarded-For: '{ClientIP}'
X-Forwarded-Host: '{Host}'
X-Forwarded-Port: '{ServerPort}'
X-Forwarded-Proto: '{Protocol}'
X-Real-IP: '{ClientIP}'
http_x_forwarded_for: '{ClientIP}'
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: 'web, websecure'
traefik.ingress.kubernetes.io/router.middlewares: >-
default-http-to-https-redirect@kubernetescrd,prod-proxy-headers@kubernetescrd
...
spec:
ingressClassName: traefik
What I hope to get
sourceIP from client
What I actually get
use a simple python script
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
def capture_headers():
headers = dict(request.headers) # 获取所有传入的 header
print("Received headers:")
for key, value in headers.items():
print(f"{key}: {value}")
return jsonify(headers), 200 # 将 header 以 JSON 格式返回到客户端
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
svclb-traefik DaemonSet pods ip (like: 10.42.1.29
)
{"Accept":"*/*","Accept-Encoding":"gzip","Host":"","User-Agent":"curl/7.81.0","X-Forwarded-For":"{ClientIP}, 10.42.1.29","X-Forwarded-Host":"{Host}","X-Forwarded-Port":"{ServerPort}","X-Forwarded-Proto":"{Protocol}","X-Forwarded-Server":"traefik-7445d5d6-2cmnf","X-Real-Ip":"{ClientIP}"}
The modifications I made
- edit traefik svc yaml
---
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: traefik
meta.helm.sh/release-namespace: kube-system
finalizers:
- service.kubernetes.io/load-balancer-cleanup
labels:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: traefik
helm.sh/chart: traefik-27.0.201_up27.0.2
name: traefik
namespace: kube-system
resourceVersion: '634622'
spec:
allocateLoadBalancerNodePorts: true
externalTrafficPolicy: Local # here
internalTrafficPolicy: Cluster
- edit traefik forwardedHeaders.trustedIP
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: traefik
namespace: kube-system
spec:
chart: https://%{KUBERNETES_API}%/static/charts/traefik-27.0.201+up27.0.2.tgz
set:
global.systemDefaultRegistry: ""
valuesContent: |-
deployment:
podAnnotations:
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
providers:
kubernetesIngress:
publishedService:
enabled: true
priorityClassName: "system-cluster-critical"
# here
additionalArguments:
- "--entrypoints.web.forwardedHeaders.trustedIPs=0.0.0.0/0"
- "--entrypoints.websecure.forwardedHeaders.trustedIPs=0.0.0.0/0"
Finally, what I want to say
I have used the same method in Azure before, and at that time Traefik could obtain the source IP normally. However, in Google Cloud, this does not work.
I hope all you traefik masters can help me!!! THX