openstack非DHCP网络配置注入和cloud-init分析

来源:互联网 发布:小米口罩知乎 编辑:程序博客网 时间:2024/06/11 14:58

      原理:基于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

其会调用:self._write_network

其实现?
@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()

在__init__.py中,_write_network未实现,实际上他会在具体的guest操作系统中进行实现。
举例,如果是debain系统,则此函数在distrio/debain.py中实现如下;
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


       

1 0
原创粉丝点击