This page looks best with JavaScript enabled

最近使用 Docker Compose 时遇到的一些问题及解决(网络相关)

 ·  ☕ 3 min read  ·  ✍️ 鱼子盖饭 · 👀... views

昨天晚上在电脑上配置 Nextcloud,用的官方的 docker-compose.yml,遇到了如下几个问题

Docker pull 镜像时速度慢甚至卡住

最开始是通过创建 /etc/systemd/system/docker.service.d/http-proxy.conf 文件的方式为 Docker 提供 http 代理,但在需要 pull 多个镜像时,总是会有个镜像下载到一半就不动了,而且不是特定的镜像,因为每次重新 pull 卡住的镜像都不同,很纳闷。。

通过使用镜像加速器的方式解决了这个问题:

我用的是阿里云的镜像加速,需要登录阿里云账号,然后在“容器镜像服务”的“镜像加速器”中获取镜像加速地址

修改 daemon 配置文件 /etc/docker/daemon.json 来使用加速器

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["镜像加速地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

用过清华的镜像加速,效果不理想,阿里云的 pull 起来就飞快了~

另外,如果 pull 阶段出错,导致后面每次执行 docker-compose up -d 都报错,删除已创建的容器和拉取的镜像即可,也可以用如下命令清空容器、镜像、网络等:

1
sudo rm -rf /var/lib/docker

Failed to add the host

问题出现在 Docker Compose 启动容器的时候,出现如下错误:

1
2
3
Error response from daemon: Cannot start container xxx:
failed to create endpoint xxx on network xxx:
failed to add the host (veth7f6f907) <=> sandbox (veth788d9dc) pair interfaces: operation not supported

查了关于这个报错的很多资料,但错误原因不太一样。。

还用 sudo ip link add vetha type veth peer name vethb 手动去连接这两个网络。。

最后偶然间在 这里 找到了答案:

QQ截图20200410145104.jpg

同是 Archlinux,更新内核之后会将内核旧的模块删除,而 Docker 仍然会使用旧模块创建接口,需要重启系统使用新的模块

想起我平时都是开机首先就 pacman -Syu 一把,于是

1
2
reboot
docker-compose up -d

ok 了。。。

然后我又去 Archlinux 官网看了看更新日志

QQ截图20200410152043.jpg

应该就是在我今天的更新中对内核模块进行了更新。。

Host is unreachable

这个错误出现在访问服务的时候(今天真的是拉取、创建、使用的一条龙错误服务。。。),Nginx 502 错误,用 docker logs 看了下:

1
2
2020/04/09 15:09:20 [error] 7#7: *1 connect() failed (113: Host is unreachable) while connecting to upstream, client: 172.20.0.1, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://172.20.0.5:9000", host: "127.0.0.1:8080"
172.20.0.1 - - [09/Apr/2020:15:09:20 +0000] "GET / HTTP/1.1" 502 157 "-" "curl/7.69.1" "-"

这个错误不在 Nginx,也不是 Docker Compose 的配置问题,毕竟是官方的配置和镜像,即使有问题也能及时解决,原因在于防火墙!

关闭防火墙之后,容器间的通信就正常了。。

由于我只开了必需的端口,因此出错后也尝试过打开 9000 端口。不过我用的是 Firewalld,默认是添加端口到 public zone,所以还需要将 Docker 的网络添加进去:

首先获取 Docker 的 IP

1
2
3
4
5
$ ip addr show docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:6e:f0:a0:82 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

其次是 Nextcloud 使用的 nextcloud_default 的子网 IP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ docker inspect `docker network ls | grep nextcloud_default | awk '{print $1}'`
...
"IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
...

将他俩添加到 Firewalld 中即可:

1
2
3
sudo firewall-cmd --zone=trusted --add-source=172.17.0.1/16 --permanent
sudo firewall-cmd --zone=trusted --add-source=172.20.0.0/16 --permanent
sudo firewall-cmd --reload

结语

Docker 不是给人快乐的吗,这次用 Docker Compose 部署 Nextcloud 遇到的都是 Docker 使用上的错误,花了挺长时间去查资料找原因。。。但归根结底是我对 Docker 网络知识了解不到位造成的,以及本地环境对 Docker 造成的影响。

那么问题又来了,在使用一个工具时,是应该在使用前进行系统学习,还是应该在使用中处理遇到的问题?


鱼子盖饭
WRITTEN BY
鱼子盖饭
Get into trouble, make mistakes.


What's on this Page