linux 虚拟网络设备之vlan

我们通过一个网桥两个设备对,来连接两个网络名字空间,每个名字空间中创建两个vlan

借助vconfig来配置vlan:

 

查看一下vlan配置:

 

现在,我们可以分别在两个名字空间来ping另外一个名字空间的两个IP,虽然两个IP都能ping通,但是使用的源IP是不同的,走的vlan也是不同的,我们可以在veth01/veth10/veth02/veth20/br-test-vlan 任意一个上抓包,会看到vlan信息:

 

如果试图从veth10.3001 去ping 172.16.30.22 是不能通的,因为是不同的vlan呀:

 

不适用vconfig的解法:

另: vlan 一般以  设备名.vlanid 来命名,不过并非强制,如下命名为 vlan3003也是没问题的

注意:一个主设备上相同vlan好的子设备最多只能有一个

 

所以,正常来讲,一般是这样的:

 

参考: http://network.51cto.com/art/201504/473419.htm

http://www.mamicode.com/info-detail-2357921.html

ceph 之 ceph-bluestore-tool

ceph-bluestore-tool 可以对bluestore 文件系统进行检查:

注意: 必须把对应的osd停掉才行

ceph 之 mon quorum操作

取消某个mon的法人资格:

恢复一个mon的法人资格

不幸的是,该命令卡死不动;甚至,如果期望提示enter补全都会卡死不动; 哪怕是4个mon,exit一个再tell回来也是卡死的,所以,tell命令似乎只能取消法人资格,不能恢复法人资格

 

方法2: 直接在需要恢复法人资格的daemon上执行如下命令

当while read 遇上ssh

为什么第二条命令输出的不是a b c三行?

改进:

这里把ssh的标准输入关闭了,结果就正常了,可见,原来不能输出三行是有ssh的标准输入导致的

再次验证如下:

这里比较清晰地说明了b、c被ssh给读走了

如果不想费这心思,完全可以别走管道:

 

有时候就是这样,能用简单明了的写法,最好别摆酷

 

非图片版:

 

vxlan 问题排查

现象:

openstack中创建的vpc网络中,虚拟机不能dhcp到IP地址,抓包分析如下:

这是openstack控制节点的网络相关信息,问题是: vxlan-60中一个虚机想要通过dhcp获取IP地址,现在dhcp的数据包可以通过eth0到达brqce4d2a54-44,抓包可以验证 :

但是vxlan-60上却抓不到dhcp数据包:

我觉得,到达了 brqce4d2a54-44 的vxlan数据包,如果vxlan id是60就直接转给vxlan-60 就是了,还可能被哪里的规则给拦截?问题都定位了这地步了,应该问题就出现在openstack-controller身上吧?不应该和其它机器有关系吧?(我不断祭出bridge fdb、brctl、ip等工具,浪费了有半天的时间)

后来,在我都试图想重启openstack-controller的时候,我决定分别在两个compute上创建两个机器,如果两个机器之间能够通信,则说明openstack-controller 的问题,否则,就不是openstack-controller的问题; 测试发现,两个机器不能通信,我才把重点放在了compute节点;

compute节点网络架构:

话说,这个网络和官方指导架构或者书本上指导的架构都不一样; 正常来讲,把bond0 添加到 /etc/neutron/plugins/ml2/linuxbridge_agent.ini 中就可以了,也不会出现今天的问题,因为最初是这样的,我测试vpc功能都是OK的;

加入我把bond0给了neutron,则neutron会将bond0的IP转移给brqce4d2a54-44 , 由于机器有限,我需要在这些compute节点上起ceph node,ceph node也通过虚拟机提供存储服务(如上图的vnet0),如果让vnet0桥接到brqce4d2a54-44 上,总感觉不大好,于是,便有了上述的网络架构;

既然  /etc/neutron/plugins/ml2/linuxbridge_agent.ini  里面配置成了veth_neutron ,那么 /etc/neutron/plugins/ml2/linuxbridge_agent.ini 里面的 local_ip 也应该修改为 veth_neutron 的IP,不是吗?(当然不是,错就错在这儿了),于是我就这么改了

 

 

因为vxlan-60 的 dev 是brqce4d2a54-44 ,数据只有先到达brqce4d2a54-44  才可能进入vxlan-60 ;

我发现,进入的vxlan数据包首先是要走到bond0的,然后走到br0,我期望能通过veth_br0 到 veth_neutron , 再到 brqce4d2a54-44 ,然后再到vxlan-60, 然而,实际情况是,vxlan数据包根本不进入veth_br0; 我猜测,很可能内核已经在分析vxlan数据包了,该给谁给谁,没人要就丢掉呗; 然而,vxlan-60是base在brqce4d2a54-44  上的,没有base在br0上; 如果让vxlan-60 base在br0上是不是就可以了呢?

关于vxlan-60 base在哪个设备是通过/etc/neutron/plugins/ml2/linuxbridge_agent.ini  里面的local_ip 来决定的,和 physical_interface_mappings 是不必相同的。

修改后,重启 neutron-linuxbridge-agent.service , 重新创建vpc, 问题解决。

 

思考:

