簡體   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