繁体   English   中英

Docker Swarm容器无法连接到它的Docker主机,连接超时

[英]Docker Swarm container cannot connect to its Docker host, connection times out

长话短说:Docker Swarm 主机 A 上的容器 C 可以访问 Nginx( deploy mode:global )Docker Swarm 主机 B 但不能访问 Docker Swarm 主机 A 通过 884126800538818 timed5.8 connection timed out

长话短说:我有一个带有 3 个主机的 Docker Swarm。 所有 Docker 容器都在scope:swarmdriver:overlay .network 上运行,称为internal.network 在 swarm 上,我还有 3 个 Nginx( deploy mode: global )正在运行。 Nginx 将 default.network 设置为internal.network ,但ports配置为target:80,published:80,protocol:tcp,mode:host (和其他端口)。 这个想法是将与 Docker 群主机的连接转发到 Nginx 容器,然后转发(反向代理)到运行在群上的 Docker 容器,例如 GitLab、Mattermost 等。 此外,Docker 群主机已将keepalived配置为共享相同的 IP(故障转移) - 因此无论将此共享 IP 分配给哪个 Docker 主机,始终有一个 Nginx 正在运行以接受传入请求。 我正在使用 Oracle Linux 8(内核 5.4.17 el8uek)和 Docker 20.10.12。 Docker 配置了icc: falseuserland-proxy: false

在以下示例中, addr.foo解析为shared ip

什么有效:

  • 共享的 IP 在 Docker 主机之间正确共享,一旦拥有 IP 的主机出现故障,另一个接管共享的 IP - 但是,问题似乎与keepalived无关,因为它也发生在 Docker 主机的 IP 上。
  • 从外部客户端可以连接到 Nginx(在共享的 IP 或 Docker 主机 IP 上)并被反向代理到 Docker 容器,例如 GitLab 或 Mattermost
  • 还有一个 PostgreSQL 在同一个堆栈和internal.network上运行,Mattermost 可以与internal.network上的 PostgreSQL 实例通信。
  • 在任何 Docker swarm 主机上,都可以运行curl https://addr.foocurl https://<shared ip>并访问 Nginx 和反向代理的 8053296 容器 8053296
  • 在任何 Docker swarm 主机上,都可以运行curl https://<host ip>并访问 Nginx 和反向代理的 Docker 容器
  • From within a Docker container (eg Nginx, GitLab, Mattermost) it is possible to run curl https://addr.foo or curl https://<shared IP> when the shared IP is not hosted by the Docker host that is hosting Docker 容器本身。

什么不起作用:

  • 在 Docker 容器(例如 Nginx、GitLab、Mattermost)中,不可能运行curl并指向托管容器的 Docker 群主机。 Curl(容器,docker)解析它自己的 IP Docker 群主机(例如curl https://<Docker host name> ),这是正确的,但随后连接超时。
  • 当共享 IP 由运行容器的 Docker 主机托管时,无法从 Docker 容器 ([...]) 运行curl并指向共享 IP。 访问容器 Docker 主机时curl连接超时。

因此,从容器内部不可能连接到容器 Docker 主机的 IP,而是连接到其他 Docker 主机的 IP。 所有 Docker 主机上的 .network 接口ens192都在 firewall-zone public中,所有必要的端口都打开,外部访问有效。

所以我的问题是:在 Docker 容器中,无法与托管 Docker 容器的 Docker 主机建立连接,但可以连接到另一台主机。

在主机 docker 主机 1 上, addr.foo解析为 docker 主机 2:

docker exec -it <nginx container id> curl https://addr.foo
[...] valid response
docker exec -it <nginx container id> curl https://<docker host 2>
[...] valid response
docker exec -it <nginx container id> curl https://<docker host 1>
connection timed out

为什么需要它:Mattermost 通过 GitLab 对用户进行身份验证。因此,Mattermost 需要连接到 GitLab。当 Mattermost 和 GitLab 在同一台 Docker swarm 主机上运行时,Mattermost 无法连接到 GitLab。

我不想做的事:限制 GitLab 和 Mattermost 不在同一群主机上运行。

我还尝试将接口docker_gwbridge移动到trusted的防火墙区域,这导致了 Docker 容器没有启动的问题。

我希望这是足够的信息来理解这个想法。

好的,我猜在这里找到了答案: Docker Userland Proxy

在上一节中,我们确定了两种情况,其中 Docker 无法使用 iptables NAT 规则到 map 到容器服务的已发布端口:

  • 当连接到另一个 Docker.network 的容器尝试访问服务时(Docker 正在阻止 Docker.networks 之间的直接通信);

  • 当本地进程尝试通过环回接口访问服务时。

这就是userland-proxy的用途,将其设置为true (默认)可启用所需的行为。

在容器之间通信时,您使用 docker 服务的服务名称,而不是主机 IP。

尝试从一个容器的 cli 根据服务名称 ping 其他容器。 如果没有回复,那么他们不在同一个 overlay.network 上。

遇到了类似的问题。 就我而言,nginx 没有正确确定容器的 ip 地址。 nginx 指令的明确指示有助于:

resolver 127.0.0.11 ipv6=off;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM