原理:基于config drive方式,将配置的网络信息注入到openstack/content/0000文件中,然后虚机启动后,由cloudinit读取此文件数据,由cloud-init中的基础组件进行虚机网络设置。
openstack的环境配置:
1.设置网络关闭dhcp功能。如果是使用中进行配置关闭,还需要查看网络中是否存在dhcp类型port.将dhcp类型的port删除掉。
2.配置nova.conf文件:
flat_injected = True #使能network信息注入功能
injected_network_template = ******** #配置产生网络metadata数据的模板位置。
默认在nova安装目录下,存在interfaces.template模板;
nova/virt/interfaces.template
实验时,copy上述文件到/etc/nova目录下。设置injected_network_template为:
injected_network_template = /etc/nova/interfaces.template
启动虚机时,nova-compute服务会按照interfaces.template的格式,生成content/0000文件。如:
接下来分析cloudinit是如何生效网络配置的:
cloudinit 首先通过挂在的目录获取content/0000数据,这个处理是由cloud init的util.py文件中的方法处理的。
通过日志可以知道,由DataSourceConfigDrive.py处理了更新network interfaces操作。具体是下面的函数
def on_first_boot(data, distro=None): """Performs any first-boot actions using data read from a config-drive.""" if not isinstance(data, dict): raise TypeError("Config-drive data expected to be a dict; not %s" % (type(data))) net_conf = data.get("network_config", '') if net_conf and distro: LOG.debug("Updating network interfaces from config drive") distro.apply_network(net_conf) files = data.get('files', {}) if files: LOG.debug("Writing %s injected files", len(files)) for (filename, content) in files.items(): if not filename.startswith(os.sep): filename = os.sep + filename try: util.write_file(filename, content, mode=0o660) except IOError: util.logexc(LOG, "Failed writing file: %s", filename)
所以,network注入后,网卡的配置工作是在cloudinit的最初的阶段就开始执行了。 从 distro.apply_network(net_conf),可以知道,实现apply_network是根据具体的linux发行版本来实现的: 注意cloudinit的源码结构: 其中就有distros文件夹: 所以,对于直接使用命令实现注入配置功能,都会和具体的操作系统有关。 在distro的__init__.py中可以找到apply_network的实现:
def apply_network(self, settings, bring_up=True): # Write it out dev_names = self._write_network(settings) # Now try to bring them up if bring_up: return self._bring_up_interfaces(dev_names) return False
@abc.abstractmethod def _write_network(self, settings): # In the future use the http://fedorahosted.org/netcf/ # to write this blob out in a distro format raise NotImplementedError()
def _write_network(self, settings): util.write_file(self.network_conf_fn, settings) return ['all']
参考资料:http://blog.oddbit.com/2015/06/26/openstack-networking-without-dhcp/
windows系列的镜像,使用cloudbase时,需要额外使用插件:cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin
在cloudbase-init和cloudbase-init-unattend中都需要添加。
在虚机中加载config drive的cdrom :mount/dev/disk/by-label/config-2 /mnt/config