从 18.04 升级到 Ubuntu 20.04-microk8s 本地 DNS 解析停止工作

从 18.04 升级到 Ubuntu 20.04-microk8s 本地 DNS 解析停止工作

我有一台从 Ubuntu 16.04 开始运行的服务器。我想让它更新到最新版本,所以我从 16.04 升级到了 18.04(基本没有问题)我让它运行了一天,以确保一切按预期运行,然后我升级到了 20.04。但这次升级并不顺利。

我已经解决了升级过程中的大部分问题(内核恐慌、MySQL 5.7 与 mariadb 不兼容等),但有一件事我无法弄清楚,为什么我的 UFW 规则在安装 kubernetes(microk8s)时表现不同。

我有几个 pod 在 microk8s 中运行。这些 pod 在 16.04 和 18.04 下运行良好。但是一旦我升级到 20.04,它们就无法访问我的 DNS 服务器(即在同一主机上运行的 dnsmasq)

我已将 microk8s 配置为转发到 192.168.0.50(我的主机主本地 IP 地址)。在升级到 20.04 之前,这同样运行良好。我需要 pod 能够访问此本地 DNS 服务器,因为我的网络上有只有此 DNS 服务器知道的特定服务。我已禁用内置的 systemd-resolver 以支持 dnsmasq。

还要注意,由于我运行自己的 Web 服务器、邮件服务器等,所以 192.168.0.50 暴露在公共互联网中(我的路由器的 DMZ 指向 192.168.0.50)。所以我希望 DNS 暴露给任何内部接口和/或 IP,但我不希望它暴露给来自互联网的公共 IP。

如果我检查 netstat,它看起来好像 dnsmasq 正在监听所有正确的接口:

# netstat -lepn | grep ":53 " | grep -v tcp6 | grep -v udp6
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      0          10627970   3213753/dnsmasq     
tcp        0      0 192.168.0.50:53         0.0.0.0:*               LISTEN      0          10627968   3213753/dnsmasq     
tcp        0      0 192.168.123.1:53        0.0.0.0:*               LISTEN      0          10627966   3213753/dnsmasq     
tcp        0      0 172.18.0.1:53           0.0.0.0:*               LISTEN      0          10627964   3213753/dnsmasq     
tcp        0      0 172.17.0.1:53           0.0.0.0:*               LISTEN      0          10627962   3213753/dnsmasq     
tcp        0      0 10.1.206.192:53         0.0.0.0:*               LISTEN      0          10627960   3213753/dnsmasq     
udp        0      0 127.0.0.1:53            0.0.0.0:*                           0          10627969   3213753/dnsmasq     
udp        0      0 192.168.0.50:53         0.0.0.0:*                           0          10627967   3213753/dnsmasq     
udp        0      0 192.168.123.1:53        0.0.0.0:*                           0          10627965   3213753/dnsmasq     
udp        0      0 172.18.0.1:53           0.0.0.0:*                           0          10627963   3213753/dnsmasq     
udp        0      0 172.17.0.1:53           0.0.0.0:*                           0          10627961   3213753/dnsmasq     
udp        0      0 10.1.206.192:53         0.0.0.0:*                           0          10627959   3213753/dnsmasq     

现在升级后,我发现 UFW 似乎阻止了来自 k8s 网络接口的 DNS 请求:

Apr 28 12:20:37 server kernel: [   58.148877] [UFW BLOCK] IN=cali00ea8fe43e0 OUT=enp1s0f0 MAC=ee:ee:ee:ee:ee:ee:fa:cd:4a:b9:17:d8:08:00 SRC=10.1.206.231 DST=10.1.206.232 LEN=86 TOS=0x00 PREC=0x00 TTL=63 ID=20903 DF PROTO=UDP SPT=49282 DPT=53 LEN=66
Apr 28 12:20:37 server kernel: [   58.148898] [UFW BLOCK] IN=cali00ea8fe43e0 OUT=enp1s0f0 MAC=ee:ee:ee:ee:ee:ee:fa:cd:4a:b9:17:d8:08:00 SRC=10.1.206.231 DST=10.1.206.232 LEN=86 TOS=0x00 PREC=0x00 TTL=63 ID=53947 DF PROTO=UDP SPT=45603 DPT=53 LEN=66

