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.