【问题标题】:K8S with Traefik and HAP not getting real client IP on pods带有 Traefik 和 HAP 的 K8S 无法在 pod 上获取真实的客户端 IP
【发布时间】:2021-04-07 08:17:35
【问题描述】:

我有一个使用 HAProxy 的外部 LB,以便拥有一个 HA k8s 集群。我的集群在 Rancher 的 K3s 中,它在内部使用 Traefik LB。 我目前面临一个问题,在我的 pod 中,我获取的是 Traefik IP 而不是真实的客户端 IP。

HAP 配置:

# Ansible managed

defaults
  maxconn 1000
  mode http
  log global
  option dontlognull    
  log stdout local0 debug
  option httplog
  timeout http-request 5s
  timeout connect 5000
  timeout client 2000000
  timeout server 2000000

frontend k8s
  bind *:6443
  bind *:80
  bind *:443
  mode tcp
  option tcplog

  use_backend masters-k8s
    
backend masters-k8s
  mode tcp
  balance roundrobin

  server master01 master01.k8s.int.ntw
  server master02 master02.k8s.int.ntw
  
# end Ansible managed

Traefik 服务:

apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: traefik
    meta.helm.sh/release-namespace: kube-system
    service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"
  labels:
    app: traefik
    app.kubernetes.io/managed-by: Helm
    chart: traefik-1.81.0
    heritage: Helm
    release: traefik
spec:
  clusterIP: 10.43.250.142
  clusterIPs:
  - 10.43.250.142
  externalTrafficPolicy: Local
  ports:
  - name: http
    nodePort: 32232
    port: 80
    protocol: TCP
    targetPort: http
  - name: https
    nodePort: 30955
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app: traefik
    release: traefik
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 10.0.1.1
    - ip: 10.0.1.11
    - ip: 10.0.1.12
    - ip: 10.0.1.2

使用这种配置,我永远无法在 pod 上获得我的真实 IP,在一些研究中,我看到人们建议在 HAP 中使用 send-proxy,如下所示:

  server master01 master01.k8s.int.ntw check send-proxy-v2
  server master02 master02.k8s.int.ntw check send-proxy-v2

但是当我这样做时,我的所有集群通信都会返回 ERR_CONNECTION_CLOSED。 如果我没看错的话,这意味着它从 HAP 到集群,而集群在某处拒绝流量。

我在这里缺少什么线索吗?

谢谢

【问题讨论】:

    标签: kubernetes haproxy traefik high-availability k3s


    【解决方案1】:

    你有两个选择。

    1. 使用代理协议
    2. 使用 X-Forwarded-For 标头

    选项 1:代理协议

    此选项要求站点 HAProxy 和 Traefik 都使用代理协议,这就是人们推荐“send-proxy-v2”的原因。
    这还要求所有其他想要连接到 Traefik 的客户端必须也使用代理协议,如果客户端不使用代理协议,那么您将收到通信错误。
    当您在 TCP 模式下配置 HAProxy 时,这是将客户端 ip 获取到 Traefik 的唯一选项。

    选项 2:X-Forwarded-For

    我个人会使用此选项,因为它可以使用任何 http(s) 客户端连接到 traefik。
    这需要你在 haproxy 中使用 HTTP 模式和一些更多的参数,比如option forwardfor

    # Ansible managed
    
    defaults
      maxconn 1000
      mode http
      log global
      option dontlognull    
      log stdout local0 debug
      option httplog
      timeout http-request 5s
      timeout connect 5s
      timeout client 200s
      timeout server 200s
      # send client ip in the x-forwarded-for header
      option forwardfor
    
    frontend k8s
      bind *:6443 v4v6 alpn h2,http/1.1 ssl ca-file /etc/haproxy/letsencryptauthorityx3.pem crt /etc/ssl/haproxy/
      bind *:80   v4v6 alpn h2,http/1.1 ssl ca-file /etc/haproxy/letsencryptauthorityx3.pem crt /etc/ssl/haproxy/
      bind *:443  v4v6 alpn h2,http/1.1 ssl ca-file /etc/haproxy/letsencryptauthorityx3.pem crt /etc/ssl/haproxy/
    
      use_backend masters-k8s
    
    backend masters-k8s
    
      balance roundrobin
    
      server master01 master01.k8s.int.ntw check
      server master02 master02.k8s.int.ntw check
    
    # end Ansible managed
    

    文件“/etc/haproxy/letsencryptauthorityx3.pem”是后端的 CA,目录“/etc/ssl/haproxy/”是前端的证书。
    请查看有关 crt 关键字的文档。
    您还必须配置 traefik 以允许来自 haproxy forwarded-headers 的标头

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-16
      • 2020-10-01
      • 2013-08-18
      • 2012-08-04
      • 2020-05-22
      • 2017-03-24
      • 1970-01-01
      • 2013-04-16
      相关资源
      最近更新 更多