• 如何将Docker容器通过独立IP暴露给局域网


    菜鸟查了很多资料才找到解决办法,Hats off to the shares!

    https://blog.csdn.net/lvshaorong/article/details/69950694

    问题需求:

    先说我的需求:

    简单说:Centos上启动了几个容器,我要通过与Centos在同一局域网下的Win 10 PC去访问这些docker,但是Win 10 和 容器没有在一个网段下,不能直接通信。

    具体点:我把Centos作宿主机,利用Docker启动一个hadoop集群,我要通过与Centos在一个局域网下的Win10 PC机通过Java API的方式与集群中的节点进行通信。其实这个需求是我在实验中遇到问题后一步步定位到的,更具体地问题解决过程可以看我的另一篇文章

    我们知道,在Docker启动时会产生虚拟网卡,可以把这个网卡理解为一个虚拟交换机,然后每个容器都连接在这个交换机下,每个容器都拥有自己单独的网卡和IP。现在整理下我们的需求中大致的网络拓扑:

    Centos宿主机(假设IP为192.168.1.237)和Win 10 (假设IP为192.168.1.135)在同一局域网下,Centos上运行多个docker(假设所处网段为172.19.0.1/16)。这样的拓扑结构下,Centos宿主机可以和其上运行的容器通信,Centos宿主机可以和Win 10通信。

    通过查找各种资料,看到一些解决方案,比如,让容器使用静态独立外部IP等,由于我只是在学习hadoop的时候把Docker作为一个使用工具,不想花费太多时间在Docker上,所以希望尽可能简单的解决问题,最终决定了使用文章开头提到的参考资料。这个方案下的解决思路:

    解决方案思路:

    Centos宿主机查看网卡和IP:

    [root@centos7 ~]# ifconfig
    br-af4e4c5cd5b4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.19.0.1  netmask 255.255.0.0  broadcast 172.19.255.255
            inet6 fe80::42:6cff:fe9b:7ed2  prefixlen 64  scopeid 0x20<link>
            ether 02:42:6c:9b:7e:d2  txqueuelen 0  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 8  bytes 656 (656.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            inet6 fe80::42:f7ff:feb9:485d  prefixlen 64  scopeid 0x20<link>
            ether 02:42:f7:b9:48:5d  txqueuelen 0  (Ethernet)
            RX packets 165569  bytes 5882890 (5.6 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 24244  bytes 81774073 (77.9 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.1.237  netmask 255.255.255.0  broadcast 192.168.1.255
            inet6 fe80::1823:15e9:2383:bb13  prefixlen 64  scopeid 0x20<link>
            ether 00:0c:29:fd:d2:c8  txqueuelen 1000  (Ethernet)
            RX packets 5306454  bytes 1201239143 (1.1 GiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 354841  bytes 298525072 (284.6 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            inet6 ::1  prefixlen 128  scopeid 0x10<host>
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 135  bytes 9108 (8.8 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 135  bytes 9108 (8.8 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    veth0b92e02: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet6 fe80::d02a:1bff:fe77:4d9a  prefixlen 64  scopeid 0x20<link>
            ether d2:2a:1b:77:4d:9a  txqueuelen 0  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 8  bytes 656 (656.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    这里面br-af4e4c5cd5b4和docker0都是Docker创建的虚拟网卡,其中docker0是Docker启动时自己创建的,br-af4e4c5cd5b4是我为我的集群自定义的网络,都是桥接模式,这里我以br-af4e4c5cd5b4介绍,在看文章的你可能直接使用的docker0,也可能也是制定了自定义的网络,但是都没差别的,类比过去就好 ,主要注意IP就成。ens160这块网卡就是与Win 10在同一局域网下。

    通过在Centos宿主机查看路由信息可以看出:因为有了这两块网卡,Centos知道到目标地址为172.19.0.0/16以及到192.168.1.0/24的路由。从下面的结果可以看出,172.19.0.0/16网段的数据包通过br-af4e4c5cd5b4发出,192.168.1.0/24数据包通过ens160发出。

    [root@centos7 ~]# ip route
    default via 192.168.1.1 dev ens160 proto dhcp metric 100 
    172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
    172.19.0.0/16 dev br-af4e4c5cd5b4 proto kernel scope link src 172.19.0.1 
    192.168.1.0/24 dev ens160 proto kernel scope link src 192.168.1.237 metric 100 

    因为有了br-af4e4c5cd5b4,所以Centos可以和dockers通信,Centos在于dockers通信时使用的IP是172.19.0.1;因为有了ens160,所以Centos可以和Win 10通信,Centos于Win 10通信时使用的IP是192.168.1.237。

    在容器里面,查看下容器的网卡和IP,这个容器的IP为172.19.0.2

    [root@hadoop-0 /]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.19.0.2  netmask 255.255.0.0  broadcast 172.19.255.255
            ether 02:42:ac:13:00:02  txqueuelen 0  (Ethernet)
            RX packets 8  bytes 656 (656.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    查看下Win 10 的网卡和IP,(只贴出与Centos通信的网卡的信息),Win 10 IP为192.168.1.135。

    无线局域网适配器 WLAN:
    
       连接特定的 DNS 后缀 . . . . . . . :
       本地链接 IPv6 地址. . . . . . . . : fe80::d9ab:19ac:60d:8c5d%19
       IPv4 地址 . . . . . . . . . . . . : 192.168.1.135
       子网掩码  . . . . . . . . . . . . : 255.255.255.0
       默认网关. . . . . . . . . . . . . : 192.168.1.1

    结合上面的网络拓扑,现在如果我想让Win 10与dockers通信是不成功的,因为Win 10 不知道到172.19.0.0/16的路由,只能把数据包发送给路由器一,但是路由器一也不知道到172.19.0.0/16的路由,所以不能ping通。

    为了解决这个问题,只需要告诉Win 10 或 路由器一 到172.19.0.0/16的路由就好,而知道这个路由的设备就是我们的Centos,所以把172.19.0.0/16到Win 10 或 到路由器一的数据包转发给Centos(192.168.1.237)就可以了。

    具体解决方案:

    在Win 10 中添加静态路由:

    route add 172.19.0.1/16 192.168.1.237

    然后在Win 10下ping某个容器的ip可以ping通:

    C:WINDOWSsystem32>ping 172.19.0.2
    
    正在 Ping 172.19.0.2 具有 32 字节的数据:
    来自 172.19.0.2 的回复: 字节=32 时间=1ms TTL=63
    来自 172.19.0.2 的回复: 字节=32 时间=1ms TTL=63
    来自 172.19.0.2 的回复: 字节=32 时间<1ms TTL=63
    ……

    (在路由器一中添加路由的方法我没有尝试;另外,文章开头的参考方案中需要删除宿主机内的一条iptables,但是我没有删除成功,删除以后反而失败了,具体原因还不清楚)

    另外,虽然已经ping通,但是在我的使用场景下,telnet端口还是不通,最后无奈关闭了我的宿主机的防火墙,很不优雅,以后再解决吧,也希望有大神提供解决方案。

  • 相关阅读:
    流程图的标准画法
    java应用,直接请求没问题,通过nginx跳转状态吗400
    jenkins启动java项目的jar包总是退出
    可以通过下面的脚本直观的看一下当前系统中所有进程的得分情况:
    sonarqube安装的坑
    Windows共享设定-使用net use添加网络盘带上账号密码
    Synctoy2.1使用定时任务0X1
    如果报错,使用 journalctl -f -t etcd 和 journalctl -u etcd 来定位问题。
    NodePort 只能在node节点上访问,外部无法访问
    mysql5.7 yum安装
  • 原文地址:https://www.cnblogs.com/Jing-Wang/p/10848960.html
Copyright © 2020-2023  润新知