美文网首页DockerLinuxk8s
Linux虚拟网络技术

Linux虚拟网络技术

作者: 王勇1024 | 来源:发表于2019-05-20 10:55 被阅读0次

Network Namespace

Network Namespace 是 Linux 内核提供的功能,是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己都在独立的网络中。而且不同Network Namespace的资源相互不可见,彼此透明。

这篇文章介绍 Network Namespace 的基本概念和用法。这篇文件借助ip命令来完成各种操作。ip命令来自于iproute2安装包,一般系统会默认安装,如果没有的话,读者自行安装。

注意:ip命令修改网络配置时需要 sudo 权限。

可以通过ip netns命令完成对Network Namespace 的相关操作,可以通过ip netns help查看命令帮助信息:

$ ip netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
       ip netns list-id

默认情况下,Linux系统中是没有任何 Network Namespace的,所以ip netns list命令不会返回任何信息。

创建Network Namespace

下面,我们通过命令创建一个名为ns1的命名空间:

$ ip netns add ns1
$ ip netns list
ns1

新创建的 Network Namespace 会出现在/var/run/netns/目录下。如果相同名字的 namespace 已经存在,命令会报Cannot create namespace file "/var/run/netns/ns1": File exists的错误。

对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。

操作Network Namespace

ip命令提供了ip netns exec子命令可以在对应的 Network Namespace 中执行命令。

  1. 查看新创建 Network Namespace 的网卡信息
$ ip netns exec ns1 ip addr
sudo: unable to resolve host zormshogu
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到,新创建的Network Namespace中会默认创建一个lo回环网卡,此时网卡处于关闭状态。此时,尝试去 ping 该lo回环网卡,会提示Network is unreachable

$ ip netns exec ns1 ping 127.0.0.1
connect: Network is unreachable

通过下面的命令启用lo回环网卡:

ip netns exec ns1 ip link set lo up

然后再次尝试去 ping 该lo回环网卡:

$ ip netns exec ns1 ping -c 3 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.048 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.031 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.029/0.036/0.048/0.008 ms

veth

veth设备的特点

  • veth和其它的网络设备都一样,一端连接的是内核协议栈;
  • veth设备是成对出现的,另一端两个设备彼此连接;
  • 一个设备收到协议栈的数据发送请求后,会将数据发送到另一个设备上去。
+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|              ↑               ↑               ↑                 |
|..............|...............|...............|.................|
|              ↓               ↓               ↓                 |
|        +----------+    +-----------+   +-----------+           |
|        |   eth0   |    |   veth0   |   |   veth1   |           |
|        +----------+    +-----------+   +-----------+           |
|192.168.1.11  ↑               ↑               ↑                 |
|              |               +---------------+                 |
|              |         192.168.2.11     192.168.2.1            |
+--------------|-------------------------------------------------+
               ↓
         Physical Network

上图中,我们给物理网卡eth0配置的IP为192.168.1.11, 而veth0和veth1的IP分别是192.168.2.11和192.168.2.1。

veth pair

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


veth pair

创建veth pair

$ sudo ip link add type veth
$ ip addr
61: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e6:39:e1:e0:3a:a0 brd ff:ff:ff:ff:ff:ff
62: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether be:41:49:42:23:6a brd ff:ff:ff:ff:ff:ff

可以看到,此时系统中新增了一对veth pair,将veth0和veth1两个虚拟网卡连接了起来,此时这对 veth pair 处于”未启用“状态。

如果我们想指定 veth pair 两个端点的名称,可以使用下面的命令:

ip link add vethfoo type veth peer name vethbar

实现Network Namespace间通信

下面我们利用veth pair实现两个不同的 Network Namespace 之间的通信。刚才我们已经创建了一个名为ns1的 Network Namespace,下面再创建一个信息Network Namespace,命名为ns2

$ ip netns add ns2
$ ip netns list
ns2
ns1

