我的 Docker 有两个运行中的 Container 容器:

Jenkins:
ip:192.168.0.220:10240
名称:myjenkins

Gitlab:
ip:192.168.0.220:10082
名称:mygitlab

(主机 ip 为:192.168.0.220)
经过一次 [公司的网络改造] 后,发现这两个容器无法通过 [主机 ip:port ] 的方式 curl ,但是可以 ping 得通。以下为一些表现,求大家帮忙找找问题。(注:网络改造前,完全是可以通过 [主机 ip:port ] 互相访问的)。
在 jenkins 容器上:

ping gitlab ip: ping 192.168.0.220:10082。没有问题。
curl gitlab ip: curl 192.168.0.220:10082。一直没反应。
curl gitlab 容器名称+port:curl mygitlab:3000。没有问题。(由于 gitlab 与 Jenkins 容器处于同一个 bridge network 当中,所以可以通过容器名称访问。其中 3000 为 gitlab 自身的端口号)

在主机上:

ping gitlab ip: ping 192.168.0.220:10082。没有问题。
curl gitlab ip: curl 192.168.0.220:10082。没有问题。

麻烦大家帮忙看看,为什么这两个容器没法通过 [主机 ip:port ] 互相 curl ?

jenkins 是 curl www.baidu.com 是通的

搞错了,ping 不带 port 。另外,ping 可以通,是不是代表路由表是通的。

注意了,我知道 [通过容器名] 可以互联,但是,我的需求是:通过 [主机 ip:port] 也能够访问。

ping 还能带端口呢?

  1. 假设你的容器网络为 bridge network ,那么容器之间要 link,才能互相通过对方的 hostname 访问(你也提到了这点)2. bridge network 情况下,需要通过 -p 发布端口到宿主机的某个接口,宿主机外面才能访问3. bridge network 下,容器如果想要访问宿主机(的某个服务),那么一般会选择 docker0 也就是 172.17.0.1 ,当然选择 host 的某个网卡 IP 也行,只是不那么靠谱因为可能会变。4. ping 没有端口的啦根据你的现象总结,可能需要检查下1. publish port 的写法以及 host 的 IP2. 是否新增 iptables 规则,docker 是靠的 iptables

ping 是 icmp ,http 是 tcp ,完全两个东西,并不能说明一个行则另一个必须行。

#1 不知道啊,计算机网络不怎么懂

#2 感谢大佬。但是,我们公司 [网络改造] 之前,jenkins 容器是完全可以通过 [主机 ip:port] 的方式访问 gitlab 的,现在确不行了。-p 规则检查过了,现在宿主机外面访问完全没问题了。比如:宿主机外 192.168.0.220:10082 是完全可以访问 gitlab 的。我周一去检查一下 iptables 规则。

#3 那 http 不行怎么办呢?我们 [网络改造] 前,是完全行的。

简单了解一下 tcp/ip 模型,然后了解一下 docker 的网络,你就知道了。不解释的情况下,请使用容器名互访。

我有类似问题,不过是两台机器上,A 机器宿主机本身是可以 curl 到 B 机器的,但在 A 机器的一个容器里,只能 ping 通 B 机器的 IP ,curl 就不通,很奇怪,排查了很多地方都还没找到原因。有哪位大佬能提供一点线索吗?

这些问题你把宿主机、容器的路由表和 iptables 规则都捋一遍,如果还有问题再来问更合适

一般来说 tcping 才带端口

我觉得问题大概率出在 iptables 里。

两个容器加到一个 docker network 里面用容器名访问

#7 就是容器名互访不好用。比如 gitlab 中的仓库,maven 地址是 [主机 ip:port] 的,拉到 jenkins 里就没法拉到 maven 仓库了。

#8 是不是要使用 overlay 网络啊你

ping 端口是什么操作?

#13 可是容器名和用哪个仓库没一毛钱关系。我还是建议你稍微了解一点网络。另外,这个问题可能跟网络改造也没什么关系

就是比如我有一个 java 仓库,引用的 maven 仓库也是 gitlab 容器上的,maven 服务器地址和 gitlab 一样,也是 192.168.0.220:10082 。这时候如果 jenkins 容器把这个 java 仓库拉一下编译,由于 jenkins 没法访问 192.168.0.220:10082 ,就没法下载引用的 maven 库,就没法编译

  • 从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server ,使容器可以直接通过“容器名”通信。使用默认的 bridge 网络,不能通过 DNS server 实现通过容器名通信。- ping 通 192.168.0.220 是宿主机,和容器没有半点关系。根据网络,一般使用 bridge ,192.168.0.220:10082 这种是需要创建容器的时候把端口从容器里映射出来.

要用容器名通讯你必须创建一个 bridge 网络。你得把创建容器的 docker run 命令,或者把 yaml 配置文件贴出来。

docker 主机的防火墙开放 tcp 端口。docker 有时候很奇怪,不开防火墙端口,外部机器能访问,但是内部容器可能会无法访问。

你先 telnet 192.168.0.220 10240telnet 192.168.0.220 10082 看看是否能够正常连上吧...

创建一个 network 并划好网段把这两个容器用这个 external 的 network 连起来并且固定 ip ,用 ip 通信就行了。每当看到这个感觉还是 k8s 的 calico+coredns 舒服

这办法太多了。1. 容器间直接用容器名 myjenkins 、mygitlab 就能互相访问了。2. 容器内部也是有内部 ip 的,你可以先 docker network create [网络名],在 docker run --network [网络名]的时候指定这个网络,这样两个容器就在一个内部的局域网了,通过 docker inspect [容器 ID]可以查看具体的内部 ip 地址,同时端口也要用内部端口。3. 同 2 ,它其实也是一个外部网络。

你这个容器网络用的是 HOST 模式? 那两容器间用 127.0.0.1+端口方式试下

先用 docker0 这个虚拟网卡的 ip 试试连通性吧,也就是 172.0.0.0/24 这个网段的 ip ,这个网段不用走路由器。

两个 bridge 模式的内网 IP ,就是 172 的那个,能互通不?

你应该使用 docker 内网 IP ,172 那个可以 ping 通 192.168.0.200 并不代表路由到了另一个 docker 容器,这应该是到宿主机是通的你映射了 port ,

打快了没打完,你映射了 port ,或者使用 host 模式,才能够通过 192.168.0.200:对应端口访问容器否则只能通过内网 IP可以通过 docker network 查看

用内部端口