[英]Cannot connect with Docker container from inside a swarm and the host machine
[英]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:swarm
和driver: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: false
和userland-proxy: false
。
在以下示例中, addr.foo
解析为shared ip
。
什么有效:
keepalived
无关,因为它也发生在 Docker 主机的 IP 上。internal.network
上运行,Mattermost 可以与internal.network
上的 PostgreSQL 实例通信。curl https://addr.foo
和curl https://<shared ip>
并访问 Nginx 和反向代理的 8053296 容器 8053296curl https://<host ip>
并访问 Nginx 和反向代理的 Docker 容器curl https://addr.foo
or curl https://<shared IP>
when the shared IP is not hosted by the Docker host that is hosting Docker 容器本身。什么不起作用:
curl
并指向托管容器的 Docker 群主机。 Curl(容器,docker)解析它自己的 IP Docker 群主机(例如curl https://<Docker host name>
),这是正确的,但随后连接超时。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.