cali00ea8fe43e0我的 k8s 集群的一个网络接口在哪里。

如果我查看 microk8s core-dns 日志,我会看到如下行:

[ERROR] plugin/errors: 2 8297669929822044709.913121715873788735. HINFO: read udp 10.1.206.203:45629->192.168.0.50:53: i/o timeout

所以在我看来,UFW 确实阻止了此流量。唯一的问题是我无法弄清楚它停止工作的确切原因。我有/etc/ufw/user.rules文件的备份副本,升级似乎添加了以下几行:

### tuple ### allow any 30080 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 30080 -j ACCEPT
-A ufw-user-input -p udp --dport 30080 -j ACCEPT

### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 in_vxlan.calico
-A ufw-user-input -i vxlan.calico -j ACCEPT

### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 out_vxlan.calico
-A ufw-user-output -o vxlan.calico -j ACCEPT

### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 in_cali+
-A ufw-user-input -i cali+ -j ACCEPT

### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 out_cali+
-A ufw-user-output -o cali+ -j ACCEPT

我没有手动添加这些,它们是在升级过程中自动添加的。也许通过迁移到较新版本的 microk8s?这些新规则都以某种方式与我的 k8s 集群相关联。

这些行显示ufw status numbered如下:

# ufw status numbered
WARN: Duplicate profile 'Dovecot IMAP', using last found
WARN: Duplicate profile 'Dovecot Secure IMAP', using last found
WARN: Duplicate profile 'Dovecot POP3', using last found
WARN: Duplicate profile 'Dovecot Secure POP3', using last found
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 80                         ALLOW IN    Anywhere                  
[ 3] 6969                       ALLOW IN    Anywhere                  
[ 4] 9696                       ALLOW IN    Anywhere                  
[ 5] 110                        ALLOW IN    Anywhere                  
[ 6] 143                        ALLOW IN    Anywhere                  
[ 7] 25                         ALLOW IN    Anywhere                  
[ 8] 993                        ALLOW IN    Anywhere                  
[ 9] 995                        ALLOW IN    Anywhere                  
[10] 9300:9599/tcp              ALLOW IN    Anywhere                  
[11] Apache Full                ALLOW IN    Anywhere                  
[12] Anywhere                   ALLOW IN    192.168.0.0/16            
[13] 192.168.1.255 53           ALLOW IN    192.168.1.0 53            
[14] 127.0.1.1 53               ALLOW IN    127.0.0.1 53              
[15] 30080                      ALLOW IN    Anywhere                  
[16] Anywhere on vxlan.calico   ALLOW IN    Anywhere                  
[17] Anywhere                   ALLOW OUT   Anywhere on vxlan.calico   (out)
[18] Anywhere on cali+          ALLOW IN    Anywhere                  
[19] Anywhere                   ALLOW OUT   Anywhere on cali+          (out)

我假设这里发生的事情是 microk8s 网络发生了一些根本性的变化。我不记得以前有所有这些“calico”和“cali+”接口。因此,microk8s 必须在升级期间添加一些防火墙规则,以允许 pod 获得出站 Internet 访问权限……但看起来规则可能不允许 pod 访问我的主机服务器上的“任何地方”。

IE:如果我没有看错的话:第 16 行允许任何发往“vxlan.calico 上的任何地方”的流量进入,第 17 行允许从 vxlan.calico 上的任何地方出站到“任何地方”

但是这两者似乎都不允许来自 vxlan.calico 的流量进入?(在我看来应该允许)。

我一直在尝试弄清楚如何修改该行以user.rules允许来自 vxlan.calico 和 cali+ 接口的任何/所有流量,但我没有找到正确的语法来做到这一点。我想我可以允许来自 10.0.0.0/8 的所有流量,因为这似乎是所有这些接口使用的 CIDR,但我不确定这是否是“正确”的方法。

总结一下:

主要问题 #1:有没有办法允许流量从特定接口进入任何端口。例如:我想添加一行显示在 UFW 状态中的内容,例如:

     To                         Action      From
     --                         ------      ----
