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

openstack,centos6 · 浏览次数 : 4

小编点评

问题出现在将一批老旧的镜像从其他三方云平台迁移到OpenStack集群时,发现这些镜像在使用ConfigDrive的方式注入配置初始化时无法对非首张网卡镜像进行初始化。经过排查,初步判断Cloud-init服务正常工作,但需要进一步分析Cloud-init的初始化日志。 在Cloud-init的初始化过程中,首先会尝试读取ConfigDrive数据源。如果成功,则继续进行网络配置等后续步骤。如果在尝试读取ConfigDrive数据源失败时,Cloud-init会尝试使用其他数据源进行初始化。在这个过程中,我们观察到Cloud-init在处理非首张网卡镜像时存在问题。 为了解决这个问题,我们可以采取以下两种解决方案: 1. 升级Cloud-init:升级Cloud-init到最新版本,以解决与CentOS 7之间的兼容性问题。 2. 手工实现Cloud-init网络初始化部分的逻辑:参考高版本的Cloud-init驱动实现逻辑,使用Go或C语言重新编写补丁,以实现网络初始化部分的逻辑。 最终,通过升级Cloud-init或手工实现网络初始化部分的逻辑,可以解决这个问题的影响。

正文

问题表现

在我的 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 语言这种重新写一个补丁,经测试可行。由于这个组件是为公司开发的,不方便开源,但是欢迎交流。

与OpenStack 下 CentOS6.X 镜像网络初始化失败问题排查相似的内容:

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

问题表现 在我的 OpenStack 集群上迁移了一批老旧的镜像(从其他三方云平台过来的)发现这批镜像在使用 ConfigDrive 的方式注入配置初始化时无法对非首张网卡镜像初始化(后经过测试非 ConfigDrive 的数据源也不行)。 排查路径 首先检查 cloud-init 是否是正常工作的

OpenStack Centos7 T版本搭建

目录Centos7搭建OpenStack T版本 --上1. 环境准备(所有节点操作)1.1 修改主机名1.2 关闭selinux 以及防火墙1.3 修改hosts1.4 配置时间同步controller 操作compute以及其他节点操作1.5 配置OpenStack 软件包1.6 安装数据库1.

[转帖]0.03秒引发的网络血案

https://www.jianshu.com/p/45085331b9f0 背景 用户Pike版Openstack,Firewall drivers为Openvswitch。Openstack内一租户网络下多台虚拟机中部署一K8S集群,其中Openstack下租户网络使用VxLAN,K8S集群采用

openStack核心组件的工作流程

目录openStack核心组件的工作流程1. Keystone1.1 User1.2 Credentials1.3 Authentication1.4 Token1.5 Project1.6 Service1.7 Endpoint1.8 Role1.9 keystone综述2. glance2.1

每天5分钟复习OpenStack(十三)存储缓存技术Bcache

Ceph作为一个分布式存储,在项目中常见的形态有两者,一种是采用 SSD 或NVME 磁盘做Ceph的日志盘,使用SATA磁盘来做数据盘。这样的好处是比较经济实惠。另一种则是全部采用 SSD 或NVME磁盘,其性能更好,但是其价格比较昂贵。在第一种形态中,我们能像中间件那样加上一层缓存层,从而实现给

[转帖]openstack中region、az、host aggregate、cell 概念

https://www.cnblogs.com/xiexun/p/14491057.html 1. region 更像是一个地理上的概念,每个region有自己独立的endpoint,regions之间完全隔离,但是多个regions之间共享同一个keystone和dashboard。(注:目前op

将虚拟机跑在ceph之中

目录openStack对接ceph1. cinder对接ceph1.1 ceph创建存储池1.2 ceph授权1.3 下发ceph文件1.4 修改globals文件1.5 部署cinder1.6 创建卷null2. nova对接ceph2.1 创建卷2.2 更新cinder权限2.3 修改globa

kvm链接克隆虚拟机迁移到openstack机器的实验

总结 如果是完整克隆的那种虚拟机,是可以直接在openstack使用的,如果镜像格式没问题的话。 因为kvm虚拟机大部分都是链接克隆出来的镜像,不可用直接复制使用,所以需要创建新的镜像文件 创建空盘:qemu-img create -f qcow2 mcwlink1-new.qcow2 50G 将链

Kolla-ansible部署openStack

目录Kolla-ansible部署openStack1. 简介2. 环境准备3. 部署3.1 基础环境配置3.1.1 配置主机名,所有节点操作,这里以openstack01为例3.1.2 添加hosts3.1.3 配置免密登录3.1.4 关闭防火墙以及selinux3.1.5 设置yum源3.1.6

[转帖]RabbitMQ服务优化,修改最大连接数

https://www.cnblogs.com/hoyeong/p/16242202.html RabbitMQ的优化RabbitMQ的连接数是压垮消息队列的一个重要的指标。所以在平时使用OpenStack平台的过程中,如果大量的用户同时创建虚拟机,会导致云平台创建报错,其实就是消息队列服务的崩溃。