• OpenStack 下 CentOS6.X 镜像网络初始化失败问题排查


    问题表现

    在我的 OpenStack 集群上迁移了一批老旧的镜像(从其他三方云平台过来的)发现这批镜像在使用 ConfigDrive 的方式注入配置初始化时无法对非首张网卡镜像初始化(后经过测试非 ConfigDrive 的数据源也不行)。

    排查路径

    首先检查 cloud-init 是否是正常工作的
    实例化镜像查看 cloud-init 服务, 以及相关日志。

    systemctl status cloud-init
    systemctl status cloud-init-local
    

    服务均正常启用。
    再查看 Cloud-init 的初始化日志

    [   19.254076] cloud-init[1483]: Cloud-init v. 0.7.5 finished at Tue, 02 Jul 2024 06:28:30 +0000. Datasource DataSourceConfigDriveNet [net,ver=2][source=/dev/sr0].  Up 19.24 seconds
    

    可以看到有类似读取到数据源并实例化的日志。基本上可以可以排除 cloud-init 运行不正常的情况。

    cloud-init 调试

    只能细化cloud-init初始化的流程。
    关于cloud-init 运行阶段的讲述推荐这篇文章,我此处不多赘述。https://www.cnblogs.com/frankming/p/16281447.html
    此处给出快速重重跑初始化的脚本

    # centos7
    #! /bin/bash
    cloud-init clean
    rm -rf /var/run/cloud-init/
    rm -rf /var/lib/cloud/
    rm -rf /etc/sysconfig/network-scripts/ifcfg-*
    
    # local 阶段数据源准备
    cloud-init init --local
    
    # 网络阶段, 渲染数据
    cloud-init init
    
    # 执行模块
    cloud-init modules --mode=config
    
    # centos6
    #! /bin/bash
    rm -rf /var/run/cloud-init/
    rm -rf /var/lib/cloud/
    rm -rf /etc/sysconfig/network-scripts/ifcfg-*
    
    # local 阶段数据源准备
    cloud-init init --local
    
    # 网络阶段, 渲染数据
    cloud-init init
    
    # 执行模块
    cloud-init modules --mode=config
    

    很遗憾,在重跑初始化流程中未看出端疑,对比可以初始化多张网卡的日志(CentOS7系统上),总感觉 CentOS6 在网卡配置阶段无任务操作。于是拖下了 Cloud-init 的源码码进行静态审计+Print大发。
    源码路径:

    /usr/lib/python2.6/site-packages/cloudinit
    

    定位到 Cloud-init 7.5 的这个位置

    ...
    # sources/DataSourceConfigDrive.py +166
    def read_config_drive(source_dir, version="2012-08-10"):
        reader = openstack.ConfigDriveReader(source_dir)
        finders = [
            (reader.read_v2, [], {'version': version}),
            (reader.read_v1, [], {}),
        ]
        excps = []
        for (functor, args, kwargs) in finders:
            try:
                return functor(*args, **kwargs)
            except openstack.NonReadable as e:
                excps.append(e)
        raise excps[-1]
    ...
    
    ...
    # sources/DataSourceConfigDrive.py +59
        def get_data(self):
            found = None
            md = {}
            results = {}
            if os.path.isdir(self.seed_dir):
                try:
                    results = read_config_drive(self.seed_dir)
                    found = self.seed_dir
                except openstack.NonReadable:
                    util.logexc(LOG, "Failed reading config drive from %s",
                                self.seed_dir)
            if not found:
                for dev in find_candidate_devs():
                    try:
                        results = util.mount_cb(dev, read_config_drive)
                        found = dev
                    except openstack.NonReadable:
    ...
    

    可以看到在挂载 /dev/sr0 设备后,cloud-init 0.7.5 版本使用的是 2012-08-10 数据源
    手动挂载并查看

    [root@aa home]# mount /dev/sr0 /mnt/
    mount: /dev/sr0 is write-protected, mounting read-only
    [root@aa home]# ls /mnt/
    ec2  openstack
    [root@aa home]# ls /mnt/openstack/2012-08-10/
    meta_data.json  user_data
    

    好哇,根本没有network_data.json这种东西。看相关网络配置的初始化,验证网络初始逻辑只给ubuntu做了适配。得出结果,Cloud-init 0.7.5 版本过低,centos7支持差导致。

    解决方案

    解决方案大致有两种:

    1. 升级 Cloud-init
    2. 手工实现 Cloud-init 网络初始化部分的逻辑
    

    解决方案一

    升级的话首选需要升级Python版本,本人未采用升级的方案,所以不多赘述,但是是一定可行的,推荐手动升级Python 并源码安装 Cloud-init。

    解决方案二

    推荐像本人一样参考高版本的 cloud-init 驱动实现逻辑手工用 go 或者 C 语言这种重新写一个补丁,经测试可行。由于这个组件是为公司开发的,不方便开源,但是欢迎交流。

  • 相关阅读:
    前端练手项目合集40.0个,附源码,2022年最新
    (附源码)php投票系统 毕业设计 121500
    Spring项目-前端问题:Can‘t find variable:$
    SpringBoot项目打包与运行
    基于uni-app和图鸟UI的云课堂小程序开发实践
    HarmonyOS DevEso环境搭建
    React 底层 Fiber 架构 简单理解
    docker下安装apollo多环境(DEV 和UAT)
    多线程可见
    java后端web前端10套项目开发案例源码,毕设,期末作业
  • 原文地址:https://www.cnblogs.com/oscar2960/p/18281572