我正在使用 docker 和 iptables 运行多个安装。这些安装的目的之一是转发系统日志消息。我有时会遇到网络数据包停止到达容器的中断情况。在我当前的情况下,系统日志通过端口 514 发送到主机,主机应该将它们转发到容器。根据日志源,数据包通过 UDP 或 TCP 到达。目前,在一个安装中,UDP 数据包不会到达容器。
这是设置:
(1) 容器为 TCP+UDP 暴露端口 514:
/usr/bin/docker run --rm --detach \
-p 514:514/udp \
-p 514:514/tcp \
syslog-container \
${@}
(2)用netstat确认:
root@cc-01-m:~# netstat -plantu | grep 514
tcp 0 0 192.168.8.134:55228 10.68.8.70:514 ESTABLISHED 6844/rsyslogd
tcp6 0 0 :::514 :::* LISTEN 71629/docker-proxy
udp6 0 0 :::514 :::* 71644/docker-proxy
(3) IPTables FORWARD(过滤器)和 DOCKER(预路由)链:
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
285M 444G DOCKER-ISOLATION all -- * * 0.0.0.0/0 0.0.0.0/0
203M 225G DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
Chain PREROUTING (policy ACCEPT 8087 packets, 4046K bytes)
pkts bytes target prot opt in out source destination
1138M 904G DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
1 52 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:514 to:172.17.0.2:514
0 0 DNAT udp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:514 to:172.17.0.2:514
我对此的看法:
- TCP 和 UDP 的设置相同
- PREROUTING/DNAT 与 514/UDP 不匹配
- 下面有一个更新:我同时添加了端口 1514/UDP,它也正在工作......
(4) dmesg 中的结果:
但在 dmesg 中我看到:
工作示例(TCP,OUT=docker0)
[1220244.781877] [FW-ACCEPT] IN=ens192 OUT=docker0 MAC=00:50:56:9c:a0:21:00:09:0f:09:00:21:08:00 SRC=172.16.104.81 DST=172.17.0.2 LEN=2475 TOS=0x00 PREC=0x00 TTL=125 ID=10684 DF PROTO=TCP SPT=57211 DPT=514 WINDOW=8212 RES=0x00 ACK PSH URGP=0
不起作用的示例(UDP、OUT=,表示 INPUT 而不是 FORWARD):
[1219701.100893] [FW-ACCEPT] IN=ens192 OUT= MAC=00:50:56:9c:a0:21:00:09:0f:09:00:21:08:00 SRC=172.16.102.19 DST=192.168.8.134 LEN=793 TOS=0x00 PREC=0x00 TTL=62 ID=13050 DF PROTO=UDP SPT=35541 DPT=514 LEN=773
172.17.0.2是docker容器IP,192.168.8.134是主机IP。因此,尽管有匹配的 PREROUTING,但没有完成路由/转发,但它是匹配的不知何故输入。
(5) DOCKER过滤器链确认
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
1562K 2347M ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:514
0 0 ACCEPT udp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 udp dpt:514
这里没有 UDP 计数器,PREROUTING 失败。
(六,结论
我只能断定这是一个缺陷。
(7) 问题
有人能明白这一点吗?是否有进一步解决或缓解问题的步骤?
非常感谢你,安德烈亚斯
(八)更新
我为端口 1514/UDP 添加了类似的设置(无论如何都是需要的)。这才有效。我一无所知。会不会是负载问题?端口 514/UDP 上有大量流量。也许流量在 docker 接口出现之前就开始了,并且默认为输入,因为 PREROUTING(尚)不可能???有人吗?
当我尝试使用 TRACE 目标确定差异时,它看起来像这样:
(A) 工作示例(为了可读性而缩短,端口 1514):
[ 4760.393530] TRACE: raw:PREROUTING:policy:2 IN=ens192 OUT=
SRC=172.16.102.9 DST=192.168.8.134 ID=31601 PROTO=UDP SPT=63830 DPT=1514 LEN=472
[ 4760.393541] TRACE: filter:FORWARD:rule:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514
LEN=472
[ 4760.393546] TRACE: filter:DOCKER-ISOLATION:return:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514
LEN=472
[ 4760.393551] TRACE: filter:FORWARD:rule:2 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514
LEN=472
[ 4760.393556] TRACE: filter:DOCKER:rule:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514
LEN=472
(B) 不起作用的示例(为了可读性而缩短,端口 514):
[ 5122.397806] TRACE: raw:PREROUTING:policy:2 IN=ens192 OUT= SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451
[ 5122.397811] TRACE: filter:INPUT:rule:7 IN=ens192 OUT=
SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451
[ 5122.397822] TRACE: filter:OK:return:2 IN=ens192 OUT=
SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451
备注:我确实有一条记录并接受的链“OK”。