问题
我最近创建了一个 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
再次运行),则必须重复该过程。
那么这个问题的解决方案是什么呢?
首先,记下当前连接到默认区域的所有网络接口 - 在此示例中为eth0
和eth1
。
然后运行以下命令(替换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
通常情况下,您不需要重新启动计算机,您的下一个容器将会被连接。
如果此方法无效,您可以尝试:
- 首先,重启一个新容器
- 二、重启docker:
sudo systemctl restart docker
- 最后,重新启动计算机
答案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