然后我们将veth0加入到ns1,将veth1加入到ns2,如下所示:

$ ip link set veth0 netns ns1
$ ip link set veth1 netns ns2

然后我们分别为这对veth pair配置上ip地址,并启用它们:

$ ip netns exec ns1 iplink set veth0 up
$ ip netns exec ns1 ip addr add 10.0.1.1/24 dev veth0
$ ip netns exec ns2 iplink set veth1 up
$ ip netns exec ns2 ip addr add 10.0.1.2/24 dev veth1

查看这对veth pair的状态

$ ip netns exec ns1 ip addr
61: veth0@if62: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:39:e1:e0:3a:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 10.0.1.1/24 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e439:e1ff:fee0:3aa0/64 scope link
       valid_lft forever preferred_lft forever

$ ip netns exec ns2 ip addr
62: veth1@if61: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:41:49:42:23:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.1.2/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::bc41:49ff:fe42:236a/64 scope link
       valid_lft forever preferred_lft forever

从上面可以看出,我们已经成功启用了这个veth pair,并为每个veth设备分配了对应的ip地址。我们尝试在ns2中访问ns1中的ip地址:

$ ip netns exec ns2 ping -c 3 10.0.1.1
sudo: unable to resolve host zormshogu
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=0.037 ms

--- 10.0.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.035/0.054/0.091/0.026 ms

可以看到,veth pair成功实现了两个不同Network Namespace之间的网络交互。

网桥

veth pair打破了 Network Namespace 的限制,实现了不同 Network Namespace 之间的通信。但veth pair有一个明显的缺陷,就是只能实现两个网络接口之间的通信。
如果我们想实现多个网络接口之间的通信,就可以使用下面介绍的网桥(Bridge)技术。
简单来说,网桥就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。

网桥的工作原理

网桥的工作过程

注意:和 bridge 有关的操作也可以使用命令 brctl,这个命令来自 bridge-utils 这个包

bridge-utils安装

  1. CentOS
sudo yum install -y bridge-utils
  1. Ubuntu
sudo apt-get install bridge-utils

创建网桥

$ ip link add br0 type bridge
$ ip link set dev br0 up
网桥网络拓扑图

iptables

netfilter

相关文章

  • Kubernetes网络实现

    在《Linux虚拟网络技术》这篇文章中我们已经详细介绍了Linux虚拟网络技术,在《Docker网络实现》这篇文章...

  • Docker网络实现

    实现原理 Docker使用Linux桥接(参考《Linux虚拟网络技术》),在宿主机虚拟一个Docker容器网桥(...

  • Linux虚拟网络技术

    Network Namespace Network Namespace 是 Linux 内核提供的功能,是实现网络...

  • k8s基础

    endpoint、虚拟二层网络技术、nodeSelector、label、controller、deploymen...

  • go学习资源

    书 《The Garbage Collection Handbook》《深入理解linux网络技术内幕》《redi...

  • Linux安装及其静态IP配置,安装JDK与Tomcat

    Linux虚拟机安装及静态IP配置 环境 新建Linux虚拟电脑 Linux虚拟机系统安装 静态IP配置 安装JD...

  • 操作系统内存

    Linux 内存 一、虚拟内存 这个虚拟内存指的是“进程的虚拟内存”,或者说是虚拟地址空间,注意与” Linux ...

  • 进程虚拟内存

    Linux虚拟内存空间分布Linux虚拟内存空间描述linux进程虚拟内存 .text(代码段)可执行文件加载到内...

  • Neutron学习笔记1--基本概念

    Neutron学习笔记 基本概念 1.涉及的Linux网络技术 bridge:网桥,Linux中用于表示一个能连接...

  • 用虚拟机技术学习Linux

    Linux教程 用虚拟机技术学习Linux 虚拟化技术简介 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计...

网友评论

    本文标题:Linux虚拟网络技术

    本文链接:https://www.haomeiwen.com/subject/yzxczqtx.html