为什么vxlan的目的IP是brqce4d2a54-44, 而实际却不能真正落到brqce4d2a54-44 上?

vxlan实践

vxlan 也能在单台机器上演示:

网络拓扑:

pic

执行命令:

  1. 创建两个网络名字空间:(相当于做了两个虚拟机)

     
  2. 创建一个设备对儿:

     
  3. 将设备对分别添加到两个名字空间:

     
  4.  进入名字空间进行配置:

     
  5. 进入另外一个名字空间进行类似配置:

     
  6. 通过ip link show veth01   和ip link show veth10, 查到:
    veth01 Mac: fe:ea:f2:aa:1f:fc
    veth0 Mac: ee:b4:c4:3f:b3:2b
  7. 添加转发表:
  8. 验证:

     
  9. 注意:我们在各自的名字空间内ping不到自己的IP,因为我们没有启动lo,启动lo就可以ping到自己了

 

参考: http://tech.mytrix.me/2017/04/vxlan-overlay-in-linux-bridge/

watch + ssh 远程top

通过ssh远程top一次ceph用户的所有进程:

如果想查看多次(3次):

如果想以本机的top效果查看,则可以:

其实,根本不用watch :

但是如果想在一个机器上查看2个机器的top呢?

如果如果想在一个机器上查看4个机器的top呢?写4遍ssh好繁琐:

分割线的打印,参考: https://stackoverflow.com/questions/5349718/how-can-i-repeat-a-character-in-bash

 

cloud-init 源码阅读

网络初始化:

/usr/lib/python2.7/site-packages/cloudinit/stages.py:

 

分析:

  1. 每次都查找网络配置
  2. 如果找到配置,则 self.distro.apply_network_config_names(netcfg)
    1. 对于新机器,则 self.distro.apply_network_config(netcfg, bring_up=bring_up)  ,包括
      1.  写 ifcfg-eth0 配置文件
      2. if bring_up ,则,启动该网络设备

 

/usr/lib/python2.7/site-packages/cloudinit/stages.py:

分析:

先尝试从三个不同的地方获取网络配置(注意,这里是有优先级的):cmdline、system_cfg、datasource中的network_config; 只要其中一个地方明确禁用网络或存在配置则返回;

如果没有找到任何配置,则进入预定义的配置逻辑net/__init__.py: net.generate_fallback_config() :

 

分析:

  1. lo 排除在外
  2. list目录 SYS_CLASS_NET = “/sys/class/net/”  ,可以找到多个网络设备,如:
  3. 分析现有的网络设备,看看哪个最适合连网
    “””Determine which attached net dev is most likely to have a connection and
    generate network state to run dhcp on that interface”””

    1. 如果是veth开头的,认为是设备对,不考虑
    2. 如果存在 /sys/class/net/{$name}/bridge  则认为是(肯定是)网桥, 也不考虑
    3. 如果是插着线(carrier)的,则加入可以考虑的接口列表,如何判断是否插着线呢?
      参考:

       

      简单说就是: cat /sys/class/net/{$name}/carrier    如果结果是整数,则是插着线呢,否则就没插线,如下:

      注意:
      插着线的意思是,线的两端都是加了电的网络设备,即: 数据链路层是UP的;
      有些网络设备的该文件是不能cat的,如:

    4. 如果cat /sys/class/net/{$name}/dormant  是一个大于0的整型值,也可以考虑
    5. 参考文件 /sys/class/net/{$name}/operstate  ,这里记录了设备的状态,如果状态是: ‘dormant’, ‘down’, ‘lowerlayerdown’, ‘unknown’, 也可以考虑
    6. 最后,对可以考虑的列表进行排序;排在前面的优先考虑; 不过还有个例外,程序里面定义了一个默认的网络设备 DEFAULT_PRIMARY_INTERFACE,就是 eth0, 排序后被特意添加到了列表的最前面; 不出意外的话,后续胜出的基本就是eth0了
  4. 根据上面得到的列表,查找设备的mac地址,只要有一个设备有mac地址,该设备就胜出了,后面的就没戏了
  5. 最后,返回网络配置

     

总结:

分析可知,如果不对网络进行特殊配置的话,cloud-init只能帮我们配置一个网卡; 一般来讲,大部分需求已经满足了。

我们如果看 cloud-init ( /var/log/cloud-init.log )的日志的话,会发现,在多个网卡的时候,虽然其他网卡的信息也被read了,但是最终却没有得到和eth0相同的待遇,现在也就真相大白了

 

 

 

堆栈:

关于cmdline的获取方法: (util.py)

  1. 容器的话,cat /proc/1/cmdline
  2. 非容器的话, cat /proc/cmdline
  3. 结果:

变化的mac地址

 

一个bridge诞生时,会有一个mac地址;当向bridge上addif  veth2时,bridge的mac地址就跟随了veth2的mac地址,难道br0就不能固定一个mac地址吗?

可以的:

默认情况下,bridge总是跟随port中mac地址最小的那个port的mac地址,如果不想让mac地址总是变化,则可以设置bridge的首选mac地址,方法就是显式地给bridge设置mac地址:

参考:

http://blog.csdn.net/fanwenbo/article/details/2131193