![](/img/trans.png)
[英]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.