Sid*_*ngh 4 networking linux wireless-networking docker docker-compose
我最近创建了一个必须拉出公共 github 存储库的 docker 容器,但是,它无法解析主机 github.com。事实上,它甚至无法执行 ping 命令。
注意:这里的所有网络操作都在构建后的容器内,当容器运行时
ping www.google.com
给 cannot resolve host
它根本无法连接到互联网。
在查看互联网和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
Run Code Online (Sandbox Code Playgroud)
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
sudo service restart docker
Run Code Online (Sandbox Code Playgroud)
这个本来对这个问题有效
ubuntu 有一个解决方案,但是我的网络配置没有那个有问题的线路
我sudo pico /etc/NetworkManager/NetworkManager.conf
的只是充满了评论
[main]
#plugins=ifcfg-rh
[logging]
#level=TRACE
#domains=ALL
Run Code Online (Sandbox Code Playgroud)
sudo yum install iptables-services
sudo service docker restart
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
不知道这个有没有用
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"
}
}
]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
事件虽然 OP 找到了解决他的问题的方法并关闭了这个问题,但他没有找到根本问题。Docker 的默认桥接网络bridge
连接到 Internet的事实airflowsetup_default
并不表明 Docker 网络设置有问题。
我做了一些研究,结果 Fedora 32 决定它并不真正关心 Docker 是否在它上面工作。
甚至无法以文档中描述的方式安装 Docker,如果您安装 Fedora 提供的软件包,它仍然无法正常工作 - 有关该问题的更多信息可以在此处、此处和此处找到。
主要问题是,如果容器连接到任何自定义桥接网络,则容器内部没有 Internet 连接——无论它是使用docker network create
docker-compose创建的还是由 docker-compose创建的。
原因很简单——Docker 假设操作系统使用的防火墙是iptables,但 Fedora 32默认使用firewalld。这意味着 Docker 不能手动配置防火墙——它必须手动配置。
出于参考目的,我将首先描述如何在干净的 Fedora 32 安装上设置 Docker。
首先运行以下命令:
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"
sudo groupadd docker
sudo usermod -aG docker $USER
Run Code Online (Sandbox Code Playgroud)
这将配置 cgroups 以与 Docker 守护程序兼容,并允许您的用户在没有 sudo 的情况下使用 Docker CLI。
接下来重新启动系统以应用更改并运行:
sudo dnf install -y moby-engine docker-compose nano
sudo systemctl enable docker
sudo systemctl start docker
Run Code Online (Sandbox Code Playgroud)
安装和启用 Docker。
现在转到包含您的目录docker-compose.yml
并运行docker-compose up -d
. Yuo 应该会看到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
Run Code Online (Sandbox Code Playgroud)
docker0
是 Docker 的默认桥接网络,而br-b56fa303f315
是由docker-compose
(您的名称可能不同)创建的新网络。如果您的操作系统正在使用iptables
一切都会按预期工作,但事实并非如此,因此我们需要检查docker0
in的配置firewalld
。
运行firewall-cmd --get-active-zones
,你会得到类似的东西:
docker
interfaces: docker0
public
interfaces: eth0 eth1
Run Code Online (Sandbox Code Playgroud)
您可以看到bridge
网络在docker
区域中,但新网络不在。实际上它根本没有列出,这意味着它在默认区域中。您可以通过运行来检查那是什么firewall-cmd --get-default-zone
。在 Fedora 32 的全新安装中,它是public
.
所以运行(记得br-b56fa303f315
用你的接口名称替换):
sudo firewall-cmd --zone=docker --add-interface=br-b56fa303f315
Run Code Online (Sandbox Code Playgroud)
docker-compose up -d
如果您的服务之前未能启动,则运行,瞧 - 您的容器具有网络连接。
不幸的是,如果您重新启动系统,它将再次失去连接。
您可以使用以下方法防止这种情况:
sudo firewall-cmd --permanent --zone=docker --add-interface=br-b56fa303f315
sudo firewall-cmd --reload
Run Code Online (Sandbox Code Playgroud)
但是,如果您创建任何新网络或重新创建现有网络(例如通过运行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
Run Code Online (Sandbox Code Playgroud)
现在,之前在默认区域中的接口应该会再次出现,但是所有新接口(以及所有新的 Docker 网络)都将自动添加到docker
区域,这将为它们提供完整的网络连接。