跳转至

首页

在LinuxBridge/OVS中使用VxLAN组网以及创建VTEP

这是一篇入门文章,帮助初学者理清VxLAN的基本原理与使用,ovs只是工具,新版本内核也可使用ip命令直接创建。

本篇内容分为两篇,第一篇是使用简单VxLAN通道网络,第二篇会接入OVS模拟的VTEP设备。

一、使用VxLAN通道

原理是在网络命名空间上(仅测试环境),创建对端接口(peer/patch,虚拟化环境中即是虚拟机veth设备接口与OVS tun接口),以通过VxLAN通道与彼此通信。

host1拥有物理接口eth0(192.168.0.101),host2拥有物理接口eth0(192.168.0.102),两者在同一局域网中。

实验拓扑如下图。

在host1上创建veth与对端接口,对端接口会与ovs网桥相连,其中veth1代表虚拟机接口(地址为10.0.0.1),veth1p代表与ovs网桥相连的接口。

添加网络命名空间

ip netns add ns-host1

添加对端接口

ip link add name veth1 type veth peer name veth1p

将虚拟机接口放入命名空间

ip link set dev veth1 netns ns-host1

设置虚拟机接口IP

ip netns exec ns-host1 ifconfig veth1 10.0.0.1/24 up

添加ovs网桥

ovs-vsctl add-br ovs-vxlan

将虚拟机的对端接口放入命名空间

ovs-vsctl add-port ovs-vxlan veth1p

激活接口

ip link set ovs-vxlan up ip link set veth1p up

同样在host2上创建。

ip netns add ns-host2 ip link add name veth1 type veth peer name veth1p ip link set dev veth1 netns ns-host2 ip netns exec ns-host2 ifconfig veth1 10.0.0.2/24 up

ovs-vsctl add-br ovs-vxlan ovs-vsctl add-port ovs-vxlan veth1p ip link set ovs-vxlan up ip link set veth1p up

然后,分别在host1与host2上创建VxLAN通道。

host1,将VxLAN的对端指向host2的eth0,VNI(VXLAN Network Identifier)为123。

ovs-vsctl add-port ovs-vxlan vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.168.0.102 options:key=123

host2,将VxLAN的对端指向host2的eth0。

ovs-vsctl add-port ovs-vxlan vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.168.0.101 options:key=123

这样即可完成最简单的OVS VxLAN实验准备,在host2上的虚拟机尝试ping host1上的虚拟机。

ip netns exec ns-host2 ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=1.74 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.734 ms 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.669 ms

这里可以将主机上的物理接口,比如eth1加入到ovs-vxlan中,从而使得与其相连的主机或者网络设备能够接入此VxLAN网络; 当添加第三台主机时,使用gre网络需要在每个gre0中设置remote_ip以两两相连,可以是星形或者环形(打开ovs生成树协议,ovs-vsctl set bridge ovs-gre stp_enable=true),而VxLAN网络

二、使用VxLAN通道连接虚拟机与物理机

三、接入OVS VTEP设备

参考: brctl与bridge命令对比 在oVirt中使用ovs gre网络 搭建基于Open vSwitch的VxLAN隧道实验 Connecting VMs Using Tunnels (Userspace)

虚拟化平台镜像去冗测试(opendedup)

OpenDedup,是一款开源去重文件系统,https://github.com/opendedup/sdfs,可以分布式,支持NFS、iSCSI等,感觉非常厉害,作者是Veritas的银堡(Sam Silverberg)。

Note

RedHat 7就开始带了VDO,但是还没测过。

可以去官网下载镜像,或者是笔者认为更加实用的NAS系统。

简单测试

目的是减少更多本地环境占用,使用opendedup测试。

  1. 首先测试我新闻服务器上的数据,以索引文件为主,经常变动,有大有小。

  2. 然后选择一款kvm软件平台。

安装:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
wget http://www.opendedup.org/downloads/sdfs-latest.deb
sudo dpkg -i sdfs-latest.deb

