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

    Docker容器网络

    Docker容器网络介绍

    Docker在安装后自动提供3种网络,可以使用docker network ls命令查看

    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    1589f1749fc8   bridge    bridge    local
    ed75b8665acd   host      host      local
    6906ded84590   none      null      local
    

    Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

    Docker的4种网络模式

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

    bridge模式(与本机的docker0桥接)

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

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

    bridge模式是docker的默认网络模式,不写--network参数,就是bridge模式。

    bridge模式如下图所示:

    演示如下:

    //本机的容器网桥是172.17.0.1
    [root@localhost ~]# ip a
    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
    2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 00:0c:29:0b:34:02 brd ff:ff:ff:ff:ff:ff
        inet 192.168.110.20/24 brd 192.168.110.255 scope global noprefixroute ens160
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:fe0b:3402/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:ee:28:39:8e 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
    47: veth26c26d7@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 66:f5:ab:e6:db:52 brd ff:ff:ff:ff:ff:ff link-netnsid 1
        inet6 fe80::64f5:abff:fee6:db52/64 scope link 
           valid_lft forever preferred_lft forever
    
    #使用交互模式进入到busybox容器,默认是bridge模式
    //容器buybox的IP地址是172.17.0.2
    [root@localhost ~]# docker run -it --rm 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
    48: eth0@if49: <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
           
     //容器leidazhuang的IP地址是172.17.0.3
    [root@localhost ~]# docker run -it --rm leidazhuang/web:v0.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
    46: eth0@if47: <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
    
    //测试是否可以互相ping通
    #在容器一中ping容器二的IP
    / # ping 172.17.0.3
    PING 172.17.0.3 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.093 ms
    64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.070 ms
    ^C
    --- 172.17.0.3 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.070/0.081/0.093 ms
    / # ping 172.17.0.3
    PING 172.17.0.3 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.073 ms
    64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.148 ms
    64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.074 ms
    ^C
    --- 172.17.0.3 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 0.073/0.098/0.148 ms
    
    #在容器二中ping容器一的IP
    / # ping 172.17.0.2
    PING 172.17.0.2 (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.085 ms
    64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.140 ms
    ^C
    --- 172.17.0.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.085/0.112/0.140 ms
    

    如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机端口]:[容器端口]访问容器。

    host模式(与本机的网卡ens160桥接)

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

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

    host模式如下图所示:

    演示如下:

    [root@localhost ~]# docker run -it --rm --network host 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
        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:0b:34:02 brd ff:ff:ff:ff:ff:ff
        inet 192.168.110.20/24 brd 192.168.110.255 scope global ens160
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:fe0b:3402/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue 
        link/ether 02:42:ee:28:39:8e 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
    47: veth26c26d7@if46: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0 
        link/ether 66:f5:ab:e6:db:52 brd ff:ff:ff:ff:ff:ff
        inet6 fe80::64f5:abff:fee6:db52/64 scope link 
           valid_lft forever preferred_lft forever
    

    container模式

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

    container模式如下图所示:

    演示如下:

    //用busybox镜像启动一个容器
    [root@localhost ~]# docker run -it --rm 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
    52: eth0@if53: <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 ps
    CONTAINER ID   IMAGE     COMMAND   CREATED              STATUS              PORTS     NAMES
    5ecc4b2e8129   busybox   "sh"      About a minute ago   Up About a minute             exciting_herschel
    [root@localhost ~]# docker run -it --rm --network container:5ecc4b2e8129 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
    52: eth0@if53: <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一样了,说明成功
    

    none模式(没有IP地址)

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

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

    应用场景:

    • 启动一个容器处理数据,比如转换数据格式
    • 一些后台的计算和处理任务

    none模式如下图所示:

    //没有ID地址信息
    [root@localhost ~]# docker run -it --rm --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
    / # 
    
  • 相关阅读:
    POJ 3468 A Simple Problem with Integers
    BZOJ 4430 Guessing Camels
    POJ 2309 BST
    POJ 1990 MooFest
    cf 822B Crossword solving
    cf B. Black Square
    cf 828 A. Restaurant Tables
    Codefroces 822C Hacker, pack your bags!
    [HDU 2255] 奔小康赚大钱
    [BZOJ 1735] Muddy Fields
  • 原文地址:https://www.cnblogs.com/leixixi/p/14467016.html
Copyright © 2011-2022 走看看