K3s and X-Forwarded-For Header in traefik 18.1

Hi there,

maybe someone here can help a noob to figure out on how to get the clients ip in X-Forwarded-For from a external http(s) request using traefik as the reverse proxy.

I found some interesting informations on the following site A Deep Dive into Kubernetes External Traffic Policies — Andrew Sy Kim, which enlightend me to use

externalTrafficPolicy: Local

what i did but this seems not to help in my case. I found many informations on the net but i lack of knowledge on how to interpret them.

What do i have:

  • k3s version v1.19.5+k3s2, with no special parameters

I have setup a test deployment with a python httpserver showing me the headers:

apiVersion: v1
kind: Namespace
metadata:
  name: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
  namespace: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: test
        image: fedora:latest
        command: [ "/bin/bash", "-c", "--" ]
        args: [ "dnf -y install iproute bind-utils iputils nmap procps;mkdir test;cd test;echo -e '' > index.html;echo -e '#!/usr/bin/env python3\nimport http.server as SimpleHTTPServer\nimport socketserver as SocketServer\nimport logging\nPORT = 80\nclass GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):\n    def do_GET(self):\n        logging.error(self.headers)\n        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)\nHandler = GetHandler\nhttpd = SocketServer.TCPServer((\"\", PORT), Handler)\nhttpd.serve_forever()\n' > test.py; chmod 755 test.py;python3 test.py; while true; do sleep 30; done;" ]
---
apiVersion: v1
kind: Service
metadata:
  name: test
  namespace: test
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/preserve-host: "true"
spec:
  type: NodePort
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: test
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test
  namespace: test
spec:
  rules:
  - host: hop.math.ethz.ch
    http:
      paths:
      - path: /
        backend:
          serviceName: test
          servicePort: 80

But every request comes in with the following headers:

User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Cookie: ORA_FPC=id=d389ee4b-32b9-44c3-ab59-ebf3236703e9
If-Modified-Since: Thu, 14 Jan 2021 09:49:43 GMT
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.42.1.1
X-Forwarded-Host: hop.math.ethz.ch
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-5dd496474-pcft9
X-Real-Ip: 10.42.1.1

Thank you for reading this!

Yours,
bbk

This is the thing:

  1. Using svclb never returns Client IP
  2. Embedded Flannel in k3s has - --ip-masq=true

But i don’t yet understand which solution will have what consequences in my setup…

seems like i will have to try them out.