我的日志设置是单个 Docker 主机,为 syslog 公开了 UDP 514。nginx 容器已发布其端口,因此当您将日志发送到 10.1.1.100(如下图所示)时,它首先到达 nginx,其用于对 Logstash 容器进行透明负载平衡的配置为:
user root;
events {worker_connections 32768;}
stream {
upstream logstash_servers {
server logstash-collector-01:514;
server logstash-collector-02:514;
server logstash-collector-03:514;
}
listen 514 udp;
proxy_pass logstash_servers;
proxy_bind $remote_addr transparent;
}
}
这工作正常。但是,TCP 514(或任何 TCP)不工作。即使我添加了正确的侦听器和配置,我仍然认为 TCP 握手未完成,因为当 nginx 执行透明负载平衡时,其 proxy_bind 会将 10.1.1.5 作为源 IP 传递到 172.18.0.4(Logstash 实例)。然后该实例尝试完成握手,但 10.1.1.5(以及沿途的任何路由器)不知道如何路由到 172.18.0.0/16 的 Docker 网络。
这里是否有一个解决方案可以使用 TCP 进行日志记录?
答案1
听起来 nginx 可能不是这里最适合做这项工作的工具 - haproxy(如果您想要简单的 TCP/UDP 负载平衡)或 rsyslog(如果您想要一些更能感知应用程序的东西)似乎更适合,并且可以实现与 nginx 相同的功能。
查看您的设置,您甚至可以在 514 上有一个前端 logstash 侦听器,它可以转发到另一个 logstash 实例进行实际处理。据我所知,由于 logstash 不进行负载平衡,因此您可以根据您放置的某些标签/类型“路由”事件。
检查https://www.nginx.com/resources/admin-guide/tcp-load-balancing/,为了同时拥有 TCP 和 UDP,你需要类似以下内容:
stream {
upstream logstash_servers {
server logstash-collector-01:514;
server logstash-collector-02:514;
server logstash-collector-03:514;
}
server {
listen 514;
...
}
server {
listen 514 udp;
...
}
}
我不完全清楚在 UDP 服务器块中使用 logstash_servers 是否会导致 nginx 与它们使用 UDP 或 TCP,因此您可能需要同时提供这两种服务。
我有点怀疑问题是否归结于 nginx 节点在连接到 logstash 后端时使用了“错误”的 IP 作为源 - 通常,您的 nginx 前端将使用“正确”的 IP 来执行此操作,在您的情况下,这意味着 172.18/16 内的地址。这类似于反向代理到本地主机时使用 nginx 的方式:在这种情况下,nginx 将使用源 IP 127.0.0.1(或 ::1)与本地主机应用程序通信,而不是 nginx 看到请求来自的 IP。
而且还有一个事实是,你似乎在说这一切都适用于 UDP - 这往往表明路由本身不是问题,但你的 TCP 设置中可能存在问题。