无法从X-Forwarded-For获取真实用户的IP

时间:2018-10-16 17:49:42

标签: traefik

我正在单节点Kubernetes集群上运行Traefik 1.7.3,我试图从X-Forwarded-For标头中获取真实的用户IP,但是我得到的是X-Forwarded-For: 10.244.0.1,它是我的k8s群集中的IP。

这是我的Traefik部署和服务:

    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: traefik-conf
    data:
      traefik.toml: |
        # traefik.toml
        debug = true
        logLevel = "DEBUG"
        defaultEntryPoints = ["http","https"]
        [entryPoints]
          [entryPoints.http]
          address = ":80"
          compress = true
          [entryPoints.http.forwardedHeaders]
          trustedIPs = [ "0.0.0.0/0" ]
          entryPoint = "https"
          [entryPoints.https]
          address = ":443"
          compress = true
          [entryPoints.https.forwardedHeaders]
          trustedIPs = [ "0.0.0.0/0" ]
          [entryPoints.https.tls]

        [acme]
        email = "xxxx"
        storage = "/acme/acme.json"
        entryPoint = "https"
        onHostRule = true
        #caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
        acmeLogging = true
        [[acme.domains]]
        main = "xxxx"
        [acme.dnsChallenge]
        provider = "route53"
        delayBeforeCheck = 0

        [persistence]
        enabled = true
        existingClaim = "pvc0"
        annotations = {}
        accessMode = "ReadWriteOnce"
        size = "1Gi"

        [kubernetes]
        namespaces = ["default"]
        [accessLog]
        filePath = "/acme/access.log"
        [accessLog.fields]
        defaultMode = "keep"
    ---
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: traefik-ingress-controller
      namespace: default
      labels:
        k8s-app: traefik-ingress-lb
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: traefik-ingress-lb
      template:
        metadata:
          labels:
            k8s-app: traefik-ingress-lb
            name: traefik-ingress-lb
        spec:
          serviceAccountName: traefik-ingress-controller
          terminationGracePeriodSeconds: 60
          containers:
          - image: traefik
            name: traefik-ingress-lb
            env:
              - name: AWS_ACCESS_KEY_ID
                value: xxxx
              - name: AWS_SECRET_ACCESS_KEY
                value: xxxx
              - name: AWS_REGION
                value: us-west-2
              - name: AWS_HOSTED_ZONE_ID
                value: xxxx
            ports:
            - name: http
              containerPort: 80
            - name: admin
              containerPort: 8080
            args:
            - --api
            - --kubernetes
            - --configfile=/config/traefik.toml
            volumeMounts:
            - mountPath: /config
              name: config
            - mountPath: /acme
              name: acme
          volumes:
          - name: config
            configMap:
              name: traefik-conf
          - name: acme
            persistentVolumeClaim:
              claimName: "pvc0"
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: traefik-ingress-service
      namespace: default
    spec:
      externalIPs:
      - x.x.x.x
      externalTrafficPolicy: Local
      selector:
        k8s-app: traefik-ingress-lb
      ports:
        - protocol: TCP
          port: 80
          name: web
        - protocol: TCP
          port: 443
          name: https
        - protocol: TCP
          port: 8080
          name: admin
      type: NodePort

这是我的入口:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: headers-test
      namespace: default
      annotations:
        ingress.kubernetes.io/proxy-body-size: 500m
        kubernetes.io/ingress.class: traefik
    spec:
      rules:
      - host: xxxx
        http:
          paths:
          - path: /
            backend:
              serviceName: headers-test
              servicePort: 8080

我读到我只需要添加[entryPoints.http.forwardedHeaders]和一个trustedIPs的列表,但这似乎不起作用。我想念什么吗?

1 个答案:

答案 0 :(得分:0)

如果将NodePort用于Traefik Ingress服务,则必须将service.spec.externalTrafficPolicy设置为“本地”。否则,当您的连接进入K8s集群时,您将拥有SNAT。如果传入连接不在同一节点上运行,则必须使用此SNAT将传入连接转发到您的Pod。

但是请注意,将service.spec.externalTrafficPolicy设置为“ Local”,只有执行Traefik Pod的节点会接受80、443、8080上的请求。没有从其他节点转发到Pod的请求。不再。连接到服务时,这可能会导致奇怪的延迟。为了避免这种情况,您的Traefik将需要在HA设置(DaemonSet)中运行。请记住,您需要K / V-Store来进行分布式Traefik设置,以使Letsencrypt正常工作。

如果service.spec.externalTrafficPolicy设置仍无法解决您的问题,则可能还需要将kubernetes覆盖网络配置为不执行任何SNAT。

service.spec.externalTrafficPolicy在这里得到了很好的解释: https://kubernetes.io/docs/tutorials/services/source-ip/