V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
KratosOmega
V2EX  ›  程序员

Docker 的两个 Container,无法通过 [主机 ip:port] 互相 curl

  •  
  •   KratosOmega · 2024-03-22 20:00:35 +08:00 · 3606 次点击
    这是一个创建于 372 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    1. Jenkins:
      • ip:192.168.0.220:10240
      • 名称:myjenkins
    2. Gitlab:
      • ip:192.168.0.220:10082
      • 名称:mygitlab

    (主机 ip 为:192.168.0.220)

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

    在 jenkins 容器上:

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

    在主机上:

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

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

    第 1 条附言  ·  2024-03-23 11:27:03 +08:00
    jenkins 是 curl www.baidu.com 是通的
    第 2 条附言  ·  2024-03-23 12:39:59 +08:00
    搞错了,ping 不带 port 。
    另外,ping 可以通,是不是代表路由表是通的。
    第 3 条附言  ·  2024-03-23 17:09:15 +08:00
    注意了,我知道 [通过容器名] 可以互联,但是,我的需求是:
    通过 [主机 ip:port] 也能够访问。
    第 4 条附言  ·  2024-03-25 11:39:52 +08:00
    https://www.dropbox.com/scl/fi/r64cj5c82cllih3zt6020/iptables.txt?rlkey=7jn23k7z3xku3h1k2cd99yqfv&dl=0
    这是我导出的 docker 主机的 iptables 。

    容器的 iptables 是空的,什么都没配置。麻烦各位大佬帮忙看看。
    第 5 条附言  ·  2024-03-25 14:22:38 +08:00
    结案~~~iptables 的问题,感谢各位大牛
    30 条回复    2024-03-25 11:27:44 +08:00
    whileFalse
        1
    whileFalse  
       2024-03-22 20:08:55 +08:00 via Android   ❤️ 2
    ping 还能带端口呢?
    winterpotato
        2
    winterpotato  
       2024-03-22 20:17:52 +08:00   ❤️ 1
    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 的 IP
    2. 是否新增 iptables 规则,docker 是靠的 iptables
    DefoliationM
        3
    DefoliationM  
       2024-03-22 20:19:58 +08:00 via Android
    ping 是 icmp ,http 是 tcp ,完全两个东西,并不能说明一个行则另一个必须行。
    KratosOmega
        4
    KratosOmega  
    OP
       2024-03-22 22:03:32 +08:00
    @whileFalse #1 不知道啊,计算机网络不怎么懂
    KratosOmega
        5
    KratosOmega  
    OP
       2024-03-22 22:07:48 +08:00
    @winterpotato #2 感谢大佬。
    但是,我们公司 [网络改造] 之前,jenkins 容器是完全可以通过 [主机 ip:port] 的方式访问 gitlab 的,现在确不行了。

    -p 规则检查过了,现在宿主机外面访问完全没问题了。比如:宿主机外 192.168.0.220:10082 是完全可以访问 gitlab 的。

    我周一去检查一下 iptables 规则。
    KratosOmega
        6
    KratosOmega  
    OP
       2024-03-22 22:08:28 +08:00
    @DefoliationM #3 那 http 不行怎么办呢?我们 [网络改造] 前,是完全行的。
    wheat0r
        7
    wheat0r  
       2024-03-22 23:15:41 +08:00
    简单了解一下 tcp/ip 模型,然后了解一下 docker 的网络,你就知道了。
    不解释的情况下,请使用容器名互访。
    icaolei
        8
    icaolei  
       2024-03-23 01:12:25 +08:00
    我有类似问题,不过是两台机器上,A 机器宿主机本身是可以 curl 到 B 机器的,但在 A 机器的一个容器里,只能 ping 通 B 机器的 IP ,curl 就不通,很奇怪,排查了很多地方都还没找到原因。有哪位大佬能提供一点线索吗?
    hawhaw
        9
    hawhaw  
       2024-03-23 07:15:32 +08:00 via Android
    这些问题你把宿主机、容器的路由表和 iptables 规则都捋一遍,如果还有问题再来问更合适
    Goooooos
        10
    Goooooos  
       2024-03-23 07:35:34 +08:00 via Android
    一般来说 tcping 才带端口
    A01514035
        11
    A01514035  
       2024-03-23 08:45:46 +08:00
    @icaolei 我觉得问题大概率出在 iptables 里。
    INTOX8O
        12
    INTOX8O  
       2024-03-23 09:58:31 +08:00
    两个容器加到一个 docker network 里面用容器名访问
    KratosOmega
        13
    KratosOmega  
    OP
       2024-03-23 10:21:35 +08:00
    @wheat0r #7 就是容器名互访不好用。比如 gitlab 中的仓库,maven 地址是 [主机 ip:port] 的,拉到 jenkins 里就没法拉到 maven 仓库了。
    KratosOmega
        14
    KratosOmega  
    OP
       2024-03-23 10:21:51 +08:00
    @icaolei #8 是不是要使用 overlay 网络啊你
    pendulum
        15
    pendulum  
       2024-03-23 11:15:21 +08:00
    ping 端口是什么操作?
    wheat0r
        16
    wheat0r  
       2024-03-23 12:26:59 +08:00
    @KratosOmega #13 可是容器名和用哪个仓库没一毛钱关系。
    我还是建议你稍微了解一点网络。
    另外,这个问题可能跟网络改造也没什么关系
    KratosOmega
        17
    KratosOmega  
    OP
       2024-03-23 12:37:51 +08:00 via iPhone
    @wheat0r 就是比如我有一个 java 仓库,引用的 maven 仓库也是 gitlab 容器上的,maven 服务器地址和 gitlab 一样,也是 192.168.0.220:10082 。
    这时候如果 jenkins 容器把这个 java 仓库拉一下编译,由于 jenkins 没法访问 192.168.0.220:10082 ,就没法下载引用的 maven 库,就没法编译
    fish3125
        18
    fish3125  
       2024-03-23 12:50:50 +08:00   ❤️ 1
    - 从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server ,使容器可以直接通过“容器名”通信。使用默认的 bridge 网络,不能通过 DNS server 实现通过容器名通信。
    - ping 通 192.168.0.220 是宿主机,和容器没有半点关系。根据网络,一般使用 bridge ,192.168.0.220:10082 这种是需要创建容器的时候把端口从容器里映射出来.
    fish3125
        19
    fish3125  
       2024-03-23 12:57:39 +08:00
    要用容器名通讯你必须创建一个 bridge 网络。
    你得把创建容器的 docker run 命令,或者把 yaml 配置文件贴出来。
    yinmin
        20
    yinmin  
       2024-03-23 13:13:14 +08:00 via Android
    docker 主机的防火墙开放 tcp 端口。docker 有时候很奇怪,不开防火墙端口,外部机器能访问,但是内部容器可能会无法访问。
    burby
        21
    burby  
       2024-03-23 13:24:11 +08:00
    你先
    telnet 192.168.0.220 10240

    telnet 192.168.0.220 10082

    看看是否能够正常连上吧...
    zx900930
        22
    zx900930  
       2024-03-23 15:14:25 +08:00
    创建一个 network 并划好网段
    把这两个容器用这个 external 的 network 连起来并且固定 ip ,用 ip 通信就行了。

    每当看到这个感觉还是 k8s 的 calico+coredns 舒服
    klo424
        23
    klo424  
       2024-03-23 16:10:26 +08:00
    这办法太多了。

    1. 容器间直接用容器名 myjenkins 、mygitlab 就能互相访问了。
    2. 容器内部也是有内部 ip 的,你可以先 docker network create [网络名],在 docker run --network [网络名]的时候指定这个网络,这样两个容器就在一个内部的局域网了,通过 docker inspect [容器 ID]可以查看具体的内部 ip 地址,同时端口也要用内部端口。
    3. 同 2 ,它其实也是一个外部网络。
    cat1879
        24
    cat1879  
       2024-03-23 19:02:07 +08:00
    你这个容器网络用的是 HOST 模式? 那两容器间用 127.0.0.1+端口方式试下
    ns09005264
        25
    ns09005264  
       2024-03-23 19:12:13 +08:00
    先用 docker0 这个虚拟网卡的 ip 试试连通性吧,也就是 172.0.0.0/24 这个网段的 ip ,这个网段不用走路由器。
    helleon
        26
    helleon  
       2024-03-23 19:25:01 +08:00
    两个 bridge 模式的内网 IP ,就是 172 的那个,能互通不?
    hqt1021
        27
    hqt1021  
       2024-03-24 01:49:12 +08:00 via Android
    你应该使用 docker 内网 IP ,172 那个
    可以 ping 通 192.168.0.200 并不代表路由到了另一个 docker 容器,这应该是到宿主机是通的
    你映射了 port ,
    hqt1021
        28
    hqt1021  
       2024-03-24 01:50:17 +08:00 via Android   ❤️ 1
    @hqt1021 打快了没打完,
    你映射了 port ,或者使用 host 模式,才能够通过 192.168.0.200:对应端口访问容器
    否则只能通过内网 IP
    可以通过 docker network 查看
    iblessyou
        29
    iblessyou  
       2024-03-24 15:30:14 +08:00
    用内部端口
    KratosOmega
        30
    KratosOmega  
    OP
       2024-03-25 11:27:44 +08:00
    @hqt1021 #28 感谢,内网和 host 模式都不满足我们的需求,我还是想使用 [主机 host:port] 的模式。
    已经确认过了,10082 是我映射后的 Port ,没有问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2405 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:55 · PVG 23:55 · LAX 08:55 · JFK 11:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.