sudo su
echo "* hardnofile 65535" >> /etc/security/limits.conf
echo "* soft nofile 65535" >> /etc/security/limits.conf
exit
sudo mkfs.sdfs --volume-name=pool0 --volume-capacity=256GB
sudo mkdir /media/pool0 
sudo mount.sdfs pool0 /media/pool0/

数据拷贝进去后,原9.3GB索引数据降为8.5GB,效果不如想象中好。

可能原因:

sdfs提供了丰富的命令行选项,我没有使用,使用后可能会达到预期,比如更小的block。

"VMWare vCenter Converter SDK"

看到有公司专门做P2V、V2V,看了一下他们做了一些管理与适应各平台的边边角角工作,其技术原理是使用iotap或者VMWare Hypervisor层的 VAIO(感谢黄老师指导),从而达成CDP效果。

但这种技术的现在的缺点有两点:

  1. 没法支持任何的并行IO类应用,比如GPFS,Oracle RAC等;

  2. 本质上没法做consistent group。

更多具体内容可以查看Falcon与Commvault的相关专利,但这篇文章中2V的话还可以玩玩,那么我们试一下Converter SDK吧,也可直接下载Converter

下载最新的VMware vCenter Converter Standalone SDK 6.1

OpenStack、OpenDayLight、硬件SDN交换机集成

本文将讲述如何在OpenStack中使用SDN交换机,同时将OpenDayLight作为控制器,测试网络类型为vxlan。

本文适用目标为OpenStack Neutron组件,但理论上说包括任何可使用Neutron组件服务的云管理平台,比如oVirt。

