Debian 10(buster) + ufw + Docker: 处理Docker容器无法与外部通信的问题
突然处理方法
在update-alternatives –config iptables命令中,将iptables-legacy设置为默认选项。
$ sudo update-alternatives --config iptables
alternative iptables (/usr/sbin/iptables を提供) には 2 個の選択肢があります。
選択肢 パス 優先度 状態
------------------------------------------------------------
* 0 /usr/sbin/iptables-nft 20 自動モード
1 /usr/sbin/iptables-legacy 10 手動モード
2 /usr/sbin/iptables-nft 20 手動モード
現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 1
update-alternatives: /usr/sbin/iptables (iptables) を提供するためにマニュアルモードで /usr/sbin/iptables-legacy を使います
$ sudo reboot
突然下结论。 xià
-
- Debian 10はiptables v1.8系を採用.nftables APIを使うiptables-nftと旧来のiptables-legacyが用意されている.
-
- デフォルトはiptables-nftだが,Dockerはiptables-legacyを使う.
-
- この状態で,ufwなどを使ってiptables-nftで定義を設定すると,iptables-legacyの定義は無視される(ようだ).その結果,外部との通信ができない.
- そこで,iptables-legacyをデフォルトに変更し,定義をlegacy側に寄せて対処する.
详细解释
ufw和iptables
ufw(Uncomplicated Firewall)是一种简单易用的防火墙管理工具,只需编写ufw allow 22/tcp等命令即可实现端口开放。
在内部,它的定位类似于iptables(Netfilter)的包装器,可以让您忘记iptables易忘的命令体系。我认为它最初是为Ubuntu设计的工具,但是从很早以前开始也可以在Debian上使用。
iptables v1.8支持nftables API。
目前正在测试中的Debian GNU/Linux 10 (buster)中,iptables已从1.6版本升级到1.8版本。
- iptables 1.8.0 release [LWN.net]
在iptables 1.8中,新增了使用nftables Kernel API1的iptables-nft工具,旧有的工具可以使用iptables-legacy来进行操作。
iptables是Debian 10的默认设置,其中有一个指向iptables-nft的符号链接。ufw等使用这个默认设置。
$ ls -l /usr/sbin/iptables
lrwxrwxrwx 1 root root 26 2月 17 11:44 /usr/sbin/iptables -> /etc/alternatives/iptables
$ ls -l /etc/alternatives/iptables
lrwxrwxrwx 1 root root 22 2月 18 22:53 /etc/alternatives/iptables -> /usr/sbin/iptables-nft
Docker使用iptables-legacy。
一方面,Docker在处理iptables-nft时遇到了问题,因此不管默认设置如何,必须进行修正以始终使用iptables-legacy。
-
- Docker doesn’t work with iptables v1.8.1 · Issue #38099 · moby/moby
- debian has iptables-legacy and iptables-nft now by myobie · Pull Request #2285 · docker/libnetwork
ufw + Docker = 使用iptables-nft + iptables-legacy
在这种情况下,如果使用默认设置的ufw和Docker,会存在iptables-nft和iptables-legacy两个定义。
$ sudo iptables-nft -L
Chain INPUT (policy DROP)
target prot opt source destination
ufw-before-logging-input all -- anywhere anywhere
ufw-before-input all -- anywhere anywhere
ufw-after-input all -- anywhere anywhere
ufw-after-logging-input all -- anywhere anywhere
ufw-reject-input all -- anywhere anywhere
ufw-track-input all -- anywhere anywhere
(省略)
$ sudo iptables-legacy -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
(省略)
从这里开始,只能做出推测,但据推测,在这种情况下,只有 iptables-nft 的定义才会生效。因此,尽管 Docker 已经为我们更改了定义,但却无法生效,导致容器无法与外部通信。
当使用ping命令指定IP地址时可以正常通信,但当指定主机名时无法解析DNS的情况。
$ sudo docker run -it --rm busybox
/ # ping github.com
ping: bad address 'github.com'
/ # ping 192.30.255.112
PING 192.30.255.112 (192.30.255.112): 56 data bytes
64 bytes from 192.30.255.112: seq=0 ttl=49 time=133.961 ms
64 bytes from 192.30.255.112: seq=1 ttl=49 time=134.677 ms
处理方法:将iptables-legacy设置为默认选项。
嗯,关于解决方法,我们建议大家都使用iptables-legacy,包括ufw在内。
正如在 moby/moby的Issue评论中提到的那样,Docker 与 iptables v1.8.1 不兼容。因此,我们将把默认的 iptables 更改为 iptables-legacy。
$ sudo update-alternatives --config iptables
alternative iptables (/usr/sbin/iptables を提供) には 2 個の選択肢があります。
選択肢 パス 優先度 状態
------------------------------------------------------------
* 0 /usr/sbin/iptables-nft 20 自動モード
1 /usr/sbin/iptables-legacy 10 手動モード
2 /usr/sbin/iptables-nft 20 手動モード
現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 1
update-alternatives: /usr/sbin/iptables (iptables) を提供するためにマニュアルモードで /usr/sbin/iptables-legacy を使います
只需要重新启动就完成了。
即使iptables-nft定义仍然存在,但作为默认选择的是iptables-legacy,因此legacy将优先使用。
请参考
-
- Debian — buster の iptables パッケージに関する詳細
-
- iptables 1.8.0 release [LWN.net]
-
- Docker doesn’t work with iptables v1.8.1 · Issue #38099 · moby/moby
- debian has iptables-legacy and iptables-nft now by myobie · Pull Request #2285 · docker/libnetwork
原本iptables-nft应该可以使用相同的命令,但是出现了一些问题。在Pull request中可以看到类似于“翻译器可能有bug,没有完全跟进到位?”的评论。
关于nftables支持,早在很久以前就有相关的问题提出([feature request] nftables support · Issue #26824 · moby/moby)。