V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kismetX
V2EX  ›  Docker

Docker 容器间相互访问 refused

  •  
  •   kismetX · 2017-11-06 21:47:44 +08:00 · 7854 次点击
    这是一个创建于 2604 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我用 docker-compose.yml 配置了 nginx、web1、web2

    nginx: build: ./nginx ports: - "80:80" expose: - "80" links: - "web1" - "web2"

    auth: build: ./php expose: - "9000"

    plan: build: ./php expose: - "9000"

    nginx 里配了给 web1、web2 分别配了,web1.domain.comweb2.domain.com ,结果 web1 和 web2 不能相互访问,提示 connect refused,在宿主机可以访问 web1、web2,敢问各位大佬是什么原因。。在 web1 和 web2 容器里 ping 域名都是 127.0.0.1,应该是我在宿主机配置了 hosts 的原因

    13 条回复    2017-11-07 13:41:29 +08:00
    kkxxxxxxx
        1
    kkxxxxxxx  
       2017-11-06 22:11:04 +08:00   ❤️ 1
    同一台宿主机的话,要么加入同一网桥,要么防火墙写对应的路由,目前只知道这两个
    tomczhen
        2
    tomczhen  
       2017-11-06 22:35:50 +08:00 via Android
    宿主机配置 host ?也就是用 host 改了域名的解析么?
    那么不用 127.0.0.1 而是改成内网 IP 试试。
    kismetX
        3
    kismetX  
    OP
       2017-11-06 23:06:54 +08:00
    @kkxxxxxxx 容器相互间本来就是处于同一局域网,应该不用这么加吧,你说的防火墙加路由不是很明白,防火墙不是用来过滤用的吗?
    @tomczhen 容器的 ip 是动态的,给 nginx 的容器做了和宿主机的端口映射,原文里的是 docker-compose.yml 里的配置,展示和编辑时不一样~
    tomczhen
        4
    tomczhen  
       2017-11-06 23:37:40 +08:00   ❤️ 1
    哦,那建议去看官方文档关于 Network 和 DNS 这块的内容吧,希望能找到解决方法,洗洗睡。
    kismetX
        5
    kismetX  
    OP
       2017-11-06 23:53:06 +08:00
    @tomczhen 看了一下。。英文很一般,单词都认识,就是看不懂~~
    wwqgtxx
        6
    wwqgtxx  
       2017-11-07 07:36:29 +08:00 via iPhone   ❤️ 1
    docker 默认的网络配置方式是一个私有网络加 nat 桥接,所以你在容器内访问 127.0.0.1 是访问的容器本身而不是宿主机
    kismetX
        7
    kismetX  
    OP
       2017-11-07 09:15:59 +08:00
    @wwqgtxx 对,我是在宿主机访问容器 1,然后容器 1 访问容器 2,结果是 refused,我在容器 1ping 容器 2 的域名,显示的 ip 是 127.0.0.1,讲道理应该是在宿主机或 nginx 容器才会这样
    wwqgtxx
        8
    wwqgtxx  
       2017-11-07 09:36:54 +08:00 via iPhone
    @kismetX 你在容器内访问另一个容器应该用另一个容器的 name 而不是域名,你域名是在宿主机的 hosts 中配置的,在容器中会直接被继承,所以还是 127.0.0.1,而如果你访问容器名,docker 会在内部给你添加 dns 映射保证你访问 web01 的时候获得的就是 web01 这个容器的内网 ip
    kismetX
        9
    kismetX  
    OP
       2017-11-07 10:06:37 +08:00
    @wwqgtxx 对,我刚刚也发现这个问题,于是我把宿主机的 hosts 改成了 docker 分配给宿主机的 ip,然后就可以了~
    kismetX
        10
    kismetX  
    OP
       2017-11-07 10:11:31 +08:00
    @wwqgtxx
    @tomczhen
    @kkxxxxxxx
    谢谢各位的帮忙啦^_^
    tomczhen
        11
    tomczhen  
       2017-11-07 11:18:33 +08:00 via Android
    @kismetX 说到底你还是没知道原因,其实如果是在网关上做 DNS 劫持解析域名的话你这个问题就不会遇到了。
    tomczhen
        12
    tomczhen  
       2017-11-07 11:42:47 +08:00
    总结一下吧。

    默认的网络结构下,你可以把宿主机看成一个路由器,宿主机的内网 IP 就是路由器的 WAN IP,容器 LAN IP 就是路由器的 LAN 口,所有容器都是接在路由器的 LAN 口上,使用 P 参数暴露端口时就像在路由器上做端口映射。

    你的情况是在宿主机上做 DNS 劫持,让两个域名解析为 127.0.0.1,这样宿主机访问域名实际是走的做了映射的 nginx 容器端口,但是其他两个容器是解析之后是访问自己。

    解决方法:

    1. 其他两个容器用 nginx 而不是域名访问 web

    2. 把 HOST 的解析由 127.0.0.1 换成宿主机容器 LAN IP 或 LAN IP

    切换到公网情况,这时为了保证所有客户端都正常,DNS 肯定是只能设置成宿主机的公网 IP,那么你不会遇到这个问题。在内网模拟的话,就是通过网关来劫持 DNS 记录,为了保证内网所有机器都能范围,那么劫持的记录肯定不是 127.0.0.1 而是你的宿主机内网 IP。
    kismetX
        13
    kismetX  
    OP
       2017-11-07 13:41:29 +08:00
    @tomczhen 是的,起初在宿主机配置成 127.0.0.1 web1.domain.com 是因为给 nginx 和宿主机做了 80 端口映射,所以在宿主机访问 web1 其实就是访问 nginx,但是通过 docker 去配置容器后,因为容器解析域名时使用了宿主机的 hosts (这一步不知道 docker 是怎么操作的),所以容器内解析域名是 127.0.0.1,而非 nginx 容器是没有开 80 端口的,所以域名能 ping 通且为 127.0.0.1,80 端口自然无法访问
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5772 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 02:49 · PVG 10:49 · LAX 18:49 · JFK 21:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.