DNS 无法通过 pod 的 TCP 工作

DNS does not work over TCP from pod

我有一个 Openshift Origin 安装(1.2.1 版,但也在 1.3.0 上重现了这个问题),我正在尝试通过服务名称从 DNS 获取 pods' IP。假设我的节点有 IP 192.168.58.6,我在项目 'hz-test' 中寻找无头服务 'hz' 的 pods。当我尝试通过 UDP 将 DNS 请求发送到 dnsmasq(安装在节点上并将请求转发到 Kubernetes 的 SkyDNS)时,一切顺利:

# dig +notcp +noall +answer hz.hz-test.svc.cluster.local @192.168.58.6  
hz.hz-test.svc.cluster.local. 14 IN A   10.1.2.5
<and so on...>

但是,当我将传输协议切换为 TCP 时,我收到以下错误:

# dig +tcp +noall +answer hz.hz-test.svc.cluster.local @192.168.58.6  
;; communications error to 192.168.58.6#53: end of file

查看 tcpdump 输出后,我发现,在建立 TCP 连接(SYN - SYN/ACK - ACK)后,dnsmasq 立即发回 FIN/ACK,当 DNS 客户端尝试使用此连接发送请求,dnsmasq 发回 RST 数据包而不是 DNS 应答。我尝试从节点本身通过 TCP 执行相同的 DNS 查询,dnsmasq 给了我通常的响应,即它在 TCP 上正常工作,只有当我尝试从 pod 执行请求时才会出现问题。此外,我尝试通过 TCP 将相同的查询直接从 pod 发送到 Kubernetes 的 DNS(避免使用 dnsmasq),这个查询也可以。

那么,为什么节点上的 dnsmasq 会忽略来自 pods 的 TCP 请求,以及为什么其他通信都可以?这是应该的行为吗?

感谢任何帮助和想法。

最后,原因是dnsmasq被配置为监听节点的IP(listen-adress=192.168.58.6)。通过这样的配置,dnsmasq 绑定到 all 节点的网络接口,但会尝试拒绝用户空间中的 "wrong" 连接(即它自己)。

我真的不明白,为什么 dnsmasq 决定使用这种配置禁止从 pod 到 192.168.58.6 的请求,但我通过将 "listen-address" 更改为

来让它工作
interface=eth0
bind-interfaces

这迫使 dnsmasq 实际上只绑定到 IP 为 192.168.58.6 的 NIC。之后 dnsmasq 开始接受所有 TCP 请求。