zoukankan      html  css  js  c++  java
  • Docker网络(host、bridge、none)详细介绍

    Docker网络(host、bridge、none)

    我们会首先学习Docker提供的几种原生网络,以及如何创建自定义网络;然后探讨容器之间如何通信,以及容器与外界如何交互。

     Docker网络从覆盖范围可分为单个host上的容器网络和跨多个host的网络,本章重点讨论前一种。对于更为复杂的多host容器网络,我们会在后面进阶技术章节单独讨论。


    Docker 安装时会自动在host 上创建三个网络,我们可用docker network ls命令查看

    docker network ls

    none网络

    顾名思义,none网络就是什么都没有的网络。挂在这个网络下的容器除了1o,没有其他任何网卡。容器创建时,可以通过-network=none指定使用none网络,如图

    docker run -it --network=none busybox

    我们不禁会问,这样一个封闭的网络有什么用呢?


    其实还真有应用场景。封闭意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用none网络。
    比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。


    当然大部分容器是需要网络的,我们接着看host网络。

    host网络

    连接到host网络的容器共享Docker host的网络栈,容器的网络配置与host完全一样。
    可以通过-network-host 指定使用host网络

    docker run -it --network=host busybox

    在容器中可以看到host的所有网卡,并且连hostmame 也是host的。host网络的使用场景又是什么呢?

    直接使用Docker host的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
    Docker host的另一个用途是让容器可以直接配置host网路,比如某些跨host的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理iptables
     

    bridge网络

    Docker安装时会创建一个命名为docker0的Linux bridge。如果不指定-network,创建的容器默认都会挂到docker0上

    brctl show

    当前docker0上没有任何其他网络设备,我们创建一个容器看看有什么变化

    一个新的网络接口vethb56e98c被挂到了docker0上,vethb56e98c就是新创建容器的虚拟网卡。
    下面看一下容器的网络配置

    容器有一个网卡eth0@if34,为什么不是vethb56e98c呢?

    实际上eth0@if34 和veth28c57df 是一对veth pair。 veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡, 网卡的一头(eth0@if34) 在容器中,另一头(veth28c57df) 挂在网桥docker0 上,其效果就是将eth0@if34 也挂在了docker0上。
    我们还看到eth0@if34 已经配置了IP 172.17.0.2, 为什么是这个网段呢?让我们通过docker network inspect bridge看- -下bridge 网络的配置信息

    原来bridge 网络配置的subnet 就是172.17.0.0/16, 并且网关是172.17.0.1. 这个网关在哪儿呢?大概你已经猜出来了,就是docker0

    容器网络拓扑图

    容器创建时,docker 会自动从172.17.0.0/16 中分配-个IP,这里16 位的掩码保证有足够多的IP可以供容器使用。

    user-defined网络

    除了none、host、bridge这三个自动创建的网络,用户也可以根据业务需要创建user-defined网络。
    Docker提供三种user-defined 网络驱动:bridge、overlay 和macvlan。overlay 和macvlan用于创建跨主机的网络

    我们可通过bridge 驱动创建类似前面默认的bridge 网络

    docker network create --driver bridge my_net
    [root@kvm ~]# docker network create --driver bridge my_net
    7428a4d14c67b44be3a7184a5a065303d3688b5b13883526989b7173af881170
    [root@kvm ~]# brctl show
    bridge name	bridge id		STP enabled	interfaces
    br-7428a4d14c67		8000.024221339eb6	no		
    docker0		8000.024280532eb0	no		veth6281a8d
    virbr0		8000.52540015904b	yes		virbr0-nic
    

    新增了一个网桥br-7428a4d14c67,这里7428a4d14c67正好是新建bridge网络my_net的短id。执行docker network inspect查看一下my_net的配置信息,

    这里172.18.0.0/16是Docker自动分配的IP网段。
    我们可以自己指定IP网段吗?
    答案是:可以。


    只需在创建网段时指定--subnet和-gateway参数

    docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2

    这里我们创建了新的bridge网络my_net2,网段为172.22.16.0/24,网关为172.22.16.1与前面一样,网关在my net2对应的网桥br-5d863e9778b6上

    容器要使用新的网络,需要在启动时通过--network指定

    docker run -it --network=my_net2 busybox

    容器分配到的IP为172.22.16.20到目前为止,容器的IP都是docker自动从subnet中分配,我们能否指定一个静态IP呢?
    答案是:可以,通过-p指定

    docker run -it --network=my_net2 --ip 172.22.16.8 busybox
    

    好了,我们来看看当前docker host的网络拓扑结构

    两个busybox容器都挂在mynet2上,应该能够互通

    可见同一网络中的容器、网关之间都是可以通信的。
    my_net2与默认bridge网络能通信吗?
    从拓扑图可知,两个网络属于不同的网桥,应该不能通信,我们通过实验验证一下,让busybox容器ping 不同网段容器

    确实 ping不通,符合预期。
    “等等!不同的网络如果加上路由应该就可以通信了吧?”我已经听到有读者在建议了这是一个非常非常好的想法。

    确实,如果host上对每个网络都有一条路由,同时操作系统上打开了ip forwarding,host就成了一个路由器,挂接在不同网桥上的网络就能够相互通信。下面我们来看看docker host是否满足这些条件呢?
     

    ip r查看host上的路由表:

    172.17.0.0/16和172.22.16.0/24两个网络的路由都定义好了。再看看ip forwarding:

    [root@kvm ~]# sysctl net.ipv4.ip_forward
    net.ipv4.ip_forward = 1
    

    ip forwarding也已经启用了。条件都满足,为什么不能通行呢?
    我们还得看看iptables:

    iptavles-save
    
    -A DOCKER-ISOLATION -i br-13ceb40bd8e8 -o docker0 -j DROP
    -A DOCKER-ISOLATION -i docker0 -o br-13ceb40bd8e8 -j DROP
    

    原因就在这里了:iptables DROP掉了网桥dockero与br-13ceb40bd8e8之间双向的流量。

    从规则的命名DOCKER-ISOLATION可知docker在设计上就是要隔离不同的netwrok

    那么接下来的问题是:怎样才能让busybox与httpd 通信呢?


    答案是:为httpd容器添加一块net_my2的网卡。这个可以通过docker network connect命令实现,

    docker network connect my_net2 655643ea6894

    我们在docker0网段器中查看一下网络配置

    容器中增加了一个网卡ethl,分配了my_net2的IP 172.22.16.3。现在busybox应该能够访问docker0网段了,验证一下

    busybox能够ping到httpd,并且可以访问httpd的Web服务所示。

    (因为这里我在docker0网段,用busybox代替的httpd)

    学习了Docker各种类型网络之后,接下来我们讨论容器与容器、容器与外界的连通问题

  • 相关阅读:
    PHP的MySQL扩展:PHP访问MySQL的常用扩展函数
    PHP的MySQL扩展:MySQL数据库概述
    JQuery笔记:JQuery和JavaScript的联系与区别
    《千与千寻》给读者带来了什么?
    Canvas入门(3):图像处理和绘制文字
    Canvas入门(2):图形渐变和图像形变换
    Canvas入门(1):绘制矩形、圆、直线、曲线等基本图形
    python第三十二天----6.3作业中…………
    python第三十一天-----类的封装、继承,多态.....
    python第三十天-类
  • 原文地址:https://www.cnblogs.com/heian99/p/12585724.html
Copyright © 2011-2022 走看看