海光 CPU 指令集导致的容器无法创建问题
问题描述
在验证海光服务器与 Rancher 兼容性时,出现一个奇怪的现象:
在阿里云平台上,使用 kylin v10 (X86版)(V10 V10.0-20221226) 以及 ARM 版本,可以正常创建 RKE 和 RKE2 集群。
在海光服务器 + VMware平台上,使用 kylin v10 sp3 操作系统,可以创建 RKE2 集群。
但是在海光服务器 + 深信服平台上,使用 kylin v10 sp3 操作系统,就无法创建 RKE 和 RKE2 集群。
验证版本
Env | Version |
---|---|
Rancher | v2.8.5-ent |
RKE | v1.28.15 |
RKE2 | v1.28.15+rke2r1 |
Docker | 26.1.3 |
kernel | 4.19.90-24.4.v2101.ky10.x86_64 |
问题现象
RKE
在通过 Rancher 创建 RKE 集群时,首次注册节点运行 agent 容器直接无法运行,一直是 restarting 状态,也没有任何日志信息。使用 docker inspect xxx 查看 agent 容器状态,看到退出码是 139 。

RKE2
通过 Rancher 部署 RKE2 集群,前面都能正常运行,但是 kube-proxy pod 无法启动。
其中 kube-proxy 使用的镜像一开始 iptables 命令是指向 /usr/sbin/iptables-detect.sh,这个脚本会调用另一个脚本 /usr/sbin/xtables-set-mode.sh,根据节点 iptables mode 进行一些设置,设置完才能用正常使用 iptables。但是在执行脚本的时候会报错 Segmentation fault (core dumped),导致 kube-proxy 容器内无法正常指向可用的 iptables,同时也发现执行简单的 ls /usr/sbin/*
也会报同样的错误。从节点内核日志也可以捕获的相关的错误日志。
排查过程
发现问题
使用 docker inspect xxx 查看 agent 容器状态,看到退出码是 139 。这里初步怀疑是操作系统兼容性的问题。

随之尝试手动去 docker run agent 镜像不带任何启动参数,也是跑不起来(连最基本的 error 日志都没有)。
环境检查
- 检查 selinux 、 apparmor,确认都已关闭。
- 怀疑 glibc 兼容性问题,通过ldd 查看系统 glibc 的版本: ldd (GNU libc) 2.28
- 通过 dmesg 收集系统日志,全是下面这种日志:
1 | [926769.990280] run.sh[3902107]: segfault at 55ab42bfe000 ip 00007fcac6767d39 sp 00007ffdb440eac8 error 6 in libc-2.31.so[7fcac6609000+1e8000] |
版本兼容验证
一开始怀疑是 Docker 版本兼容问题,查看 Rancher 官方兼容列表 ,2.8.5 兼容的 Docker 版本是 23.0.x/24.0.x,随之降级 Docker 版本,失败。
尝试使用
-e LD_PRELOAD=libc-2.28.so
或者-v /usr/lib64/libc-2.28.so:/usr/lib64/libc-2.28.so
指定 glibc 版本,失败。设置 entrypoint /bin/sh 尝试进入容器的 shell,失败。
前面提到 VMware 环境可以正常启动,但是深信服环境就启动不了,经过了解,VMware 正常运行的 kylin 的 kernel 版本是 4.19.90-89.14,深信服上面跑的 kylin 的 kernel 版本是 4.19.90-89.17,随之尝试使用相同的 kernel 版本,失败。
操作系统层面再次排查
Segfault 也有可能是 so 有问题,随之在目标系统上运行 rpm -Va 进行检查, 正常来说,输出比较少,也不应该有任何 so 文件输出。
如果是 conf 文件一类,带 T,S 这些,就无所谓。 但如果是二进制 so,带 M,S 标志,就有问题了。 M 是修改的意思,so 不应该被修改。
检查了下这部分,也发现都是正常的。

重新 build 镜像
前面有尝试过 设置 entrypoint /bin/sh 启动容器都无法启动,所以决定直接基于 kylin 操作系统构建了新的agent镜像。但是也失败了。
到这一步,我们已经怀疑是底层 BCI 镜像的问题了,因为 agent 镜像是基于 bci-base 镜像构建的,所以直接运行 registry.suse.com/bci/bci-base:15.5
镜像,但也失败了,到这一步确定是底层 BCI 镜像与操作系统不兼容。
(已验证过使用官方 busybox
、或者 registry.suse.com/bci/golang:1.21
都可以正常启动。)
重要发现
根据我们 Linux 工程师的经验,Kylin v10 sp3 经常为不同客户构建不同的定制镜像,但产品名字是一样的,所以光看产品名和版本,可能不是同一套东西。其中 VMware 启动是 iso或vmdk,深信服(OpenStack)启动是 qcow2,再加上之前远程的时候有看到两个环境的内核版本不一致,所以猜测应该不同的镜像。于是向客户说明这个可能性,准备导出深信服环境的虚拟机镜像,在我们自己的环境上进行验证。
但是客户突然反驳到,他们都是使用同一个镜像进行安装,所以和操作系统也没关系了。但是他们提到之前安装的时候开启过 HostCPU 可以正常运行。这是一个很重要的发现!
于是查询了下深信服官网中对 HostCPU 的说明,其中关键部分如下:
最佳实践:海光的服务器建议所有虚拟机开启HostCPU,若不开启此选项,虚拟机的CPU型号为AMD。

问题总结
经最终排查与验证,确认本次容器无法正常启动的问题源于 CPU 指令集不兼容。主要是深信服平台在海光服务器上默认启用的虚拟化 CPU 类型为 AMD,该虚拟化层提供的 AMD CPU 指令集与所使用的 BCI 镜像在指令集支持方面存在兼容性问题,导致容器运行时在初始化或执行关键指令时发生异常,从而无法正常启动。
最后确认了问题是跟 CPU 指令集相关,后面通过启用了 HostCPU 之后,问题得到了解决,容器可以正常启动,RKE 和 RKE2 集群都能创建成功。
在使用特定国产硬件平台(如海光)与安全虚拟化环境时,还是需要特别关注 CPU 指令集兼容性对容器运行时环境的影响。