[20] Anywhere                   ALLOW **IN**   Anywhere on vxlan.calico

基本与规则 17 相同,只是“行动”是允许进入而不是允许

主要问题 #2:我是否忽略了其他一些基本问题?似乎从 18.04 升级到 20.04 不应该造成这么大的麻烦。我是否错过了某个基本步骤?

编辑#1:所以也许根本就不是 UFW 的问题...我刚刚完全禁用了 UFW,但仍然看到此流量被阻止。这是在 microk8s 本身内阻止的吗?

我完全不知所措了。我错过了什么?

我检查了一下,我可以从我的 k8s pod 顺利连接到主机服务器 (192.168.0.50) 上的其他端口。只有对端口 53 的请求被挂断了。

例如:curl -v http://192.168.0.50在其中一个 k8s pod 上运行就可以从我的 web 服务器正常返回内容。

所以我的下一个想法是,这也许是 UDP 特定的问题,但尝试使用 TCP 进行 DNS 也不起作用:

$ kubectl exec -i -t dnsutils -- dig cnn.com @192.168.0.50 +tcp
;; communications error to 192.168.0.50#53: connection reset

但是从主机使用 +tcp 的相同 dig 命令返回的结果与预期完全一致。

我还使用 tcpdump 进行了检查:tcpdump -i any -XX port 53 当我从其中一个 k8s pod 调用 dig 时,我在 tcpdump 输出中看到了请求,但没有响应:

14:55:09.849245 IP 10.1.206.251.53235 > 192.168.0.50.domain: 27889+ [1au] A? cnn.com. (36)

当我从本地网络上的另一台机器执行相同的 dig 命令时,我看到请求响应:

14:56:45.430750 IP 192.168.0.233.36836 > 192.168.0.50.domain: 43090+ [1au] A? cnn.com. (48)
14:56:45.447998 IP 192.168.0.50.domain > 192.168.0.233.36836: 43090 4/0/1 A 151.101.131.5, A 151.101.195.5, A 151.101.3.5, A 151.101.67.5 (100)

因此,我启用了 dnsmasq 中的日志记录,当我从服务器本身或网络上的其他机器发出 dns 请求时,它会记录条目,但当我从 k8s pod 发出请求时,它根本不会记录任何内容。

因此,tcpdump可以看到来自 k8s pod 的 DNS 请求数据包,但dnsmasq似乎没有收到它?这怎么可能呢?


编辑添加:嗯,这可能是我需要的线索:

# grep "ignoring query from non-local network" /var/log/syslog
Apr 29 07:59:25 server dnsmasq[1540970]: ignoring query from non-local network 10.1.206.240
Apr 29 07:59:30 server dnsmasq[1541198]: ignoring query from non-local network 10.1.206.240
Apr 29 12:43:20 server dnsmasq[2803264]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 13:56:41 server dnsmasq[3122204]: ignoring query from non-local network 10.1.206.240
Apr 29 14:04:56 server dnsmasq[3157857]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 14:40:45 server dnsmasq[3313551]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 14:51:24 server dnsmasq[3360405]: ignoring query from non-local network 10.1.206.251
Apr 29 14:52:09 server dnsmasq[3363587]: ignoring query from non-local network 10.1.206.251
Apr 29 15:47:35 server dnsmasq[3603248]: ignoring query from non-local network 10.1.206.203 (logged only once)

因为这些“仅记录一次”所以我没有看到它们......

答案1

回答我自己的问题:它与 UFW 或 microk8s 无关,而与升级到 20.04 添加新的默认标志有关/etc/init.d/dnsmasq

DNSMASQ_OPTS="$DNSMASQ_OPTS --local-service"

--local-service从此文件中删除即可修复该问题。

我简直不敢相信我花了多少时间来追踪这个问题。我想知道这是否是一个错误,因为 10.0.0.0/8 CIDR 在技术上被视为私有/本地 IP 范围,因此我不确定 dnsmasq 如何/为何得出结论认为这些特定 IP 是“非本地的”,而实际上它们非常本地。

相关内容