Docker 容器无法访问互联网

Docker 容器无法访问互联网

因此,我最近改用 Manjaro 作为我的塔和笔记本电脑的日常驱动程序。在这两个方面我都遇到了同样的问题:Docker 容器无法连接到互联网。我正在用 测试这个docker run --rm -it alpine ping 8.8.8.8。如果我使用该--net=host选项,那么整个命令看起来像docker run --rm --net=host -it alpine ping 8.8.8.8,容器就能够 ping 通。但如果我正确理解这个选项,容器将无法相互通信,而它们必须能够做到这一点。我的内核版本是5.2.21-1。

对于重要的远程可能性,两台计算机都位于 NAT 后面,并且位于根据设备的 MAC 地址进行过滤(并分配 IP)的网络中。

随着容器运行并尝试 ping 我的ip a输出(我清空了实际的 MAC),

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.173.136.22/16 brd 10.173.255.255 scope global dynamic noprefixroute wlp3s0
       valid_lft 83012sec preferred_lft 83012sec
    inet6 fe80::48d7:85d5:4c9d:4dd/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:8e:6f:31:71 brd ff:ff:ff:ff:ff:ff
    inet 172.31.0.1/16 brd 172.31.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:8eff:fe6f:3171/64 scope link 
       valid_lft forever preferred_lft forever
8: veth65af0a1@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether b2:40:b4:8c:6c:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::b040:b4ff:fe8c:6cf1/64 scope link 
       valid_lft forever preferred_lft forever

到目前为止我已经尝试过:

创建一个文件/etc/systemd/network/dockerForward.network如下这篇维基百科文章与内容

[Match]
Name=wlp3s0
[Network]
IPForward=true

看了一下networkctl因为本文。但由于输出是

$ networkctl
WARNING: systemd-networkd is not running, output will be incomplete.

IDX LINK             TYPE               OPERATIONAL      SETUP     
  1 lo               loopback           n/a              unmanaged 
  2 enp0s31f6        ether              n/a              unmanaged 
  3 wlp3s0           wlan               n/a              unmanaged 
  4 docker0          bridge             n/a              unmanaged 

我怀疑它不是罪魁祸首,因为它甚至没有运行。

此外,我还确保 IP 范围不重叠(如这条评论)。当我运行时$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 56fe5d704cd9它会给我 IP 172.31.0.2

为了更好地衡量,这是我的iptables -L输出:

$ iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
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            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere

我在这里有点不知所措,任何指向正确方向的指示将不胜感激。

编辑:

正如评论中提到的,这里是输出iptables-save -c

$ iptables-save -c
# Generated by iptables-save v1.8.3 on Fri Nov 15 10:11:51 2019
*filter
:INPUT ACCEPT [1299:403836]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [147:26907]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
[27:2268] -A FORWARD -j DOCKER-USER
[27:2268] -A FORWARD -j DOCKER-ISOLATION-STAGE-1
[0:0] -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o docker0 -j DOCKER
[27:2268] -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
[0:0] -A FORWARD -i docker0 -o docker0 -j ACCEPT
[27:2268] -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
[27:2268] -A DOCKER-ISOLATION-STAGE-1 -j RETURN
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
[27:2268] -A DOCKER-ISOLATION-STAGE-2 -j RETURN
[27:2268] -A DOCKER-USER -j RETURN
COMMIT
# Generated by iptables-save v1.8.3 on Fri Nov 15 10:11:51 2019
*nat
:PREROUTING ACCEPT [107:22651]
:INPUT ACCEPT [90:18175]
:OUTPUT ACCEPT [7:1549]
:POSTROUTING ACCEPT [7:1549]
:DOCKER - [0:0]
[6:2978] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[1:84] -A POSTROUTING -s 172.31.0.0/16 ! -o docker0 -j MASQUERADE
[0:0] -A DOCKER -i docker0 -j RETURN
COMMIT

评论中提到的更多输出:

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "53ce5b5c85f1ecd2e67118496f38141193398f5786c959305f0453ac15f96c63",
        "Created": "2019-11-16T12:36:27.244838753+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.31.0.1/16",
                    "Gateway": "172.31.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

$ docker run --rm -it alpine ip r
default via 172.31.0.1 dev eth0 
172.31.0.0/16 dev eth0 scope link  src 172.31.0.2

尝试回溯我运行的连接失败的具体位置

$ docker run -it --rm gophernet/traceroute 8.8.8.8   
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 46 byte packets
 1  172.31.0.1 (172.31.0.1)  0.005 ms  0.051 ms  0.016 ms
 2  xxx.xxx.xxx.1 (xxx.xxx.xxx.1)  15.092 ms  0.570 ms  0.656 ms
 3  *  *  *
 4  *  *  *
 [...]

xxx.xxx.xxx.136将是我的 NAT 的实际全局地址。

$ ip route                               
default via 10.173.1.1 dev wlp3s0 proto dhcp metric 600 
10.173.0.0/16 dev wlp3s0 proto kernel scope link src 10.173.136.22 metric 600 
172.31.0.0/16 dev docker0 proto kernel scope link src 172.31.0.1 linkdown 

相关内容