HAProxy Docker 容器执行 L4 负载平衡不透明

HAProxy Docker 容器执行 L4 负载平衡不透明

使用官方最新的HAProxy Docker容器和以下配置文件:

frontend logging_frontend
    bind *:1514
    mode tcp
    timeout client 1m
    default_backend logging_backend

backend logging_backend
    mode tcp
    balance roundrobin
    timeout connect 10s
    timeout server 1m
    server logstash-collector-01 logstash-collector-01:1514 check
    server logstash-collector-02 logstash-collector-02:1514 check
    server logstash-collector-03 logstash-collector-03:1514 check

我收到的日志(通过 nxlog 通过 TCP 发送到 1514)并未存储实际的客户端 IP,而是存储了 Docker 网关 IP。例如:

2017-03-02T15:57:41.585Z 172.18.0.1 {“EventTime”:“2017-03-01 15:25:02”,“Hostname”:“server.mycompany.net”,“关键字”:58096435992,“EventType”:“错误”,“SeverityValue”:“4”,“Severity”:“错误”,“EventID”:551,“SourceName”:“Microsoft-Windows-SMBServer”,“ProviderGuid”:“{D48CE617-33A2-4BC3-A5C7-11AA4F29619E}”,“版本”:1,“任务”:551,“OpcodeValue”:0,“RecordNumber”:5267740,“ProcessID”:4,“ThreadID”:5732,“Channel”:“Microsoft-Windows-SMBServer / Security”,“Domain”:“NT AUTHORITY","AccountName":"SYSTEM","UserID":"S-1-5-184","AccountType":"User","Message":"SMB 会话身份验证失败\r\n\r\n客户端名称:\\10.1.1.43\r\n客户端地址:10.1.1.43:54118\r\n用户名:\r\n会话 ID:0xAF9FC8000015\r\n状态:尝试登录无效。这是由于用户名或身份验证信息错误造成的。(0xC000006D)\r\n\r\n指导:\r\n\r\n当尝试使用不正确的凭据连接到共享时,您应该会遇到此错误。\r\n\r\n此错误并不总是表示授权问题,而主要是身份验证问题。这种情况在非 Windows 客户端上更为常见。\r\n\r\n当使用不正确的 NTLM 用户名和密码、客户端和服务器之间的 LmCompatibility 设置不匹配、Kerberos 服务主体名称重复、Kerberos 票证授予服务票证不正确或未启用来宾访问权限的来宾帐户时,可能会发生此错误","Opcode":"Info","EventReceivedTime":1488470262,"SourceModuleName":"eventlog","SourceModuleType":"im_msvistalog"}

请注意,报告服务器是 10.2.3.95,Docker 主机是 10.1.38.223,Docker 桥接接口(和本地容器子网)是 172.18.0.0/16(日志中记录的 172.18.0.1 是网关)。

从 tcpdump(已修改以显示接口): tcpdump

  1. 外部接口 eno16777728 从 10.2.3.95 获取到主机 IP 10.1.38.223 的 PUSH 数据包(包含日志数据)
  2. Docker 将对其进行 DNAT,从 10.2.3.95 转至 HAProxy 容器 (172.18.0.6)
  3. HAProxy 确认了 PUSH(屏幕截图的最后一个数据包显示使用 10.xxx IP 在外部接口上进行了 SNAT 回复)
  4. (图像乱序 - 检查时间戳)HAProxy 决定将后端容器 172.18.0.3 作为负载平衡目标
  5. (图像乱序 - 检查时间戳)Docker 接口网关在其虚拟以太网接口上对数据包进行 SNAT(为什么?)
  6. 后端服务器向 Docker 网关发送 ACK
  7. 从后端服务器到 HAProxy 的 ACK(?)
  8. 从后端服务器到 HAProxy 的 ACK(?)

source 0.0.0.0 usesrc clientip当我尝试使用节中的功能让 HAProxy 透明地传递客户端 IP 时backend,根本没有记录任何内容。

对我来说,这个问题有两个成功途径:要么:

  • 记录Docker网关IP的行为该如何解释?

或者更重要的是:

  • 我怎样才能让原始客户端 IP 出现在这些日志中,最好作为客户端 IP 字段(在日志开头的时间戳之后)?

相关内容