zoukankan      html  css  js  c++  java
  • Docker容器相互访问

    原文地址:https://blog.csdn.net/subfate/article/details/81396532?utm_source=copy

    很多时候,同一台机器上,需要运行多个docker容器,前文提到的docker-compose就是方便同时管理多个容器的工具,那么,容器与容器之间如何访问、通信呢?本文对此问题进行探讨。

    方式一:内部网络
    在安装docker时,会自动创建一个默认的bridge网络docker0。如下:

    $ ifconfig
    docker0   Link encap:以太网  硬件地址 02:42:7b:b6:74:3b  
              inet 地址:172.17.0.1  广播:0.0.0.0  掩码:255.255.0.0
              inet6 地址: fe80::42:7bff:feb6:743b/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1
              接收数据包:575938 错误:0 丢弃:0 过载:0 帧数:0
              发送数据包:700716 错误:0 丢弃:0 过载:0 载波:0
              碰撞:0 发送队列长度:0
              接收字节:47416735 (47.4 MB)  发送字节:1246042404 (1.2 GB)

    每个容器启动时,都会创建对应的网卡,地址为172.17.0.X,因此,容器之间都可以通过对应的IP地址进行访问。
    然后,运行ubuntu镜像:

    docker run -it –rm ubuntu bash

    在同一台电脑启动另一个终端,启动ubuntu镜像,使用同样的命令启动ubuntu镜像:

    docker run -it --rm ubuntu bash

    两个容器的IP如下(因为都是相同的镜像,所以直接列出IP地址):

    root@4e097f487019:/# ifconfig
    eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
              inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:25 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:3653 (3.6 KB)  TX bytes:0 (0.0 B)

    root@c02729d604f6:/# ifconfig  
    eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:03  
              inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:23 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:3380 (3.3 KB)  TX bytes:0 (0.0 B)
    Ping测试结果如下:

    root@c02729d604f6:/# ping -c 3 172.17.0.2
    PING 172.17.0.3 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.178 ms
    64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.118 ms
    64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.119 ms
    --- 172.17.0.2 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.118/0.138/0.178/0.028 ms
    这个方式只能通过IP形式,前提是要知道每个容器的IP地址。这种方式实用性不强。

    方式二:使用link
    在方式一基础上,使用–link选项,则可以将网络别名(或容器别名)的方法进行ping。
    先启动ubuntu镜像:

    docker run -it --rm --name ubuntu1 ubuntu bash

    这里将其命名为ubnntu1。
    接着在另一个终端启动再启动ubuntu镜像:

    docker run -it --rm --name ubuntu2 --link ubuntu1:ubuntu1  ubuntu bash

    这个容器命名为ubuntu2,而且将其连接到ubuntu1中。注意–link ubuntu1:ubuntu1第一个ubuntu1表示容器,第二个ubuntu1表示网络/容器别名。为了统一性,建议两者相同(这种情况下,只需要写–link ubuntu1即可,文中只是为了示例其选项用法)。
    在这个容器中查看hosts文件,内容如下:

    root@f8199115a731:/# cat /etc/hosts
    127.0.0.1       localhost
    ::1     localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.2      ubuntu1 e288b5d2f0a4
    172.17.0.3      f8199115a731

    倒数第二行看到,已经将IP地址172.17.0.2和ubuntu1(容器ID为e288b5d2f0a4)对应起来了。
    下面ping测试

    root@f8199115a731:/# ping -c 3 172.17.0.2  
    PING 172.17.0.2 (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.123 ms
    64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.111 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.109 ms
    --- 172.17.0.2 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.109/0.114/0.123/0.000 ms
    root@f8199115a731:/#

    使用ping -c 3 ubuntu1也可以ping通。

    root@f8199115a731:/# ping -c 3 ubuntu1    
    PING ubuntu1 (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.134 ms
    64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.121 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.121 ms
    --- ubuntu1 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.121/0.125/0.134/0.000 ms

    对于容器A和容器B之间使用–link连接,必须先启动其中一个容器,比如容器A,然后在启动容器B时,将其连接到容器A。这样,就可以在容器B中使用网络别名连接容器A了。以gitlab为jenkins为例,实际应用中,需要先启动gitlab,然后启动jenkins并连接到gitlab容器。

    方式三:自定义bridge网络
    首先在主机上创建一个网络,命令如下:

    docker network create mynet
    1
    在主机用ifconfig查看网络情况,对应的网卡地址如下:

    br-49d34a6504d1 Link encap:以太网  硬件地址 02:42:bc:ba:62:17  
              inet 地址:172.18.0.1  广播:0.0.0.0  掩码:255.255.0.0
              inet6 地址: fe80::42:bcff:feba:6217/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1
              接收数据包:1400 错误:0 丢弃:0 过载:0 帧数:0
              发送数据包:1558 错误:0 丢弃:0 过载:0 载波:0
              碰撞:0 发送队列长度:0
              接收字节:79757 (79.7 KB)  发送字节:3650465 (3.6 MB)

    注:可以创建多个网络,每个网络IP范围均不相同。
    然后,运行ubuntu镜像:

    docker run -it --rm --network mynet --network-alias ubuntu1  ubuntu bash

    其中,--network mynet表示使用mynet网络,--network-alias ubuntu1表示该容器运行时,使用的网络别名为ubuntu1。(网络别名的作用类似hostname,不管容器IP如何变化,都可以使用同一个别名。)
    接着,在同一台电脑启动另一个终端,启动ubuntu镜像:

    docker run -it --rm --network mynet --network-alias ubuntu2 ubuntu bash

    命令形式同上。只是将网络别名改为ubuntu2。
    在ubuntu容器中使用ifconfig查看该容器的IP地址,如下:

    root@74f4089ce79c:/# ifconfig
    eth0      Link encap:Ethernet  HWaddr 02:42:ac:12:00:02  
              inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1575 errors:0 dropped:0 overruns:0 frame:0
              TX packets:1405 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:3652734 (3.6 MB)  TX bytes:99679 (99.6 KB)

    再ping另一个容器ubuntu2,结果可以ping通。

    root@74f4089ce79c:/# ping ubuntu2
    PING jenkins (172.18.0.3): 56 data bytes
    64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.142 ms
    64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.131 ms

    同样地,在ubuntu2容器中ping另一个容器ubuntu,也可以ping通。

    root@927fe3bab506:/# ping ubuntu
    PING ubuntu (172.18.0.2): 56 data bytes
    64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.122 ms
    64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.113 ms

    推荐使用这个方式。
    默认网络中的link是静态的,不允许链接容器重启,而自定义网络下的link是动态的,支持链接容器重启(以及IP变化)
    因此,使用–link时链接的容器,在默认网络中必须提前创建好,而自定义网络下不必预先建好。使用网络别名后,不管容器ip地址如何变化,都可以根据别名进行连接。

    docker网络相关命令
    在主机上创建一个网络,命令如下:

    docker network create mynet

    查看自定义bridge网络命令如下:

    docker network inspect mynet

    移除网络要求网络中所有的容器关闭或断开与此网络的连接时,才能够使用移除命令:

    docker network disconnet mynet 容器ID

    再移除网络

    docker network rm mynet

  • 相关阅读:
    SharePoint 2010 User Profile Sync Service自动停止
    如何区别多个svchost.exe?
    Log Parser分析IIS log的一个简单例子
    Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
    Windows中右键点击文件夹, 结果找不到共享选项卡, 怎么办?
    介绍SOS中的SaveModule命令
    SharePoint中Draft版本的文档不会收到document added的Alert Email
    和我一起学Windows Workflow Foundation(1)创建和调试一个WF实例
    门户网站
    C#基础—— check、lock、using语句归纳
  • 原文地址:https://www.cnblogs.com/boonya/p/9797392.html
Copyright © 2011-2022 走看看