技术标签: 网络 linux 【计算机组成原理&操作系统】 docker
《Linux 虚拟网络设备 veth-pair》 linux基础
《Linux虚拟网络设备之veth(arp incomplete)》
【Linux 】查看veth-pair对的映射关系
Docker网络(veth、网桥、host、container、none) docker上网络概述
Docker的网络配置 1 初识 docker 精讲
Docker的网络配置 2 配置 DNS和主机名
Docker的网络配置 3 user-defined网络
Docker的网络配置 4 内嵌的DNS server
Docker的网络配置 5 将容器与外部世界连接
Docker的网络配置 6 docker-proxy
【云原生】网络之桥接(网卡对) openshift下的网络桥接模式
veth是虚拟以太端口
,总是成对出现
成对出现
的,另一端两个设备彼此相连下面这张关系图很清楚的说明了veth设备的特点:
+----------------------------------------------------------------+
| |
| +------------------------------------------------+ |
| | Newwork Protocol Stack | |
| +------------------------------------------------+ |
| ↑ ↑ ↑ |
|..............|...............|...............|.................|
| ↓ ↓ ↓ |
| +----------+ +-----------+ +-----------+ |
| | eth0 | | veth100 | | veth199 | |
| +----------+ +-----------+ +-----------+ |
|192.168.1.11 ↑ ↑ ↑ |
| | +---------------+ |
| | 192.168.2.11 192.168.2.1 |
+--------------|-------------------------------------------------+
↓
Physical Network
上图中,我们给物理网卡eth0配置的IP为192.168.1.11, 而veth100和veth1的IP分别是192.168.2.11和192.168.2.1。
标准语法 :
ip link add veth0
type veth peer name veth1
:
34: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 1a:f5:90:11:07:13 brd ff:ff:ff:ff:ff:ff
35: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ce:5d:7f:77:f1:ef brd ff:ff:ff:ff:ff:ff
注意: 当你不添加 peer name veth1
时,会自动添加 peer name vethxxx
,其中 vethxxx 是数字自动累加的,保证成对出现
ip link add veth0 type veth
查看,仍然会生成一对:
37: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
38: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
甚至,你可以直接 不指定任何veth的名称,仍然可以生成一对,其名称是 vethxxx自动累加的:
ip link add type veth // 不指定任何veth的名称
我们通过示例的方式来一步一步的看看veth设备的特点。
先通过ip link命令添加veth100和veth1,然后配置veth100的IP,并将两个设备都启动起来
dev@debian:~$ sudo ip link add veth100 type veth peer name veth199 '创建一个veth类型的网卡'
此时通过 ip a进行查看,发现多了2个网卡:
[root@paas-controller-3:R50s:/proc/24415]$ ip a|grep veth100
162: veth199@veth100: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
163: veth100@veth199: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
注意:这里面veth100 veth199 在同一个空间,因此 可以直接看到veth199@veth100 这种配对的关系,但是当你移到其它空间时,就不那么直观了,可能是类似这样 的 veth100@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000,具体 怎么映射的,可以参见 【Linux 】查看veth-pair对的映射关系
给其中的一个虚拟网卡设置ip:
dev@debian:~$ sudo ip addr add 192.168.2.11/24 dev veth100
dev@debian:~$ sudo ip link set veth100 up
dev@debian:~$ sudo ip link set veth199 up
这里不给veth1设备配置IP的原因就是想看看在veth1没有IP的情况下,veth100收到协议栈的数据后会不会转发给veth1。
ping一下192.168.2.1,由于veth1还没配置IP,所以肯定不通:
dev@debian:~$ ping -c 4 192.168.2.1
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
From 192.168.2.11 icmp_seq=1 Destination Host Unreachable
From 192.168.2.11 icmp_seq=2 Destination Host Unreachable
From 192.168.2.11 icmp_seq=3 Destination Host Unreachable
From 192.168.2.11 icmp_seq=4 Destination Host Unreachable
--- 192.168.2.1 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3015ms
pipe 3
但为什么ping不通呢?是到哪一步失败的呢?
先看看抓包的情况,从下面的输出可以看出,veth100和veth1收到了同样的ARP请求包,但没有看到ARP应答包:
dev@debian:~$ sudo tcpdump -n -i veth100
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth100, link-type EN10MB (Ethernet), capture size 262144 bytes
20:20:18.285230 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 'ARP请求包'
20:20:19.282018 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:20.282038 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:21.300320 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:22.298783 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:23.298923 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
dev@debian:~$ sudo tcpdump -n -i veth199
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth199, link-type EN10MB (Ethernet), capture size 262144 bytes
20:20:48.570459 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 'ARP请求包'
20:20:49.570012 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:50.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:51.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:52.569988 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
20:20:53.570833 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28
为什么会这样呢?了解ping背后发生的事情后就明白了:
1.ping进程构造ICMP echo请求包,并通过socket发给协议栈,
2.协议栈根据目的IP地址和系统路由表,知道去192.168.2.1的数据包应该要由192.168.2.11口出去
3.由于是第一次访问192.168.2.1,且目的IP和本地IP在同一个网段,所以协议栈会先发送ARP出去,询问192.168.2.1的mac地址
4.协议栈将ARP包交给veth100,让它发出去
5.由于veth100的另一端连的是veth1,所以ARP请求包就转发给了veth1
6.veth1收到ARP包后,查看协议栈
7.协议栈一看自己的设备列表,发现本地没有192.168.2.1这个IP,于是就丢弃了该ARP请求包,这就是为什么只能看到ARP请求包,看不到应答包的原因
给veth1也配置上IP
dev@debian:~$ sudo ip addr add 192.168.2.1/24 dev veth199
再ping 192.168.2.1成功(由于192.168.2.1是本地IP,所以默认会走lo设备,为了避免这种情况,这里使用ping命令带上了-I参数,指定数据包走指定设备),假设此时的ping次数即为Pn
dev@debian:~$ ping -c 4 192.168.2.1 -I veth100
PING 192.168.2.1 (192.168.2.1) from 192.168.2.11 veth100: 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.050 ms
--- 192.168.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.032/0.046/0.055/0.009 ms
注意:对于非debian系统,这里有可能ping不通,主要是因为内核中的一些ARP相关配置导致veth1不返回ARP应答包,如ubuntu上就会出现这种情况,解决办法如下:
如果不设置,会导致192.168.2.1在arp缓存中状态为 arp incomplete。
或者 把其中veth199加入到一个其他的命名空间。然后再ping ,参见 章节3
root@ubuntu:~# echo 1 > /proc/sys/net/ipv4/conf/veth199/accept_local
root@ubuntu:~# echo 1 > /proc/sys/net/ipv4/conf/veth100/accept_local
root@ubuntu:~# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
root@ubuntu:~# echo 0 > /proc/sys/net/ipv4/conf/veth100/rp_filter
root@ubuntu:~# echo 0 > /proc/sys/net/ipv4/conf/veth199/rp_filter
再来看看抓包情况(假设此时的ping次数即为Pn+1),我们在veth100和veth1上都看到了ICMP echo的请求包,但为什么没有应答包呢?上面不是显示ping进程已经成功收到了应答包吗?
由于Pn次 操作让ARP缓存产生一条新的记录,此时再抓包,就看不到ARP消息了
dev@debian:~$ sudo tcpdump -n -i veth100
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth100, link-type EN10MB (Ethernet), capture size 262144 bytes
20:23:43.113062 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 1, length 64
20:23:44.112078 IP 192.168.2.11
> 192.168.2.1: ICMP echo request, id 24169, seq 2, length 64
20:23:45.111091 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 3, length 64
20:23:46.110082 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 4, length 64
dev@debian:~$ sudo tcpdump -n -i veth199
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth199, link-type EN10MB (Ethernet), capture size 262144 bytes
20:24:12.221372 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 1, length 64
20:24:13.222089 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 2, length 64
20:24:14.224836 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 3, length 64
20:24:15.223826 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 4, length 64
看看数据包的流程就明白了:
1ping进程构造ICMP echo请求包,并通过socket发给协议栈,
2由于ping程序指定了走veth100,并且本地ARP缓存里面已经有了相关记录,所以不用再发送ARP出去,协议栈就直接将该数据包交给了veth100
3由于veth100的另一端连的是veth1,所以ICMP echo请求包就转发给了veth1
4veth1收到ICMP echo请求包后,转交给另一端的协议栈
5协议栈一看自己的设备列表,发现本地有192.168.2.1这个IP,于是构造ICMP echo应答包,准备返回
为啥协议栈发送reply消息不是原路返回的?是因为同主机优先从lo走吗,并且没有-i veth1指定原路返回?
为啥是协议栈 发送reply消息,而不是veth1发送reply消息?
6协议栈查看自己的路由表,发现回给192.168.2.11的数据包应该走lo口,于是将应答包交给lo设备
7lo接到协议栈的应答包后,啥都没干,转手又把数据包还给了协议栈(相当于协议栈通过发送流程把数据包给lo,然后lo再将数据包交给协议栈的接收流程)
8协议栈收到应答包后,发现有socket需要该包,于是交给了相应的socket
9这个socket正好是ping进程创建的socket,于是ping进程收到了应答包
抓一下lo设备上的数据,发现应答包确实是从lo口回来的:
dev@debian:~$ sudo tcpdump -n -i lo
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
20:25:49.590273 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 1, length 64
20:25:50.590018 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 2, length 64
20:25:51.590027 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 3, length 64
20:25:52.590030 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 4, length 64
ping 192.168.2.0/24网段的其它IP失败,ping一个公网的IP也失败:
dev@debian:~$ ping -c 1 -I veth100 192.168.2.2
PING 192.168.2.2 (192.168.2.2) from 192.168.2.11 veth100: 56(84) bytes of data.
From 192.168.2.11 icmp_seq=1 Destination Host Unreachable
--- 192.168.2.2 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
dev@debian:~$ ping -c 1 -I veth100 baidu.com
PING baidu.com (111.13.101.208) from 192.168.2.11 veth100: 56(84) bytes of data.
From 192.168.2.11 icmp_seq=1 Destination Host Unreachable
--- baidu.com ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
从抓包来看,和上面第一种veth1没有配置IP的情况是一样的,ARP请求没人处理:
dev@debian:~$ sudo tcpdump -i veth199
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth199, link-type EN10MB (Ethernet), capture size 262144 bytes
02:25:23.223947 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28
02:25:24.224352 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28
02:25:25.223471 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28
02:25:27.946539 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28
02:25:28.946633 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28
02:25:29.948055 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28
$ sudo ip link add veth100 type veth peer name veth199 ‘创建一个veth类型的网卡’
$ sudo ip addr add 192.168.2.11/24 dev veth100
$ sudo ip link set veth100 up
ip netns add netns199 //新建一个命名空间
ip link set veth199 netns netns199 //把veth199 加入到这个新建的空间
ip netns exec netns199 ip link set dev veth199 up //启动这个网卡
ip netns exec netns199 ip a a 192.168.2.12/24 dev veth199 //添加地址
ip netns exec netns199 ip a //查看网卡
在主机默认空间上 # ping 192.168.2.12
从上面的介绍中可以看出,从veth100设备出去的数据包,会转发到veth1上,如果目的地址是veth1的IP的话,就能被协议栈处理,否则连ARP那关都过不了,IP forward啥的都用不上,所以不借助其它虚拟设备的话,这样的数据包只能在本地协议栈里面打转转,没法走到eth0上去,即没法发送到外面的网络中去。
下一篇将介绍Linux下的网桥,到时候veth设备就有用武之地了。
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数