zoukankan      html  css  js  c++  java
  • Docker之单机网络一

    网卡

    网卡是一块计算机硬件。其特点是每一个网卡都有独立的MAC地址,用户可以通过电缆进行相互之间的连接。其主要功能是将数据封装成以太网中的帧,通过链路管理进行传输,接受数据后,对数据进行编码和译码。其优点是提高了CPU的利用率通过链路管理进行传输,提升了CPU的性能。 再用通俗一点的话解释,网卡其实就是七层或者四层网络模型的门户,复制接收和转发数据如下图:

    Network Namespace介绍

    Network Namespace在逻辑上是网络堆栈的一个副本,它有自己的路由、防火墙规则和网络设备。默认情况下,子进程继承其父进程的Network Namespace。如果不显式创建新的Network Namespace,所有进程都从 init 进程继承相同的默认Network Namespace。

    每个新创建的Network Namespace默认有一个本地回环接口 lo,除此之外,所有的其他网络设备(物理/虚拟网络接口,网桥等)只能属于一个Network Namespace。每个Socket也只能和一个Network Namespace通信。

    创建Network Namespace

    备注:采用的环境为阿里云CentOS 8.2

    1. 检查默认的Network Namespace 的 ID;

      readlink /proc/$$/ns/net
      
    2. 创建名为networknamespacetest的Network Namespace;

       #创建名为networknamespacetest的Network Namespace
       ip netns add networknamespacetest
       #检查netns是否创建成功
       ls /var/run/netns
      
    3. 在networknamespacetest中创建一个bash进程并且查看Network Namespace的ID;

        #创建bash进程
        ip netns exec networknamespacetest bash
        #查看Network Namespace的ID
        readlink /proc/$$/ns/net
      
    4. 经过上面可以得出每个Network Namespace都是相互隔离的,接下来我们看下networknamespacetest有什么构成;

       ip addr
      
    5. Network Namespace由本地回环接口 lo构成,并且这个接口是处于关闭状态的,接下来我们启动这个回环接口;

      ip link set lo up
      
    6. 测试lo的连通性;

    两个Network Namespace之间如何通信

    Veth-Pair

    什么是Veth-Pair

    Veth是Linux中一种虚拟出来的网络设备,Veth设备总是成对出现,所以一般也叫Veth-Pair。Veth-Pair特点就是无法单独存在,删除其中一个,另一个也会自动消失。Veth的两头都直接连着网络协议栈,所以你创建一个Veth对,主机上就会多2个网卡。

    Veth-Pair作用

    Veth-Pair作用就是反向流转数据,从一头发数据,就会从另一头收到数据。Veth-Pair常常充当着一个桥梁,连接着各种虚拟网络设备。常见用途是连接两个Netwok Namespace,或者连接Linux-Bridge、OVS 之类的。

    实战

    1. 创建两个Network Namespace network01和network02;

       ip netns add network01
       ip netns add network02
      
    2. 创建一对Veth设备,默认情况下会自动为Veth-Pair生成名称,这里为了方便我们测试,我们在创建时指定 Veth-Pair的名称;

       #创建Veth-Pair
       ip link add veth01 type veth peer name veth02
       #查看主机中Veth-Pair
       ip link ls   
      
    3. 把这一对Veth-Pair分别放到Network Namespace network01 和 network02中;

       #绑定
       ip link set veth01 netns network01
       ip link set veth02 netns network02
      
       #查看namespace组成
       ip netns exec network01 ip addr
       ip netns exec network02 ip addr
      
       #查看主机中是否存在Veth-Pair
       ip link ls
      

      查看network01和network02中的网络资源,发现各自多了一个网卡,也就是veth设备的两个端点,如下图:

    ​ 当我们把Veth-Pair分配到Network Namespace中后,在主机上就看不到它们了,如下图:

    1. 给这些Veth-Pair分配IP并启用它们;
    #启动设备veth01
    ip netns exec network01 ip link set veth01 up
    #绑定IP
    ip netns exec network01 ip addr add 10.0.1.1/24 dev veth01
    #设置IP路由
    ip netns exec network01 ip route
    
    #启动设备veth02
    ip netns exec network02 ip link set veth02 up
    #绑定IP
    ip netns exec network02 ip addr add 10.0.1.2/24 dev veth02
    #设置IP路由
    ip netns exec network02 ip route
    
    1. 通过ping命令来验证两个Network Namespace是否可以通信;

      ip netns exec network01 ping -c 10.0.1.2
      

    至此我们就完成两个Network Namespace之间的通信。

    Bridge

    什么是Bridge

    Linux Bridge(网桥)是工作于二层的虚拟网络设备,功能类似于物理的交换机。Bridge可以绑定其他Linux网络设备作为从设备,并将这些设备虚拟化为端口,当一个从设备被绑定到Bridge上时,就相当于真实网络中的交换机端口插入了一个连接有终端的网线。Bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多。

    Bridge作用

    Veth-Pair可以实现两个Network Namespace之间的通信,但是当需要在多个Network Namespace之间通信的时候,光靠Veth-Pair就显得有一些麻烦了,我们需要在Network Namespace创建很多个Veth才能和多个Network Namespace通信,我们可以把很多Veth-Pair绑定到Bridge上面,Network Namespace就能连通了多个Network Namespace,当需要通信的时候,Network Namespace只要往Bridge发报文,所有Veth-Pair全都可以收到报文信息。

    实战

    1. 创建一个br0的网桥,并设置上线;

      ip link add br0 type bridge
      ip link set dev br0 up
      ip addr
      
    2. 创建Veth-Pair;

      #创建3个 veth pair
      ip link add type veth
      ip link add type veth
      ip link add type veth
      
    3. 创建Network Namespace;

      #创建3个Network Namespace
      ip netns add net0
      ip netns add net1
      ip netns add net2
      
    4. 将Veth-Pair的一边挂到Network Namespace中,另一边挂到bridge上,并设IP地址;

      #配置net0
      ip link set dev veth1 netns net0
      ip netns exec net0 ip link set dev veth1 name eth0
      ip netns exec net0 ip addr add 10.0.1.1/24 dev eth0
      ip netns exec net0 ip link set dev eth0 up
      ip link set dev veth0 master br0
      ip link set dev veth0 up
      
      
      #配置net1
      ip link set dev veth3 netns net1
      ip netns exec net1 ip link set dev veth3 name eth0
      ip netns exec net1 ip addr add 10.220.1.2/24 dev eth0
      ip netns exec net1 ip link set dev eth0 up
      ip link set dev veth2 master br0
      ip link set dev veth2 up
      
      
      #配置net2
      ip link set dev veth5 netns net2
      ip netns exec net2 ip link set dev veth5 name eth0
      ip netns exec net2 ip addr add 10.220.1.3/24 dev eth0
      ip netns exec net2 ip link set dev eth0 up
      ip link set dev veth4 master br0
      ip link set dev veth4 up
      
    5. 给br0设置IP;

      ip link set dev br0 down
      ip addr add 10.220.1.0/24 dev br0
      ip link set dev br0 up
      ip netns exec net0 ping -c 10.220.1.3
      
    6. 解决ping不通的问题,因为系统为bridge开启了iptables功能,导致所有经过br0的数据包都要受iptables里面规则的限制,我在虚拟机已经安装了Docker,Docker将iptables里面filter表的FORWARD链的默认策略设置成了drop,于是所有不符合docker规则的数据包都不会被forward,导致你这种情况ping不通;

      解决办法有两个:

      第一个就是关闭系统bridge的iptables功能,这样数据包转发就不受iptables影响了:

      echo0 >/proc/sys/net/bridge/bridge-nf-call-iptables;
      

      第二就是为br0添加一条iptables规则,让经过br0的包能被forward:

       iptables -A FORWARD -i br0 -j ACCEPT;
      
    7. 验证;

    以上涉及的Linux技术其实已经和ocker底层的网络技术有些类似,这里先整体介绍一下,下篇我们对Docker的网络进行探究一下。

  • 相关阅读:
    Python3-元组
    Python3-列表
    Python3-字符串
    Python3-for循环机制
    Python3-初识
    优先队列——priority queue
    单调队列 —— 滑动窗口
    SDNU_ACM_ICPC_2021_Winter_Practice_7th [个人赛]
    博弈论入门(论和威佐夫、巴什、尼姆打牌被吊打是什么感受(╥﹏╥)
    字符串最大最小表示法
  • 原文地址:https://www.cnblogs.com/johnvwan/p/15623475.html
Copyright © 2011-2022 走看看