zoukankan      html  css  js  c++  java
  • Docker——容器网络

    容器网络的隔离

    Namespace是Docker所用技术之一,Namespace 是 Linux 内核用来隔离内核资源的方式。通过 Namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。

    Network Namespace则是Namespace种的一部分,其作用是用来隔离网络设备,网络栈,端口等。不同Network Namespace的资源相互不可见,彼此之间无法通信。

    虚拟化网络

    虚拟化网络即由linux内核所虚拟出来的网络,事实上,linux内核可模拟多种网络设备。

    • 可模拟网线设备:模拟的网线设备是成对出现的,一个可用在容器内,一端用在交换机内
    • 可模拟交换机:容器接在这个交换机上,如果IP在同一网段,就可以实现互相通信
    • 可模拟路由器,位于不同网络的设备互相连接通信。

    单节点容器通信

    linux内核模拟交换机,并通过虚拟网线设备将NS1及NS2连接到此交换器上。如果NS1和NS2是处同一网段,则NS1和NS2可以直接通信

    在物理机上可以有多个虚拟交换机,容器可以分别接在不同的虚拟交换机上,如果两个虚拟交换机不在同一个网段,那么如何进行通信呢?

    如果想要满足C1和C3通信,且C1和C3在不同的网段

    1.开启物理机的内核转发,使之通信

    2.再次模拟一个名称空间,开启内核转发,并且模拟2对网卡,分别插在s1和名称空间A1,s2和名称空间上A1

    多节点容器通信

    方法1:桥接模式(比如vmware的桥接)

    • 桥接模式情况下,物理网卡会作为交换机来使用
    • 所有虚拟机都接入到这个物理网卡所模拟的交换机
    • 然后再模拟出来一个网卡给物理机使用,这个模拟的网卡也接入到交换机上
    • 不同主机上的容器,可以用桥接的方式来实现通信,就是将物理网卡作为交换机

    注意:由于桥接模式中有多个模拟交换机,如果同处一个广播域,则会因为广播域内主机过多,导致产生广播风暴。代价是很大的。

    方法2:NAT模式:

    • 在nat模式场景下,每个容器都还是接入在一个虚拟交换机,并且容器的网关需要指向这个交换机的地址。
    • 当容器产生数据包的时候,这个数据就会发送到虚拟交换机上
    • 虚拟交换机是由内核模拟的,所以这个数据包会被内核收到,传到物理机上。
    • 内核就会检查发现目标主机是不是自己,如果不是自己,那么就会将这个数据包从网卡发送出去,这样就完成了跨站点的发送。

    注意:由于容器的ip是无法与网络中其他主机通信的。所以必须转发到物理机的ip,由物理机发送和接受数据包。所以NAT模式需要进行两次地址转换,效率太低

    方法3:叠加网络(Overlay network),这种网络是基于隧道模式实现的

    • 隧道模式下,也需要模拟一个交换机,而且容器也是接在交换机上。
    • 此时在进行数据发送的时候,不会修改数据包的源IP 源mac,而是在会原来数据包的基础上再封装一层ip和mac。
    • 数据包在解封装的时候找到正确的ip地址,进行数据传输。

    docker容器网络

    Docker在安装后自动提供3种网络,可以使用DOCKER NETWORK LS命令查看

    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    be3c15475776   bridge    bridge    local
    5bb868223c5e   host      host      local
    f34d22c18e39   none      null      local
    

    Docker容器网络模式

    网络模式 配置 说明
    host --network host 容器和宿主机共享Network namespace
    container --network container:NAME/ID 容器和另外一个容器共享Network namespace
    none --network none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等
    bridge --network bridge 默认模式

    host模式

    如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

    使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

    
    [root@localhost ~]# docker run --rm -it --network host busybox
    
    ## 进入容器交互shell内,查看IP,发现与物理机的network namespace一致
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
        link/ether 00:0c:29:16:30:38 brd ff:ff:ff:ff:ff:ff
        inet 192.168.197.141/24 brd 192.168.197.255 scope global dynamic noprefixroute ens160
           valid_lft 1082sec preferred_lft 1082sec
        inet6 fe80::16fe:dcc3:afe9:ed6/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever
    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
        link/ether 02:42:5b:fb:61:c0 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:5bff:fefb:61c0/64 scope link 
           valid_lft forever preferred_lft forever
    

    container模式

    这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

    [root@localhost ~]# docker run --rm -it busybox
    
    ## 第一个容器的ip为:172.17.0.2
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    ## 创建第二个容器,并选择模式为container,查看ip
    
    [root@localhost ~]# docker run --rm -it --network container:3c90f226228f busybox
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    ## 发现两个容器的ip一致,此时两个容器公用一个network namespace,但其他的namespace还是隔离状态
    

    none模式

    使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

    这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

    [root@localhost ~]# docker run --rm -it --network none busybox
    
    ## 查看发现并没有网卡连接,是封闭的容器
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    

    bridge模式(创建容器时默认的网络模式)

    当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

    从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。

    bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

    [root@localhost ~]# docker run --rm -it busybox
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    ## 重新再运行一个容器,查看Ip 
    
    [root@localhost ~]# docker run --rm -it busybox
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    ## 发现eth0网卡的ip地址都在172.17.0.0网段中。这个网段都是虚拟网桥的地址,每创建一个新的容器,网桥便为新的容器生成一个网段内的ip地址。
    

    容器网络配置

    创建Network Namespace

    [root@localhost ~]# ip netns add testns1
    [root@localhost ~]# ip netns list
    testns1
    
    ## 注意,已经存在的network namespace的名称无法再次创建
    [root@localhost ~]# ip netns add testns1
    Cannot create namespace file "/var/run/netns/testns1": File exists
    

    操作Network Namespce

    • 进入新创建的命名空间中
    ## 进入命令空间并查看网卡情况
    [root@localhost ~]# ip netns exec testns1 ip addr
    1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    
    • 开启lo网卡,并测试连接
    [root@localhost ~]# ip netns exec testns1 ip link set lo up
    
    [root@localhost ~]# ip netns exec testns1 ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    
    # 进入testns1用户空间,ping lo口的ip地址
    [root@localhost ~]# ip netns exec testns1 ping 127.0.0.1
    PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
    64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms
    64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.044 ms
    

    veth pair

    veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。

    引入veth pair是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。

    veth pair创建

    ## 新建类型为veth的连接
    [root@localhost ~]# ip link add type veth
    
    ## 生成一对端口设备 veth0和veth1
    [root@localhost ~]# ip a
    ......
    2: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
        link/ether 5a:8a:20:ae:b1:a9 brd ff:ff:ff:ff:ff:ff
    
    3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
        link/ether 76:f0:f7:c6:87:8c brd ff:ff:ff:ff:ff:ff
    

    转移veth pair,实现容器之间通讯

    • 新建testns2空间
    [root@localhost ~]# ip netns add testns2
    [root@localhost ~]# ip netns list
    testns2
    testns1
    
    • 将veth0转移到testns1网络空间内
    [root@localhost ~]# ip link set veth0 netns testns1
    
    ## 查看testns1,发现已经存在veth0
    [root@localhost ~]# ip netns exec testns1 sh
    sh-4.4# ip a
    ......
    11: veth0@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
        link/ether de:c2:86:9e:bf:dd brd ff:ff:ff:ff:ff:ff link-netnsid 0
    
    ## 为veth0位置Ip地址
    sh-4.4# ip link set veth0 up
    sh-4.4# ip addr add 192.168.1.1/24 dev veth0
    sh-4.4# ip a
    1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    11: veth0@if12: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
        link/ether de:c2:86:9e:bf:dd brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.1.1/24 scope global veth0
           valid_lft forever preferred_lft forever
    
    • 同理,将veth1转移到testns2网络空间内,并打开设备配置IP
    [root@localhost ~]# ip link set veth1 netns testns2
    [root@localhost ~]# ip netns exec testns2 sh
    sh-4.4# ip a
    ......
    12: veth1@if11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
        link/ether 2e:24:c0:34:7f:70 brd ff:ff:ff:ff:ff:ff link-netns testns1
    
    ## 打开网卡,并配置Ip
    sh-4.4# ip link set veth1 up
    sh-4.4# ip addr add 192.168.1.2/24 dev veth1
    sh-4.4# ip a
    ......
    12: veth1@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether 2e:24:c0:34:7f:70 brd ff:ff:ff:ff:ff:ff link-netns testns1
        inet 192.168.1.2/24 scope global veth1
           valid_lft forever preferred_lft forever
        inet6 fe80::2c24:c0ff:fe34:7f70/64 scope link 
           valid_lft forever preferred_lft forever
    
    ## 测试ping testns1上的veth0,发现可以通信
    sh-4.4# ping 192.168.1.1
    PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
    64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.048 ms
    64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.058 ms
    64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.057 ms
    64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.051 ms
    ^C
    --- 192.168.1.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 63ms
    rtt min/avg/max/mdev = 0.048/0.053/0.058/0.008 ms
    

    veth重命名

    ## 将testns1上的veth0设备重命名为eth0
    
    [root@localhost ~]# ip netns exec testns1 sh
    ## 先关闭网卡设备
    sh-4.4# ip link set veth0 down
    sh-4.4# ip a
    ......
    11: veth0@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
        link/ether de:c2:86:9e:bf:dd brd ff:ff:ff:ff:ff:ff link-netns testns2
        inet 192.168.1.1/24 scope global veth0
           valid_lft forever preferred_lft forever
    
    ## 重命名为eth0
    sh-4.4# ip link set dev veth0 name eth0
    
    ## 查看
    ......
    11: eth0@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
        link/ether de:c2:86:9e:bf:dd brd ff:ff:ff:ff:ff:ff link-netns testns2
        inet 192.168.1.1/24 scope global eth0
           valid_lft forever preferred_lft forever
    

    容器的常用操作

    容器内部查看主机名

    ## 创建新容器
    [root@localhost ~]# docker container run --rm -it --name test1 busybox
    ## 这里hostname即为容器的ID
    / # hostname
    3c25fd9c1ae0
    

    自定义容器主机名称

    ## 创建的时候加上'--hostname'参数,即可定义主机名
    [root@localhost ~]# docker container run --rm -it --name test1 --hostname sawyer busybox
    
    / # hostname
    sawyer
    

    修改容器的默认DNS

    ## 创建的时候定义'--dns'即可定义DNS地址
    [root@localhost ~]# docker run -it --name test1 --hostname sawyer --dns 114.114.114.114 --rm busybox
    
    / # cat /etc/resolv.conf 
    search localdomain
    nameserver 114.114.114.114
    

    添加hosts文件ip映射

    [root@localhost ~]# docker run -it --name test1 --add-host example.com:192.168.1.2 --rm busybox      
    
    / # 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
    192.168.1.2	example.com
    172.17.0.2	14429fe6ed1b
    

    开放容器端口

    run -p选项可以将容器中的应用端口映射到宿主机中,从而实现让外部主机可以通过访问宿主机的某端口来访问容器内应用的目的

    此选项有4种使用格式

    • -p <containerPort>
      • 将指定的容器端口映射至主机所有地址的一个动态端口
    [root@localhost ~]# docker run -d -p 80 --rm httpd
    9e33b3696f4180fb5a0c7cfcb6dcbfe3de0152930a89f2ab8026e18ef1f68389
    
    ## 容器中的80端口映射到了物理机上的随机端口,通过访问主机的随机端口,即可访问容器中的进程
    [root@localhost ~]# ss -antl
    State     Recv-Q      Send-Q            Local Address:Port            Peer Address:Port     
    LISTEN    0           128                     0.0.0.0:22                   0.0.0.0:*        
    LISTEN    0           128                        [::]:22                      [::]:*        
    LISTEN    0           128                           *:49153                      *:*        
    
    ## 测试访问
    [root@localhost ~]# curl localhost:49153
    <html><body><h1>It works!</h1></body></html>
    
    • -p <hostPort>:<containerPort>
      • 将容器端口<containerPort>映射至指定的主机端口<hostPort>
    [root@localhost ~]# docker container run -d -p 1112:80 --rm httpd
    963b7b250015e92f166cd4828564253963d51170da96344930cde783fe9353ee
    
    ## 将容器的80端口映射到了主机的1112端口上,同样可以访问httpd
    
    [root@localhost ~]# ss -antl
    State      Recv-Q      Send-Q            Local Address:Port           Peer Address:Port     
    LISTEN     0           128                     0.0.0.0:22                  0.0.0.0:*        
    LISTEN     0           128                        [::]:22                     [::]:*        
    LISTEN     0           128                           *:1112                      *:*        
    [root@localhost ~]# curl localhost:1112
    <html><body><h1>It works!</h1></body></html>
    
    • -p <ip>::<containerPort>
      • 将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口
    [root@localhost ~]# docker run --name test1 --rm -d -p 192.168.197.141::80 httpd
    ee7056c47d4484e853ce50aa26dec1b5cd59cd656b5676877b2e6739351e079e
    [root@localhost ~]# ss -antl
    State     Recv-Q     Send-Q             Local Address:Port            Peer Address:Port     
    LISTEN    0          128                      0.0.0.0:22                   0.0.0.0:*        
    LISTEN    0          128              192.168.197.141:49153                0.0.0.0:*        
    LISTEN    0          128                         [::]:22                      [::]:*  
    
    ## 发现用lo口无法进行访问,只能用本机ip进行访问
    [root@localhost ~]# curl localhost:49153
    curl: (7) Failed to connect to localhost port 49153: Connection refused
    
    [root@localhost ~]# curl 192.168.197.141:49153
    <html><body><h1>It works!</h1></body></html>
    
    
    • -p <ip>:<hostPort>:<containerPort>
      • 将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>
    [root@localhost ~]# docker container run --rm -d --name test1 -p 192.168.197.141:8080:80 httpd
    77fd4bae0c64cf44fd53c3fcfba9039d85dd6b97e23e813497e3bb4613a5830f
    
    ## 同时指定了映射到物理机的IP和端口
    [root@localhost ~]# ss -antl
    State     Recv-Q     Send-Q              Local Address:Port           Peer Address:Port     
    LISTEN    0          128               192.168.197.141:8080                0.0.0.0:*        
    LISTEN    0          128                       0.0.0.0:22                  0.0.0.0:*        
    LISTEN    0          128                          [::]:22                     [::]:*
    [root@localhost ~]# curl 192.168.197.141:8080
    <html><body><h1>It works!</h1></body></html>
    

    自定义bridge模式中docker0网络信息

    [root@localhost ~]# vim /etc/docker/
    daemon.json  key.json     
    [root@localhost ~]# vim /etc/docker/daemon.json 
    {
            "bip": ["192.168.1.1/24"],   将网桥Ip修改192.168.1.1
            "registry-mirrors": ["https://hub-mirror.c.163.com/"]
    }
    [root@localhost ~]# systemctl restart docker
    
    
    ## 运行新容器,查看容器ip
    [root@localhost ~]# docker container run --rm -it busybox
    / # ip a
    ......
    31: eth0@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
        inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    ## 发现容器ip为192.168.1.2,与虚拟网桥在同一网段,bip设置成功
    

    docker创建自定义桥

    除了使用docker默认给我们的网络模式外,我们还可以自行定义网络模式,前提是以已知的4种网络模式为基础,在其基础之上修改。

    ## 现在有3种默认的容器网络模式
    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    fa052ca96ddf   bridge    bridge    local
    5bb868223c5e   host      host      local
    f34d22c18e39   none      null      local
    
    ## 以bridge模式为基础,自定义一个新的网络模式,网段为2.0,网关Ip:2.1
    [root@localhost ~]# docker network create -d bridge --subnet '192.168.2.0/24' --gateway '192.168.2.1' my_br0
    67bf4ee5eb61d128ca5f7f113bf2a963aa424ac9a7ba7685896fbb8b318f8960
    
    ## 查看网络模式
    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    fa052ca96ddf   bridge    bridge    local
    5bb868223c5e   host      host      local
    67bf4ee5eb61   my_br0    bridge    local
    f34d22c18e39   none      null      local
    
    • 使用新的网络模式运行容器
    ## container_ip为192.168.2.2
    [root@localhost ~]# docker container run --network my_br0 --rm -it busybox
    / # ip a
    ......
    36: eth0@if37: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:c0:a8:02:02 brd ff:ff:ff:ff:ff:ff
        inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0
           valid_lft forever preferred_lft forever
    

    不同网桥之间的容器通信

    容器ip 网络模式
    192.168.2.2 my_br0
    192.168.1.2 bridge
    ## 尝试用192.168.2.2的容器通信1.2的容器发现无法通信
    / # ping 192.168.1.2
    PING 192.168.1.2 (192.168.1.2): 56 data bytes
    
    --- 192.168.1.2 ping statistics ---
    60 packets transmitted, 0 packets received, 100% packet loss
    
    
    ## 将my_br0创建的容器添加连接到bridge上
    
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
    1d3c12d83582   busybox   "sh"      12 seconds ago   Up 10 seconds             cool_bhaskara
    c29f7ec432df   busybox   "sh"      5 minutes ago    Up 5 minutes              goofy_maxwell
    
    
    [root@localhost ~]# docker network connect bridge 1d3c12d83582  ## 此id为为192.168.2.2容器
    
    
    ## 此时,我们在192.168.2.2容器中,查看ip,发现多了1个网卡链接,IP为192.168.1.3
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:c0:a8:02:02 brd ff:ff:ff:ff:ff:ff
        inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0
           valid_lft forever preferred_lft forever
    42: eth1@if43: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:c0:a8:01:03 brd ff:ff:ff:ff:ff:ff
        inet 192.168.1.3/24 brd 192.168.1.255 scope global eth1
           valid_lft forever preferred_lft forever
    
    ## 再次通信192.168.1.2,成功ping通
    / # ping 192.168.1.2
    PING 192.168.1.2 (192.168.1.2): 56 data bytes
    64 bytes from 192.168.1.2: seq=0 ttl=64 time=0.135 ms
    64 bytes from 192.168.1.2: seq=1 ttl=64 time=0.123 ms
    64 bytes from 192.168.1.2: seq=2 ttl=64 time=0.084 ms
    64 bytes from 192.168.1.2: seq=3 ttl=64 time=0.120 ms
    
  • 相关阅读:
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    使用Jasmine和karma对传统js进行单元测试
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    nginx 基于IP的多虚拟主机配置
    Shiro 框架的MD5加密算法实现原理
    项目实战:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)
    实用技巧:阿里云服务器建立公网物联网服务器(解决阿里云服务器端口,公网连接不上的问题)
  • 原文地址:https://www.cnblogs.com/sawyer95/p/14241887.html
Copyright © 2011-2022 走看看