how to get the real ip adress in kubernetes cluster pod when using traefik 2.2

Viewed 279

My app was deployed in kubernetes cluster, the forward relatation like this:

internet user ---> nginx(docker) ----> traefik----> pod

now I want to get the user real ip address, this is my nginx forward config:

server{
    listen 443 ssl;

    ssl_certificate /etc/nginx/conf.d/cert/example.com/fullchain1.pem;
    ssl_certificate_key /etc/nginx/conf.d/cert/example.com/privkey1.pem;

    server_name api.example.com;

    location / {
        client_max_body_size 50m;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 3600;
        proxy_pass http://k8s-edge-node;
    }
}

and this is my traefik config:

{
  "kind": "DaemonSet",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "traefik-ingress-controller",
    "namespace": "kube-system",
    "labels": {
      "app": "traefik"
    }
  },
  "spec": {
    "selector": {
      "matchLabels": {
        "app": "traefik"
      }
    },
    "template": {
      "metadata": {
        "name": "traefik",
        "creationTimestamp": null,
        "labels": {
          "app": "traefik"
        },
        "annotations": {
          "kubectl.kubernetes.io/restartedAt": "2021-06-03T19:34:06+08:00"
        }
      },
      "spec": {
        "volumes": [
          {
            "name": "config",
            "configMap": {
              "name": "traefik-config",
              "defaultMode": 420
            }
          }
        ],
        "containers": [
          {
            "name": "traefik-ingress-lb",
            "image": "traefik:2.2.1",
            "args": [
              "--configFile=/config/traefik.yaml",
              "--logLevel=INFO",
              "--metrics=true",
              "--metrics.prometheus=true",
              "--entryPoints.metrics.address=:8080",
              "--metrics.prometheus.entryPoint=metrics",
              "--metrics.prometheus.addServicesLabels=true",
              "--metrics.prometheus.addEntryPointsLabels=true",
              "--metrics.prometheus.buckets=0.100000, 0.300000, 1.200000, 5.000000",
              "--entryPoints.web.address=:80",
              "--entryPoints.websecure.address=:443",
              "--entryPoints.mysql.address=:3308",
              "--entryPoints.tcpep.address=:3179",
              "--entryPoints.streaming.address=:1704",
              "--certificatesResolvers.ali.acme.email=jiangtingqiang@gmail.com",
              "--certificatesResolvers.ali.acme.storage=/config/acme.json",
              "--certificatesResolvers.ali.acme.httpChallenge.entryPoint=web",
              "--certificatesResolvers.ali.acme.httpChallenge=true",
              "--certificatesresolvers.ali.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory",
              "--accesslog=true",
              "--accesslog.filepath=/home/access.log",
              "--accesslog.bufferingsize=100"
            ],
            "ports": [
              {
                "name": "web",
                "hostPort": 80,
                "containerPort": 80,
                "protocol": "TCP"
              },
              {
                "name": "websecure",
                "hostPort": 443,
                "containerPort": 443,
                "protocol": "TCP"
              },
              {
                "name": "mysql",
                "hostPort": 3308,
                "containerPort": 3308,
                "protocol": "TCP"
              },
              {
                "name": "hadesmysql",
                "hostPort": 3311,
                "containerPort": 3311,
                "protocol": "TCP"
              },
              {
                "name": "tcpep",
                "hostPort": 3179,
                "containerPort": 3179,
                "protocol": "TCP"
              },
              {
                "name": "metrics",
                "hostPort": 8080,
                "containerPort": 8080,
                "protocol": "TCP"
              }
            ],
            "envFrom": [
              {
                "secretRef": {
                  "name": "traefik-alidns-secret"
                }
              }
            ],
            "resources": {
              "limits": {
                "cpu": "2",
                "memory": "1Gi"
              },
              "requests": {
                "cpu": "1",
                "memory": "1Gi"
              }
            },
            "volumeMounts": [
              {
                "name": "config",
                "mountPath": "/config"
              }
            ],
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "imagePullPolicy": "IfNotPresent",
            "securityContext": {
              "capabilities": {
                "add": [
                  "NET_BIND_SERVICE"
                ],
                "drop": [
                  "ALL"
                ]
              }
            }
          }
        ],
        "restartPolicy": "Always",
        "terminationGracePeriodSeconds": 1,
        "dnsPolicy": "ClusterFirst",
        "nodeSelector": {
          "app-type": "online-app"
        },
        "serviceAccountName": "traefik-ingress-controller",
        "serviceAccount": "traefik-ingress-controller",
        "hostNetwork": true,
        "securityContext": {},
        "schedulerName": "default-scheduler",
        "tolerations": [
          {
            "operator": "Exists"
          }
        ]
      }
    },
    "updateStrategy": {
      "type": "RollingUpdate",
      "rollingUpdate": {
        "maxUnavailable": 1
      }
    },
    "templateGeneration": 68,
    "revisionHistoryLimit": 10
  },
  "status": {
    "currentNumberScheduled": 1,
    "numberMisscheduled": 0,
    "desiredNumberScheduled": 1,
    "numberReady": 1,
    "observedGeneration": 68,
    "updatedNumberScheduled": 1,
    "numberAvailable": 1
  }
}

then I get the ip address in pod using java code like this:

httpServletRequest.getHeader("x-real-ip") //172.19.104.231
httpServletRequest.getHeader("x-forwarded-for") // 172.19.104.231, 172.30.208.1

but the ip address was the kubernetes host ip address, not the internet user real ip address, what should I do to get the user real ip address? I am output the variable proxy_add_x_forwarded_for in the nginx log and found that the nginx get the client real ip success. I also tried to add this configuration by document here:

--entryPoints.web.forwardedHeaders.insecure

I also tried to add this config from this issue:

        --entryPoints.web.forwardedHeaders.trustedIPs=172.19.104.0/16

172.19.104.0/16 was the host ip. still did not fix this problem. I also checked the traefik pod network are host mode by reading this doc.

0 Answers
Related