问题

问题

问题

我最近创建了一个 docker 容器,它必须拉取一个公共的 github 存储库,但是它无法解析主机 github.com。事实上,它甚至无法执行 ping 命令。

注意:这里所有的网络操作都是在容器构建后,在容器运行时在容器内部进行的

ping www.google.com给出cannot resolve host

它根本无法连接到互联网。

在网上查找后Docker 文档

尝试的解决方案

1)按照以下说明启用 IP 转发Docker 文档

我尝试启用 IPForwarding,但无济于事。

/usr/lib/systemd/network/80-container-host0.network启用 IPForwarding 后的内容

...
[Network]
DHCP=yes
LinkLocalAddressing=yes
LLDP=yes
EmitLLDP=customer-bridge
IPForward=true // this line was changed
[DHCP]
UseTimezone=yes

2)按照以下方法重新创建 Docker Bridge堆栈溢出

pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
sudo service restart docker

这最初在这个问题

ubuntu 有解决方案,但是我的网络配置没有有问题的线

我的sudo pico /etc/NetworkManager/NetworkManager.conf只是充满了评论

[main]
#plugins=ifcfg-rh


[logging]
#level=TRACE
#domains=ALL

3)安装IP-Tables服务堆栈溢出

sudo yum install iptables-services
sudo service docker restart

4)覆盖docker-compose中的DNS配置堆栈溢出

version: "3.3"
services:
    airflow:
        build: 
            context: ./airflow
            dockerfile: Dockerfile
        ports: 
            - 8080:8080
        environment: 
            GITHUB_DAG_REPO: https://github.com/siddharths067/HelloAirflow.git
        dns:
            - 8.8.8.8
            - 8.8.4.4

Docker 网络检查镜像的网络

我不知道这是否有用

docker network inspect airflowsetup_default 
[
    {
        "Name": "airflowsetup_default",
        "Id": "141a518c1440e603f75774c54f42de33e9173e3f062a0a0bc772db13a7f1ef5d",
        "Created": "2020-08-30T14:42:30.951975699+05:30",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "airflowsetup",
            "com.docker.compose.version": "1.25.4"
        }
    }
]

输出

airflow_1  | GITHUB DAG REPO IS
airflow_1  | https://github.com/siddharths067/HelloAirflow.git
airflow_1  | Cloning into 'HelloAirflow'...
airflow_1  | fatal: unable to access 'https://github.com/siddharths067/HelloAirflow.git/': Could not resolve host: github.com

答案1

尽管 OP 找到了解决问题的办法并关闭了这个问题,但他并没有找到根本问题。Docker 的默认桥接网络bridge连接到互联网,而airflowsetup_default实际上却没有,这表明 Docker 网络设置存在问题。

我做了一些研究,结果发现 Fedora 32 并不真正关心 Docker 是否能在其上运行。

甚至无法按照文档中描述的方式安装 Docker,如果你安装 Fedora 提供的软件包,它仍然无法正常工作 - 有关该问题的更多信息可以找到这里这里这里

docker network create主要问题是,如果容器连接到任何自定义桥接网络(无论是使用还是通过 docker-compose创建),容器内部就没有互联网连接。

原因很简单——Docker 假设操作系统使用的防火墙是iptables,但 Fedora 32 使用防火墙默认情况下。这意味着 Docker 无法手动配置防火墙 - 必须手动配置。

为了参考目的,我将首先描述如何在干净的 Fedora 32 安装上设置 Docker。

首先运行以下命令:

sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"
sudo groupadd docker
sudo usermod -aG docker $USER

这将配置 cgroups 以与 Docker 守护程序兼容,并允许您的用户在没有 sudo 的情况下使用 Docker CLI。

接下来重新启动系统以应用更改并运行:

sudo dnf install -y moby-engine docker-compose nano
sudo systemctl enable docker
sudo systemctl start docker

安装并启用 Docker。

现在转到包含您的目录docker-compose.yml并运行docker-compose up -d。您应该会看到docker-compose为您创建网络,然后创建容器。如果您的容器在启动时需要互联网连接(如 OP 的),它将无法启动。

现在运行sudo iptables-save | grep DOCKER你应该会看到类似这样的内容:

:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o br-b56fa303f315 -j DOCKER
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-b56fa303f315 ! -o br-b56fa303f315 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-b56fa303f315 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-b56fa303f315 -j RETURN

docker0是 Docker 的默认桥接网络,而br-b56fa303f315是由 创建的新网络docker-compose(您的网络名称可能不同)。如果您的操作系统正在使用,则iptables一切都将按预期运行,但事实并非如此,因此我们需要检查docker0中的配置firewalld

运行firewall-cmd --get-active-zones后你会得到类似如下的结果:

docker
  interfaces: docker0
public
  interfaces: eth0 eth1

您可以看到bridge网络在docker区域中,但新网络不在。事实上,它根本没有列出,这意味着它位于默认区域中。您可以通过运行来检查它是什么firewall-cmd --get-default-zone。在全新安装的 Fedora 32 中,它是public

因此运行(记得替换br-b56fa303f315为您的接口名称):

sudo firewall-cmd --zone=docker --add-interface=br-b56fa303f315

docker-compose up -d如果您的服务之前启动失败,请运行,瞧——您的容器具有网络连接。

不幸的是,如果您重新启动系统,它将再次失去该连接。

您可以使用以下方法防止这种情况:

sudo firewall-cmd --permanent --zone=docker --add-interface=br-b56fa303f315
sudo firewall-cmd --reload

但是如果您创建任何新网络或重新创建现有网络(例如通过运行docker-compose down然后docker-compose up -d再次运行),则必须重复该过程。

那么这个问题的解决方案是什么呢?

首先,记下当前连接到默认区域的所有网络接口 - 在此示例中为eth0eth1

然后运行以下命令(替换public为默认区域的名称)

sudo firewall-cmd --set-default-zone=docker
sudo firewall-cmd --permanent --zone=public --add-interface=eth0
sudo firewall-cmd --permanent --zone=public --add-interface=eth1
sudo firewall-cmd --reload

现在,以前位于默认区域中的接口应该再次出现,但所有新接口(以及所有新的 Docker 网络)都将自动添加到docker区域中,这将为它们提供完整的网络连接。

答案2

我采用了另一种解决方案摘自 Fedora 杂志

防火墙中的白名单docker

为了让Docker 具有网络访问权,需要两个命令。

sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --permanent --zone=FedoraWorkstation
--add-masquerade

第一个命令将 Docker 接口添加到受信任环境,允许 Docker 进行远程连接。第二个命令将允许 Docker 进行本地连接。当多个 Docker 容器作为开发环境时,这特别有用。

然后你应该运行此命令来验证更改

sudo firewall-cmd --reload

通常情况下,您不需要重新启动计算机,您的下一个容器将会被连接。

如果此方法无效,您可以尝试:

  1. 首先,重启一个新容器
  2. 二、重启docker:sudo systemctl restart docker
  3. 最后,重新启动计算机

答案3

添加network-mode: bridge到我的docker-compose文件似乎有效。但我觉得这可能不是正确的做法。我不应该覆盖任何东西来允许我的容器连接。

version: "3.3"
services:
    airflow:
        build: 
            context: ./airflow
            dockerfile: Dockerfile
        ports: 
            - 8080:8080
        environment: 
            GITHUB_DAG_REPO: https://github.com/siddharths067/HelloAirflow.git
        # dns:
        #     - 8.8.8.8
        #     - 8.8.4.4
        network_mode: bridge

相关内容