zoukankan      html  css  js  c++  java
  • docker常见的网络

    使用docker info (Docker version 19.03.6)

    可查询有6种网络模式

    Network: bridge host ipvlan macvlan null overlay
    

    一: bridge(桥接默认网络)

    –net=bridge
    Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。

    docker0为虚拟网卡,红色标注部分为容器的网关

    二: host  宿主机网络

    –net=host
    容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主
    机的。容器除了网络,其他都是隔离的。
    # docker run -it --net=host  busybox   进入容器查看网卡信息与宿主机相同,即网络未隔离
    

    三:none(不常用)

    –net=none
    获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
    # docker run -it --net=none  busybox   
    

    四、 container(与指定容器共用网络名称空间)

    –net=container:Name/ID
    与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
    # docker run -itd  -p 99:80  --name  bs  busybox 
    
    新开窗口,创建容器指定网络为container:bs 
    # docker run -d  --name  nginx01  --net=container:bs  nginx 
    
    # docker exec -it bs sh  (注意busybox使用bash进不去,用sh可以)
    / # netstat -anpt  (nginx容器未开启时,没用建立监听)
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
    tcp        0      0 :::80                   :::*                    LISTEN      -
    
    访问99端口号,成功访问nginx(99端口是为容器bs的80端口映射,却访问到nginx的80,即nginx共用了bs的网络名称空间)

    五、 自定义网络

    与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名容器之间网络通信。

    bs1和bs2没有加入到同一个网络,不可以相互通信

    # docker exec -it bs1 sh  
    / # hostname
    0eb59ec71d44
    / # ping bs2
    ping: bad address 'bs2'
    

    # docker exec -it bs2 sh

    / # hostname
    a51dcef1803d
    / # ping bs1
    ping: bad address 'bs1'
    

    # docker run -it --name bs4 --net  bs-test  busybox  (自定义属于桥接网络)

    $ docker network ls  列出所有正在使用的网络
    

    bs3和bs4加入到同一个网络,相互可以通信

    # docker run -it --name bs=4  --net bs-test  busybox

    / # ping bs3
    PING bs3 (172.18.0.3): 56 data bytes
    64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.151 ms
    64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.115 ms
    

    # docker run -it --name bs3  --net bs-test  busybox

    / # ping bs4
    PING bs4 (172.18.0.2): 56 data bytes
    64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.126 ms
    64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.286 ms
    

    六、macvlan(硬件地址vlan)

    Macvlan和overlay都属于bridge网络,目的是跨主机节点,实现容器通信

    macvlan的原理是在宿主机物理网卡上虚拟出多个子网卡,通过不同的MAC地址在数据链路层(Data Link Layer)进行网络数据转发的,它是比较新的网络虚拟化技术,需要较新的内核支持(Linux kernel v3.9–3.19 and 4.0+)。

    需要把container的ip暴露给外面,使用macvlan或者overlay技术来实现。同时macvlan的配置更简单,并且没有使用docker的bridge,转发效率更高。

    macvlan技术就是在物理网卡下,添加另一张虚拟网卡,其实就是在物理网卡下添加了一个条件分支。我们可以认为报文从物理网卡进入之后,会做一个switch判断,如果该报文mac属于macvlan,则直接发往macvlan后面的网络,否则就发往原host的网络。
                                       +---------------+
                                        | network stack |
                                        +---------------+
                                            |  |  |  |
                                  +---------+  |  |  +------------------+
                                  |            |  +------------------+  |
                                  |            +------------------+  |  |
                                  |                               |  |  |
                                  |            aa  +----------+   |  |  |
                                  | eth0     +-----| macvlan0 |---+  |  |
                                  |         /      +----------+      |  |
     Wire   +------+       +---------------+   bb  +----------+      |  |
    --------| eth0 |------/ if dst mac is /--------| macvlan1 |------+  |
            +------+     +---------------+        +----------+         |
                                              cc  +----------+         |
                                             +-----| macvlan2 |---------+
                                                   +----------+

    use macvlan

    docker network create -d macvlan 
        --subnet=192.168.1.0/24 
        --gateway=192.168.1.1  
        -o parent=enp4s0 mcv
    
    # 解释:
    # 1.创建macvlan网络,使用macvlan网络驱动
    # 2.指定要桥接的网络地址
    # 3.指定网关
    # 4.设置要在宿主机上那块网卡上建立虚拟子网卡
    
    
    # 测试
    docker  run --net=mcv --ip=192.168.1.99 -itd alpine /bin/sh
    # 运行容器,指定刚建好的macvlan网络,并制定IP地址。
    # 如果不指定IP,会通过IPAM分配IP,默认是从192.168.1.2开始分配。
    # 注意,分配时并不会判断地址冲突,可以通过docker的network命令去指定分配方式,这里不做赘述。
    
    docker  run --net=mcv -it --rm alpine /bin/sh
    # 运行另外一个容器,进行连通性测试
    ping 192.168.1.99
    ping 192.168.1.1
    

    实验ping host

    创建一个macvlan docker网络:

    docker network create -d macvlan 
    --subnet=192.168.1.0/24 
    --ip-range=192.168.1.0/24 
    -o macvlan_mode=bridge 
    -o parent=enp0s3 macvlan
    

    然后我们起一个container,ip为192.168.1.11:

    docker run -d --net=macvlan --ip=192.168.1.11 --name ngix ngix
    

    container确实没法ping通host,但是它是能够ping通外接的switch。

    container能够ping通host

    利用linux创建一个macvlan类型的link,同时赋予一个与container同网段的ip:

    sudo ip link add mymacvlan link enp0s3 type macvlan mode bridge
    sudo ip addr add 192.168.1.10/24 dev mymacvlan
    sudo ifconfig mymacvlan up
    

    ping通:

     ping 192.168.1.11
    PING 192.168.1.11 (192.168.1.11) 56(84) bytes of data.
    64 bytes from 192.168.1.11: icmp_seq=1 ttl=64 time=0.142 ms
    64 bytes from 192.168.1.11: icmp_seq=2 ttl=64 time=0.069 ms
    64 bytes from 192.168.1.11: icmp_seq=3 ttl=64 time=0.050 ms
    64 bytes from 192.168.1.11: icmp_seq=4 ttl=64 time=0.066 ms
    64 bytes from 192.168.1.11: icmp_seq=5 ttl=64 time=0.062 ms
    64 bytes from 192.168.1.11: icmp_seq=6 ttl=64 time=0.064 ms
    

    带vlan的macvlan

    我理解的带vlan的macvlan其实并不是macvlan实现的,实际上是linux的子接口本身就是利用vlan来区别不同的子接口,而macvlan依附在子接口上,为子接口上加了一个mac,因此从子接口macvlan出来的报文都会带有vlan tag。

     配置与上面类似,只是用的是子接口:

    docker network create -d macvlan 
    --subnet=192.168.2.0/24 
    --ip-range=192.168.2.0/24 
    -o macvlan_mode=bridge 
    -o parent=enp0s3.20 macvlan20
    
    docker run -d --net=macvlan20 --ip=192.168.2.11 --name ngix ngix
    
    sudo ip link add mymacvlan20 link enp0s3.20 type macvlan mode bridge
    sudo ip addr add 192.168.2.10/24 dev mymacvlan20
    sudo ifconfig mymacvlan20 up
    

    看一看interface

     ip -d link
    34: enp0s3.20@enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
        link/ether 08:00:27:0a:7c:d0 brd ff:ff:ff:ff:ff:ff promiscuity 1 
        vlan protocol 802.1Q id 20 <REORDER_HDR> addrgenmode eui64 
    

    可以看到我们添加了一个子接口,同时这个子接口有带vlan id 20
    ,使用的802.1q协议。

    再来ping一次,完全没问题:

    ~ ping 192.168.2.11
    PING 192.168.2.11 (192.168.2.11) 56(84) bytes of data.
    64 bytes from 192.168.2.11: icmp_seq=1 ttl=64 time=0.175 ms
    64 bytes from 192.168.2.11: icmp_seq=2 ttl=64 time=0.046 ms
    64 bytes from 192.168.2.11: icmp_seq=3 ttl=64 time=0.126 ms
    64 bytes from 192.168.2.11: icmp_seq=4 ttl=64 time=0.061 ms
    

    七、overlay网络

    overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密

    #1、创建docker swarm 集群(前提条件)
    docker-machine create --driver virtualbox m
    docker-machine create --driver virtualbox s
    ssh docker@192.168.99.106 -i ~/.docker/machine/machines/m/id_rsa
    ssh docker@192.168.99.107 -i ~/.docker/machine/machines/s/id_rsa
    # on m
    # master service on 2377 port , tcp 2377 port for cluster
    #management communications m is manager
    docker swarm init --advertise-addr 192.168.99.106
    # 2、
    # docker_gwbridge 172.18.0.0/16
    # ingress: 10.255.0.0/16
    # bridge - docker0 172.17.0.0/16
    docker network ls
    # on s
    # join swarm as a work node
    docker swarm join --token xx 192.168.99.106:2377
    # on m
    docker network create -d overlay --attachable my-overlay-attach
    # on s 不能看见my-overlay-attach
    docker network ls
    # on s 使用my-overlay-attach 创建容器后 , 使用docker network ls
    #可以看见my-overlay-attach
    docker run -itd --name s-c1 --net my-overlay-attach hub.c.163.com/library/busybox sh
    #on m
    docker run -itd --name m-c1 --net my-overlay-attach
    hub.c.163.com/library/busybox sh
    # on m
    docker exec -it m-c1 ping s-c1
    # on s
    docker exec -it s-c1 ping m-c1
    

    八、网络访问原理

     Veth设备的作用主要用来连接两个网络命名空间,如同一对网卡中间连着一条网线。既然是一对网卡,那么其中一块网卡称作另一块的peer。在Veth设备的一端发送数据会直接发送到另一端。

    docker就是这样使用veth pair设备连接宿主机网络与容器网络。理解veth设备的工作原理对于理解bridge网络起到至关重要的作用。

    # yum install -y bridge-utils-1.5-9.el7.x86_64

    # brctl show
    bridge name	          bridge id		    STP enabled	   interfaces
    br-f8764a88ccd2     8000.02422f5f8a4c	  no		
    docker0		     8000.0242b035e79f	  no		    veth1884649
    							    veth8c1abb8  
    							    vethd30a157
    

    容器访问外界网络:

    外界网络访问容器:


    https://www.cnblogs.com/iiiiher/p/8067226.html    macvlan实现双vlan互通

    https://www.jianshu.com/p/4ccb5e1c3016  docker 网络-overlay

    https://www.cnblogs.com/mushou/p/9656401.html   docker 环境下创建 overlay 网络方案




  • 相关阅读:
    linux上修改系统默认语言设置
    【计算机基础之编程语言】编程语言的发展
    【Java语言特性学习之四】常用集合
    【Java语言特性学习之三】Java4种对象引用
    【Java语言特性学习之二】反射
    【网络知识之七】QUIC(http3)
    【网络知识之六】UDP
    【网络知识之五】TCP
    【网络知识之四】HTTP/2
    【网络知识之三】HTTPS协议
  • 原文地址:https://www.cnblogs.com/zjz20/p/13699492.html
Copyright © 2011-2022 走看看