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

      原理:基于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文件。如:


        openstack非DHCP网络配置注入和cloud-init分析_第1张图片

      

       接下来分析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


       

你可能感兴趣的:(云计算)