在搭建Neutron时,笔者使用了现成的OpenStack单节点平台(可以参考https://github.com/lofyer/openstack-pxe-deployment,为防止出现3.1节末的错误,请使用Newton之前版本,我手贱部署了最新的),但为了减少搭建部署的麻烦,我会在后期尝试直接使用Neutron VM Appliance,方便集成(暂不确定是否影响性能)。

update 2017-05-27: 当前版本zstack的云路由功能vyos所实现的nfv软路由,笔者会考虑将Neutron移植到ZStack中,如此以来SDN即可将注意力主要放在Neutron。

update 2017-06-01: 加入盛科交换机,4.10内核的vtep可直接内核实现,参考Linux doc

update 2017-06-07: OpenStack版本从Ocata切换为Newton,实验3.3重新做了。

update 2017-06-12: 使用 Neutron appliance,并添加hooks,构建ZStack SDN解决方案,来源可自行搜索oVirt的相关资料

1. 环境准备

Pica8 P-5101 48+4*8 10Gb SDN交换机2台(吵地脑袋疼),OpenStack Ocata,OpenDayLight Lastest,管理机器。

mininet虚拟机地址:192.168.0.68

操作机地址:192.168.0.55

2. 架构方案与mininet环境模拟实验

拓扑使用miniedit制作,同时首选项中打开“Start CLI”,操作机“ssh -Y mininet@MININET_IP”后,运行“sudo ~/mininet/examples/mininet.py”以开启。

2.1. 基础模拟实验——交换机互联

文字描述可参考http://blog.scottlowe.org/2012/11/27/connecting-ovs-bridges-with-patch-ports/以及其中链接。

miniedit拓扑:

目的:连接两个交换机,使得h1与h3互通。

方法:将两个交换机上的一个端口组组成patch。

ovs-vsctl -- add-port s1 patch1 -- set interface patch1 type=patch options:peer=patch2 -- add-port s2 patch2 -- set interface patch2 type=patch options:peer=patch1

结果:

root@mininet-vm:/home/mininet# ovs-vsctl show 918037ec-b307-45d7-a75a-f1ac4337d135 Bridge "s1" Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure Port "s1" Interface "s1" type: internal Port "s1-eth2" Interface "s1-eth2" Port "s1-eth1" Interface "s1-eth1" Port "patch1" Interface "patch1" type: patch options: {peer="patch2"} Bridge "s2" Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure Port "s2-eth1" Interface "s2-eth1" Port "s2" Interface "s2" type: internal Port "patch2" Interface "patch2" type: patch options: {peer="patch1"} ovs_version: "2.0.2"

2.2. 进阶实验——流表

miniedit拓扑:同上。

目的:阻断h1与h2、h2与h3,使得h1与h3互通。

方法:下发如下流表。

阻断h2与h1/h3的协议封包: ovs-ofctl add-flow s1 in_port=2,arp,ip,nw_dst=10.0.0.1,actions=drop ovs-ofctl add-flow s1 in_port=2,arp,ip,nw_dst=10.0.0.3,actions=drop

结果

mininet> h1 ping h2 -c 2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. ^C --- 10.0.0.2 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1006ms

mininet> h2 ping h1 -c 2 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. ^C --- 10.0.0.1 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1000ms

mininet> h3 ping h2 -c 2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. ^C --- 10.0.0.2 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 999ms

mininet> h2 ping h3 -c 2 PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data. ^C --- 10.0.0.3 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1006ms

mininet> h1 ping h3 -c 2 PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data. 64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=2.37 ms 64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.561 ms

--- 10.0.0.3 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.561/1.466/2.372/0.906 ms mininet> h3 ping h1 -c 2 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=2.49 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.548 ms

--- 10.0.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.548/1.521/2.494/0.973 ms mininet>

root@mininet-vm:~# ovs-ofctl dump-flows s1 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=485.308s, table=0, n_packets=0, n_bytes=0, idle_age=485, ip,in_port=2,nw_dst=10.0.0.1 actions=drop cookie=0x0, duration=483.569s, table=0, n_packets=3, n_bytes=294, idle_age=183, ip,in_port=2,nw_dst=10.0.0.3 actions=drop cookie=0x0, duration=1715.894s, table=0, n_packets=93, n_bytes=3906, idle_age=202, arp,in_port=1,arp_tpa=10.0.0.2 actions=drop cookie=0x0, duration=715.43s, table=0, n_packets=4, n_bytes=392, idle_age=400, ip,in_port=1,nw_dst=10.0.0.2 actions=drop

3. 综合实验环境配置

首先来看一下实验拓扑:

图。。。。。。

SDN交换机 管理地址:192.168.0.250/24,

OpenStack Controller/Neutron IP: 192.168.0.80

OpenDayLight IP: 192.168.0.90 Web: http://192.168.0.90:8181/index.html

3.1. 设置OpenDayLight

在主机192.168.0.90上下载启动Boron版本OpenDayLight(其他版本未测试),然后解压运行(需要Java环境):

unzip distribution-karaf-0.5.3-Boron-SR3.zip cd distribution-karaf-0.5.3-Boron-SR3

启动ODL服务

./bin/start

本地安装并启动OpenvSwitch以作测试

yum localinstall -y https://repos.fedorapeople.org/repos/openstack/openstack-ocata/rdo-release-ocata-3.noarch.rpm systemctl enable openvswitch systemctl start openvswitch ovs-vsctl set-manager tcp:192.168.0.90:6640

进入客户端

./bin/client

安装netvirt与dlux界面,其中yangman为包管理器UI

opendaylight-user@root> feature:install odl-netvirt-openstack odl-dlux-all odl-dlux-yangman odl-mdsal-apidocs odl-netvirt-ui

然后访问http://192.168.0.90:8181/index.html,用户密码为admin/admin,可以看到我们刚刚添加的本地OVS。

3.3. OpenStack与OpenDayLight集成

首先要清除原有的实例和neutron网络。

实例

openstack server list +--------------------------------------+-----------+---------+------------+-------------+------------------------------------------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+-----------+---------+------------+-------------+------------------------------------------------------+ | d45b1646-b559-4d6d-963c-af3da205aa36 | instance3 | SHUTOFF | - | Shutdown | flat-ens39=192.168.0.108; sharednet1=192.168.118.203 | +--------------------------------------+-----------+---------+------------+-------------+------------------------------------------------------+

openstack server delete instance3

网络

openstack subnet list +--------------------------------------+-------------+--------------------------------------+------------------+ | ID | Name | Network | Subnet | +--------------------------------------+-------------+--------------------------------------+------------------+ | b0acb3ad-22d4-491c-94e7-488aca906398 | flat-subnet | b8f95552-9a45-49ae-b080-2e0041d4b2a0 | 192.168.0.0/24 | | c066992d-294d-4cd6-a3fb-0386619922c7 | subnet1 | 5ac25e6f-bf49-4217-abbc-11bf171c0a3e | 192.168.118.0/24 | +--------------------------------------+-------------+--------------------------------------+------------------+

openstack router list +------------------------------+-------------------+--------+-------+-------------+-------+------------------------------+ | ID | Name | Status | State | Distributed | HA | Project | +------------------------------+-------------------+--------+-------+-------------+-------+------------------------------+ | 78507b26-38f0-4b4a- | router-flat-ens39 | ACTIVE | UP | False | False | de2aea51161642759a687b5768b2 | | a3c6-13d15c4f9665 | | | | | | 3b7e | +------------------------------+-------------------+--------+-------+-------------+-------+------------------------------+ ........

删除所有port、router、subnet后,再用如下命令检查一遍,应该为空

openstack port list

接下来,我们将控制节点(neutron管理节点)与计算节点的OVS交于ODL管理。 首先停止相应服务。

计算节点,如果与控制节点相同则优先运行此部分内容

systemctl stop neutron-openvswitch-agent systemctl disable neutron-openvswitch-agent systemctl stop neutron-l3-agent systemctl disable neutron-l3-agent

Neutron控制节点

systemctl stop neutron-server systemctl stop neutron-l3-agent

然后清空OVS数据库。

systemctl stop openvswitch rm -rf /var/log/openvswitch/* rm -rf /etc/openvswitch/conf.db systemctl start openvswitch

清空后可看到如下

ovs-vsctl show bdf45776-c7c2-4df4-9911-007e89b67bbe ovs_version: "2.6.1"

将其交予ODL管理。

ovs-vsctl set-manager tcp:192.168.0.90:6640

然后在控制节点与计算节点设置用来vxlan通信的本地端,这里只有一个节点192.168.0.80。

ovs-vsctl set Open_vSwitch . other_config:local_ip=192.168.0.80

设置好以后可以在节点上看到ODL自动创建了一个连接到ODL控制器的br-int。

ovs-vsctl show bdf45776-c7c2-4df4-9911-007e89b67bbe Manager "tcp:192.168.0.90:6640" is_connected: true Bridge br-int Controller "tcp:192.168.0.90:6653" is_connected: true fail_mode: secure Port br-int Interface br-int type: internal ovs_version: "2.6.1"

ovs-vsctl get Open_vSwitch . other_config

此时reloadODL界面,可以看到多了个OVS。

接下来让neutron使用ODL,我们首先需要在neutron控制节点上安装一个对应包。

对于将ODL放置于OS控制节点的同学可以参考如下内容以修改swift端口:

First, ensure that port 8080 (which will be used by OpenDaylight to listen for REST calls) is available. By default, swift-proxy-service listens on the same port, and you may need to move it (to another port or another host), or disable that service. It can be moved to a different port (e.g. 8081) by editing /etc/swift/proxy-server.conf and /etc/cinder/cinder.conf, modifying iptables appropriately, and restarting swift-proxy-service. Alternatively, OpenDaylight can be configured to listen on a different port, by modifying the jetty.port property value in etc/jetty.conf.

yum install -y python-networking-odl

修改/etc/neutron/plugins/ml2/ml2_conf.ini并添加内容。

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers opendaylight crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vxlan

ml2_conf_odl.ini中的设置无效且报错,可能是我姿势不对,原因是我忘了修改neutron-server的启动命令。

cat <> /etc/neutron/plugins/ml2/ml2_conf.ini [ml2_odl] url = http://192.168.0.90:8080/controller/nb/v2/neutron password = admin username = admin EOF

然后修改服务后端为ODL。

crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins odl-router crudini --set /etc/neutron/dhcp_agent.ini DEFAULT force_metadata True crudini --set /etc/neutron/dhcp_agent.ini ovs ovsdb_interface vsctl

重置neutron数据库并重启服务。

mysql -e "DROP DATABASE IF EXISTS neutron_ml2;" -uroot -p mysql -e "CREATE DATABASE neutron_ml2 CHARACTER SET utf8;" -uroot -p neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head systemctl start neutron-server

验证是否成功。

curl -u admin:admin http://192.168.0.90:8080/controller/nb/v2/neutron/networks { "networks" : [ ] }

最后在openstack中创建网络与实例。

neutron router-create router1 neutron net-create private neutron subnet-create private --name=private_subnet 10.10.5.0/24 neutron router-interface-add router1 private_subnet nova boot --flavor --image --nic net-id= test1 nova boot --flavor --image --nic net-id= test2

添加浮动IP。

ovs-vsctl set Open_vSwitch . other_config:provider_mappings=physnet1:eth1 neutron net-create public-net -- --router:external --is-default --provider:network_type=flat --provider:physical_network=physnet1 neutron subnet-create --allocation-pool start=10.10.10.2,end=10.10.10.254 --gateway 10.10.10.1 --name public-subnet public-net 10.10.0.0/16 -- --enable_dhcp=False neutron router-gateway-set router1 public-net

neutron floatingip-create public-net nova floating-ip-associate test1

在OpenStack O版中创建网络时ODL与OS分别出现如下错误。

ODL: 2017-06-03 11:27:10,768 | ERROR | pool-46-thread-1 | QosInterfaceStateChangeListener | 350 - org.opendaylight.netvirt.neutronvpn-impl - 0.3.3.Boron-SR3 | Qos:Exception caught in Interface Operational State Up event java.lang.IllegalArgumentException: Supplied value "tapd5e5b153-39" does not match required pattern "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\(" at com.google.common.base.Preconditions.checkArgument(Preconditions.java:145)[65:com.google.guava:18.0.0] at org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid.<init>(Uuid.java:55)[80:org.opendaylight.mdsal.model.ietf-yang-types-20130715:2013.7.15.9_3-Boron-SR3] at org.opendaylight.netvirt.neutronvpn.QosInterfaceStateChangeListener.add(QosInterfaceStateChangeListener.java:61)[350:org.opendaylight.netvirt.neutronvpn-impl:0.3.3.Boron-SR3] at org.opendaylight.netvirt.neutronvpn.QosInterfaceStateChangeListener.add(QosInterfaceStateChangeListener.java:27)[350:org.opendaylight.netvirt.neutronvpn-impl:0.3.3.Boron-SR3] at org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase\)DataTreeChangeHandler.run(AsyncDataTreeChangeListenerBase.java:136)[310:org.opendaylight.genius.mdsalutil-api:0.1.3.Boron-SR3] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[:1.8.0_131] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[:1.8.0_131] at java.lang.Thread.run(Thread.java:748)[:1.8.0_131]

OS: ERROR neutron.plugins.ml2.managers [req-8174eb6e-6a01-428e-9c3d-d9f115dfa36b - - - - -] Failed to bind port d5e5b153-390a-4129-babd-7work': None, 'id': u'f01e69c5-096e-4d01-a239-5dbe37005e9b', 'network_type': u'vxlan'}]

原因可能是版本传参变了,ODL没及时更新,但我不会Java,会也不想去改ODL,所以我推荐读者用个老版本的Neutron,比如M版、N版啥的。

3.4. OVS创建vtep

IP: 192.168.0.101

3.5. OpenStack与SDN交换机集成

在ODL结束以后,我们再来试一下OpenStack与SDN交换机的集成,与上一节相互独立,即一个全新的OpenStack Newton环境。

由于商业法务问题,我不会将Pica8的OpenStack插件源码全部放出来,另外放出来意义也不大,现有SDN交换机的同学可以直接向厂商索要。

/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/

Pica8交换机工作在OVS模式下,需要将neutron server与OVS Manager相连(管理网口),或许有其他方法。

首先将插件文件拷贝至/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/,目录结构如下。

/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/pica8/ ├── config.pyc ├── db.pyc ├── exceptions.pyc ├── init.pyc ├── mechanism_pica8.pyc ├── ml2_conf_pica8.ini ├── rpc.pyc └── vtep.ovsschema

修改/usr/lib/python2.7/site-packages/neutron-9.3.1-py2.7.egg-info/entry_points.txt添加neutron驱动。

... [neutron.ml2.mechanism_drivers] ... pica8 = neutron.plugins.ml2.drivers.pica8.mechanism_pica8:Pica8Driver ...

创建/etc/neutron/plugins/ml2/ml2_conf_pica8.ini,并添加如下内容。

[ml2_pica8]

(ListOpt) List of other VTEPs' IP address, either a software vtep or

other vendor's hardware vtep.

Example: vtep_list=10.0.0.100,10.0.0.101,10.0.0.102

vtep_list=192.168.0.101

(IntOpt) Sync interval in seconds between Neutron plugin and PicaOS.

This field defines how often the synchronization is performed.

This is an optional field. If not set, a value of 180 seconds

is assumed.

sync_interval = 60

Example: sync_interval = 60

openstack_version = newton

Example: openstack_version = kilo

PicOS Switch configurations.

Each switch to be managed by Openstack Neutron must be configured here.

Format:

[ml2_mech_pica_switch:192.168.0.250] =:,,... =: # =:project_name,,vni, # ...

ovsdb_port=

Example:

[ml2_mech_pica_switch:192.168.0.250]

te-1/1/1=physnet1:dev-1,dev-2,dev-3

te-1/1/2=physnet2:dev-4

te-1/1/3=physnet1:project_name,admin,vni,3535

ovsdb_port=6640

source_ip=192.168.0.80

修改/usr/lib/systemd/system/neutron-server.service文件,在${DAEMON_ARGS}字段添加pica8的引导配置,需要停止neutron-server服务并systemctl daemon-reload。

--config-file=/etc/neutron/plugins/ml2/ml2_conf_pica8.ini

修改/etc/neutron/plugins/ml2/ml2_conf.ini,如下。

type_drivers = vlan,vxlan project_network_types = vxlan mechanism_drivers = pica8,openvswitch

Make sure the is consistent in the following configuration

bridge_mappings=:br-ex network_vlan_ranges = :1:4094

安装python-ovs库。

yum install -y python-pip pip install ovs

运行如下命令创建pica8插件数据库动作。

neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini revision -m "add pica8 mechanism driver" --expand

在生成的/usr/lib/python2.7/site-packages/neutron/db/migration/alembic_migrations/versions/newton/expand/94ca4fc9191b_add_pica8_mechanism_driver.py文件中添加如下内容。

def upgrade(): op.create_table( 'pica8_interfaces_v2', sa.Column('id', sa.String(length=36), nullable=False, primary_key=True), sa.Column('switch', sa.String(length=36), nullable=False), sa.Column('interface', sa.String(10), nullable=False) ) op.create_table( 'pica8_vlan_allocations_v2', sa.Column('id', sa.String(length=36), nullable=False, primary_key=True), sa.Column('project_id', sa.String(length=255), nullable=False), sa.Column('network_id', sa.String(length=36), nullable=False), sa.Column('segmentation_id', sa.Integer, nullable=False), sa.Column('vlan_id', sa.Integer, nullable=False), sa.Column('vm_reference', sa.Integer, nullable=False, default=0), sa.Column('interface_id', sa.String(length=36), nullable=True), sa.ForeignKeyConstraint(['interface_id'], ['pica8_interfaces_v2.id'], ondelete='CASCADE') ) def downgrade(): op.drop_table('pica8_interfaces') op.drop_table('pica8_vlan_allocations_v2')

执行如下命令升级数据库(如果失败请将最后参数替换为head)。

neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade 94ca4fc9191b

重启服务。

systemctl restart openstack-nova-api systemctl restart neutron-server

物理主机接入配置。

Edit the file /etc/neutron/plugins/ml2/ml2_conf_pica8.ini to contain the following content: =:project_name,,vni, is the interface of Pica8 switch connected to the physical host < project_name > is the name of the project owning the physical host is the vxlan id of the project network the physical host connects to

miniedit使用 Pica8手册 ODL手册 OpenDaylight with Openstack Guide OpenStack with NetVirt Installing OpenStack and OpenDaylight using DevStack https://wiki.opendaylight.org//blog/images/5/59/CloudIntegrationwithOpenStackOVSDBNetVirt.pdf

再一个近期

最近把亚马逊购物车的几本书入了,目的是能够彻底掌握或者精通ABM建模中常用/不常用的模型。

把DataNote写完吧,今年。

另外我刚从亚马逊购入的书为:

Think Complexity: Complexity Science and Computational Modeling

Agent-Based and Individual-Based Modeling: A Practical Introduction

Agent-based Models of the Economy: From Theories to Applications

Agent-Based Modelling in Economics

An Introduction to Agent-Based Modeling: Modeling Natural, Social, and Engineered Complex Systems with NetLogo (MIT Press)

Thinking in Systems: A Primer

一种应用于云平台负载的PID非线性控制系统设计

本文的实现效率尚有待考证,极有可能沦为扯淡文,但如果在网络资源部分可以快速应用测试。

众所周知,很多计算机系统里的设计都可以描述为线性模型,但正如金融系统的发展,计算机系统直接面向大众以后,也会呈现出非线性的特征,比如典型的DDoS即是在系统设计之外。接下来,笔者将使用自控知识来设计一种自适应负载的云计算控制器,不仅适用于计算、也会适用于网络、存储等服务资源。

以OpenStack平台的计算(虚拟机)为例,当用户的计算需求被量化后,那么我们就能根据其需求直接给出相应数量的计算节点。假如用户的计算需求是变化的,其值为R,且我们的程序员也是个直肠子,给出相应的计算能力为C,那么他设计的程序很有可能就是这个公式:

N=10, R=nN, C=(n+2)N

每台虚拟机的计算能力N为10,虚拟机数量为n。

可以看出他给了两台的冗余量,啊哈,还不错。所以他期望的场景应该是这样的。

其中黄色为实际需求,蓝色为平台提供,绿色为虚拟机数量。

但是,假如需求呈现出短时间大量波动的话,比如下图。

这个时候事情就不是那么美妙了,平台在即时响应的同时,伴随着大量虚拟机的上线/下线,从而造成一定的资源请求拥堵,降低控制性能。

接下来,我们尝试引入PID回馈控制器,就是这个样子的。

PID的Python代码实现如下:

!/usr/bin/python

import time

class PID: def init(self, P=0.2, I=0.0, D=0.0):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    self.Kp = P
    self.Ki = I
    self.Kd = D

    self.sample_time = 0.00
    self.current_time = time.time()
    self.last_time = self.current_time

    self.clear()

def clear(self):
    #Clears PID computations and coefficients
    self.SetPoint = 0.0

    self.PTerm = 0.0
    self.ITerm = 0.0
    self.DTerm = 0.0
    self.last_error = 0.0

    # Windup Guard
    self.int_error = 0.0
    self.windup_guard = 20.0

    self.output = 0.0

def update(self, feedback_value):
    # Calculates PID value for given reference feedback

    error = self.SetPoint - feedback_value

    self.current_time = time.time()
    delta_time = self.current_time - self.last_time
    delta_error = error - self.last_error

    if (delta_time >= self.sample_time):
        self.PTerm = self.Kp * error
        self.ITerm += error * delta_time

        if (self.ITerm < -self.windup_guard):
            self.ITerm = -self.windup_guard
        elif (self.ITerm > self.windup_guard):
            self.ITerm = self.windup_guard

        self.DTerm = 0.0
        if delta_time > 0:
            self.DTerm = delta_error / delta_time

        # Remember last time and last error for next calculation
        self.last_time = self.current_time
        self.last_error = error

        self.output = self.PTerm + (self.Ki * self.ITerm) + (self.Kd * self.DTerm)

def setKp(self, proportional_gain):
    # Determines how aggressively the PID reacts to the current error with setting Proportional Gain
    self.Kp = proportional_gain

def setKi(self, integral_gain):
    # Determines how aggressively the PID reacts to the current error with setting Integral Gain
    self.Ki = integral_gain

def setKd(self, derivative_gain):
    # Determines how aggressively the PID reacts to the current error with setting Derivative Gain
    self.Kd = derivative_gain

def setWindup(self, windup):
    # unwound
    self.windup_guard = windup

def setSampleTime(self, sample_time):
    # PID that should be updated at a regular interval.
    self.sample_time = sample_time

然后在上图条件下进行PID控制,代码如下:

import PID import time import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import spline

def test_pid(P = 0.2, I = 0.0, D= 0.0, L=100): """Self-test PID class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
.. note::
    ...
    for i in range(1, END):
        pid.update(feedback)
        output = pid.output
        if pid.SetPoint > 0:
            feedback += (output - (1/i))
        if i>9:
            pid.SetPoint = 1
        time.sleep(0.02)
    ---
"""
pid = PID.PID(P, I, D)
pid.clear()
pid.SetPoint=0.0
pid.setSampleTime(0.01)

END = L
feedback = 0

feedback_list = []
time_list = []
setpoint_list = []

for i in range(1, END):
    pid.update(feedback)
    output = pid.output
    if pid.SetPoint > 0:
        feedback += (output - (1/i))
    if i<10:
        pid.SetPoint = 20
    if i>20:
        pid.SetPoint = 50
    if i>22:
        pid.SetPoint = 100
    if i>24:
        pid.SetPoint = 10
    if i>28:
        pid.SetPoint = 200
    if i>30:
        pid.SetPoint = 200
    if i>70:
        pid.SetPoint = 20

    feedback_list.append(feedback)
    setpoint_list.append(pid.SetPoint)
    time_list.append(i)
    time.sleep(0.02)

time_sm = np.array(time_list)
time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300)
feedback_smooth = spline(time_list, feedback_list, time_smooth)

plt.plot(time_smooth, feedback_smooth)
plt.plot(time_list, setpoint_list)
plt.xlim((0, L))
plt.ylim((min(feedback_list)-0.5, max(feedback_list)+0.5))
plt.xlabel('time (s)')
plt.ylabel('PID C-R')

plt.grid(True)
plt.show()

if name == "main": test_pid(1.01, 1, 0.001, L=100)

然后看看现在是什么样呢?

嗯,没错,多了一些调节量(超调量),且变化较之前平稳了一些。这些调节量是否适用于大批量的云计算环境还有待验证,但是以Web应用来看,这些调节量理应工作。

另外,考虑到虚拟机在创建后某些应用可能短时间内不接受下调,所以我们可以动态地调节C的值,即PID的输出仅用作参考。

近期

比较低靡,状况不佳。 书籍出版进入尾期,一波好几折,入圈子是要有代价的。 对模型与实验更加痴迷,由于现实所限,只得从外汇市场入手。 现在的总结与抽象能力个人感觉比以前更加强了,晚上把博客目录更新一下,还是要把书放到About里的。 亚马逊上还有几本书待买,一定很有嚼劲。 家庭方面将要迎来新开始,可喜可贺。 生活总是让人觉得平衡,有点不开心,跷跷板要垫高。

近期-2016-08

整体来说心情急躁,是坏的状态。 外汇交易刚刚进入一些起步状态,新闻趋势整体OK,技术分析算法收集,然后接下来是技术分析层面的自动交易的算法,最后才是机器学习利用新闻和技术作为信号。平台方面打算部署一套OpenShift,也可作为对外的信号系统。 其他状态较为稳定,比如书籍仍在进行,第二个笔记正在写,研究生不考了,等。

近期

也是有很久没更新过了,总结下最近的日子吧。

悲喜交加。