使用cloud-init实现虚拟机信息管理

为什么要用cloud-init 不同种类的设备VM启动总是一件非常麻烦的事情,例如安全设备有WAF、IPS等,每种设备的网络接口、启动脚本互不一样,即便同一种设备,其主机名、网络地址等也不一样。那么如何对这些VM启动过程进行管理,并完成所有数据的配置呢? 在这之前,我的实习生是怎么做的:将一台VM的管理口网络地址设置为192.168.2.100,然后每次启动实例之后定时访问http://192.168.2.100/somepath,当成功访问这个页面之后,使用REST接口配置该机器的IP地址为所需的新地址(如200.0.0.2);这个时候网络会短暂不同,然后在访问http://200.0.0.2/somepath,当成功访问之后,接下来配置各种值。 整个过程比较麻烦,所有的配置都需要实现REST接口,无法做到自定义启动脚本的更新;最不可接受的是,这个过程是串行的,当要启动100个VM时,只能一个VM一个VM顺序启动,否则两个VM都有同一个地址(192.168.2.100),那么网络访问就可能出现问题了。 不过受到各种Stack管理虚拟机用到cloud-init的启发,我认为我们也可以使用这套工具实现上述过程的。 什么是cloud-init cloud-init(简称ci)在AWS、Openstack和Cloudstack上都有使用,所以应该算是事实上的云主机元数据管理标准。那么问题来了,google相关的文档,发现中文这方面几乎没有,Stacker你们再搞虾米呢?当然话说回来英文的资料除了官网外几乎也没有什么,我花了近一周的时间才弄明白了。 首先要明确的是cloud-init在工作之前,VM是从DHCP服务器获取到了IP,所有DHCP发现不是cloud-init的事情。当你在Openstack中用ubuntu cloud VM启动卡在cloud-init界面时,多半是因为DHCP还没获取IP,而不是cloud-init本身的问题。那么cloud-init主要走什么呢?它向一台数据服务器获取元数据(meta data)和用户数据(user data),前者是指VM的必要信息,如主机名、网络地址等;后者是系统或用户需要的数据和文件,如用户组信息、启动脚本等。当cloud-init获取这些信息后,开始使用一些模块对数据进行处理,如新建用户、启动脚本等。 cloud-init工作原理 首先,数据服务器开启HTTP服务,cloud-init会向数据服务器发送请求,确认数据源模块,依次获取版本、数据类型和具体数据内容信息。 确认数据源模块 cloud-init会查找/etc/cloud/cloud.cfg.d/90_dpkg.cfg中的datasource_list变量,依次使用其中的数据源模块,选择一个可用的数据源模块。如我的配置文件中:datasource_list: [ Nsfocus, NoCloud, AltCloud, CloudStack, ConfigDrive, Ec2, MAAS, OVF, None ],那么ci首先调用$PYTHON_HOME/dist-packages/cloudinit/sources/DataSourceNsfocus.py中类DataSourceNsfocus的get_data函数,当且仅当访问链接DEF_MD_URL为正常时,这个数据源被认为是OK的。 在我的实践中,CloudStack的DEF_MD_URL为DHCP的服务器ip,而Openstack和AWS则为一个常值169.254.169.254,然后在宿主机的中做一个iptables重定向,这样就到了我们的服务器监听端口8807:

一些系统假设 需要说明的是,虽然每个数据源访问的入口都是get_data,但每个数据服务的格式和位置是不一样的,元数据可能在/nsfocus/latest/metadata/,也可能在/latest/metadata.json,也就是说数据源模块根据自己系统的规定,访问相应的数据,并根据ci的规定,指定如何将这些数据与ci接下来的处理模块对应上。 那么我们的数据访问地址是这样的:

其中,namespace为nsfocus,meta_data.json是一个json文件,里面包含所有元数据。 其次,我们的数据服务器IP为111.0.0.2 … Continue reading

Openstack节点网卡连Cisco交换机出现环路的处理

前一阵子部署了两台Openstack的计算节点,奇怪的是每隔一段时间连管理网的网卡eth0灯不亮,交换机上对应的19端口灯变橙色,登陆上去一看,eth0显示:

运行ip link set eth0 up无效。 登陆交换机,查看端口状态:

可以看到19端口出现问题,继续看日志

发现原来是出现了环路,参考cisco的官方文档,一个可能的原因是交换机定时发送keepalive,这个数据包进入节点后又出来,到了同一个端口,则交换机认为可能出现环路,从而禁用。 解决办法是禁用keepalive:

当然也可以升级到高版本的IOS,默认会禁用keeplive。 然后恢复出错的端口:

过了300秒后,端口应该恢复正常,此时能够连接上主机了。 我觉得也可以在节点侧,在连接eth0的ovs桥br0加stp,以观后效

参考文章 Cisco交换机命令行配置(http://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus5000/sw/configuration/guide/cli_rel_4_0_1a/CLIConfigurationGuide/sm_syslog.html) Cisco交换机端口出错处理(http://www.cisco.com/c/en/us/support/docs/lan-switching/spanning-tree-protocol/69980-errdisable-recovery.html)