最近在龙芯 3B6000 平台上基于 AnolisOS 23.4 部署 Docker 环境时,遇到了一个典型问题:通过系统默认仓库安装 Docker 后,服务能正常启动,但在尝试创建或运行容器时,却频繁遭遇失败。这个问题在国产化平台迁移和容器化实践中具有一定普遍性,其背后往往涉及架构兼容性、内核模块、存储驱动等多个层面的因素。本文将系统性地拆解这一问题的完整排查与解决流程,从环境准备、问题复现、根因分析到最终修复,提供一套可复现的实战指南。无论你是正在将业务向龙芯平台迁移的运维工程师,还是对 LoongArch 架构下容器技术感兴趣的开发者,都能从中获得直接的帮助。

1. 背景与核心概念

在深入问题之前,我们有必要厘清几个关键概念,这有助于理解后续的排查逻辑。

龙芯 3B6000 与 LoongArch 架构 :龙芯 3B6000 是龙芯中科推出的新一代通用处理器,采用完全自主设计的 LoongArch 指令集架构。这意味着其二进制指令与常见的 x86_64 或 ARM 架构不同,所有软件,包括操作系统内核、系统工具和应用程序,都需要针对 LoongArch 进行编译或提供对应的版本。

AnolisOS 23.4 :Anolis OS 是由 OpenAnolis 社区推出的开源、中立的企业级 Linux 发行版,旨在为多样化的计算场景提供稳定、高性能的操作系统。AnolisOS 23.4 是其一个重要版本,提供了对 LoongArch 等新兴架构的良好支持,并集成了较新的软件包。

Docker 与容器 :Docker 是一种容器化平台,它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中。容器共享宿主机的操作系统内核,但拥有独立的用户空间,从而实现快速部署和一致性运行。在 LoongArch 架构上运行 Docker,意味着我们需要 LoongArch 版本的 Docker 引擎、相关工具以及兼容的容器镜像。

问题的本质 :在 x86_64 架构上, yum install docker apt install docker.io 通常能获得一个开箱即用的环境。但在龙芯平台上,情况更为复杂。默认仓库提供的 Docker 包可能并非为 LoongArch 架构最优构建,或者其依赖的内核模块、底层库(如 containerd runc )存在版本不匹配或兼容性问题,导致容器运行时( runc )无法正确创建容器所需的隔离环境(如命名空间、控制组等)。因此,“安装成功但无法创建容器”是一个典型的运行时兼容性问题。

2. 环境准备与版本说明

为了准确复现和解决问题,首先需要明确我们的基础环境。以下版本信息基于实际测试,你的环境可能略有差异,但排查思路是通用的。

  • 硬件平台 :龙芯 3B6000 处理器
  • 操作系统 :AnolisOS 23.4 (LoongArch 64)
  • 内核版本 5.10.0-26.an23.loongarch64 (可通过 uname -r 命令查看)
  • 安装方式 :通过 AnolisOS 23.4 默认的 dnf 仓库安装 Docker。

首先,我们验证系统架构和初始状态:

# 查看系统架构
uname -m
# 预期输出:loongarch64

# 查看内核版本
uname -r
# 预期输出类似:5.10.0-26.an23.loongarch64

# 检查 Docker 是否已安装(初始状态应未安装)
docker --version
# 如果已安装旧版本,建议先彻底卸载

3. 问题复现:默认仓库安装与容器创建失败

让我们按照“常规”流程操作,重现问题。

3.1 通过默认仓库安装 Docker

在 AnolisOS 中,我们使用 dnf 包管理器。

# 1. 更新软件包索引
sudo dnf makecache

# 2. 安装 Docker 引擎及相关工具
sudo dnf install docker docker-compose

# 3. 启动 Docker 服务并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

# 4. 验证 Docker 服务状态
sudo systemctl status docker

如果安装和启动成功, status 命令应显示 active (running)

3.2 尝试运行容器并遭遇失败

安装完成后,我们尝试运行一个最简单的容器进行测试,例如官方的 hello-world 镜像。但请注意,Docker Hub 上官方镜像大多为 linux/amd64 linux/arm64 ,没有 linux/loongarch64 。因此,我们需要一个针对 LoongArch 编译的镜像。这里以 busybox 为例(假设有 LoongArch 版本),或者直接测试容器创建过程。

# 尝试运行一个交互式 busybox 容器(此命令很可能失败)
sudo docker run -it --rm busybox /bin/sh

或者,更直接地测试容器运行时:

# 拉取一个已知支持多架构(包含loongarch64)的镜像,例如来自第三方仓库的镜像
# 这里假设我们有一个可用的镜像地址,实际操作中可能需要先配置镜像仓库
# sudo docker pull cr.loongnix.cn/library/busybox:latest

# 运行测试
# sudo docker run -it --rm cr.loongnix.cn/library/busybox:latest echo “Hello LoongArch”

在问题环境中,你很可能会遇到如下几种典型的错误信息:

  1. docker: Error response from daemon: failed to create shim task: OCI runtime create failed: ... 这是最常见的一类错误,指向 OCI(开放容器标准)运行时(通常是 runc )创建失败。
  2. docker: Error response from daemon: failed to start shim: fork/exec /usr/bin/containerd-shim-runc-v2: no such file or directory 这表明 containerd 的 shim 可执行文件路径有问题或文件缺失。
  3. docker: Error response from daemon: failed to create shim: could not find an OCI runtime configuration file 指向 OCI 运行时配置文件缺失。
  4. 权限错误 :虽然使用了 sudo ,但仍可能遇到与 cgroup AppArmor SELinux 或用户组相关的权限问题。

4. 根因分析与深度排查

当容器创建失败时,我们需要像侦探一样,从 Docker 引擎日志、容器运行时日志以及系统层面逐层排查。

4.1 查看 Docker 引擎日志

Docker 服务的详细日志是首要的排查入口。

# 使用 journalctl 查看 Docker 服务的日志
sudo journalctl -u docker.service --since “1 hour ago” -f

# 或者查看 Docker 守护进程的日志文件(如果配置了)
# sudo tail -f /var/log/docker.log

在日志中,寻找 ERROR failed 等关键词。重点关注与 runc containerd cgroup iptables seccomp 相关的错误信息。

4.2 检查容器运行时状态

Docker 默认使用 containerd 作为容器运行时。

# 检查 containerd 服务状态
sudo systemctl status containerd

# 查看 containerd 的配置
sudo cat /etc/containerd/config.toml

确保 containerd 服务正在运行,并且其配置中指定的 runc 路径(通常是 /usr/bin/runc /usr/sbin/runc )是存在的、可执行的 LoongArch 版本。

4.3 验证 runc 与内核模块

runc 是实际创建容器的工具,它依赖于 Linux 内核的命名空间和 cgroup 功能。

# 1. 检查 runc 的版本和路径
which runc
runc --version
# 确认输出的是 LoongArch 版本,且版本与 Docker/containerd 兼容。

# 2. 检查必需的内核模块是否加载
lsmod | grep -E “overlay|br_netfilter|ip_tables|iptable_filter|iptable_nat”
# 关键模块:`overlay`(存储驱动)、`br_netfilter`、`ip_tables`(网络)
# 如果未加载,使用 `sudo modprobe <模块名>` 加载。

# 3. 检查 cgroup 文件系统支持
ls /sys/fs/cgroup/
# 确认有 `cgroup2` 或 `cgroup` 目录。现代 Docker 更推荐使用 cgroup v2。
grep cgroup /proc/filesystems
# 查看内核支持的文件系统类型。

4.4 分析存储驱动

Docker 使用存储驱动来管理镜像和容器的分层文件系统。在龙芯平台上, overlay2 是最常用且推荐的驱动。

# 查看 Docker 当前的存储驱动配置
sudo docker info | grep “Storage Driver\|Backing Filesystem”

如果输出不是 overlay2 ,或者 Backing Filesystem 不被支持(如 xfs 需要 ftype=1 ),就需要调整。

4.5 检查用户组与权限

虽然使用了 sudo ,但 Docker 守护进程本身以及 runc 执行时对某些资源的访问权限可能仍有问题。

# 将当前用户加入 docker 组,避免每次都使用 sudo(操作后需重新登录)
sudo usermod -aG docker $USER

# 检查 /var/run/docker.sock 的权限
ls -l /var/run/docker.sock
# 应属于 docker 组,且组用户有读写权限。

5. 解决方案:修复容器创建失败

根据上述排查,我们针对龙芯 3B6000 + AnolisOS 23.4 的常见问题,提供一套组合解决方案。

5.1 方案一:彻底卸载并安装社区验证版本

默认仓库的 Docker 包可能不是最佳选择。我们可以卸载后,采用龙芯社区或 Anolis 社区验证过的软件源进行安装。

# 1. 彻底卸载现有 Docker
sudo dnf remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine docker-compose
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

# 2. 添加龙芯开源软件仓库(Loongnix 或 OpenAnolis 的扩展仓库)
# 例如,添加 Anolis 的 extras 仓库(请根据 AnolisOS 23.4 实际文档操作)
# 通常仓库配置文件在 /etc/yum.repos.d/ 下
# 这里以可能存在的社区源为例,实际操作需确认可用性
# sudo curl -o /etc/yum.repos.d/anolis-extras.repo https://some-mirror.anolisos.com/repo/anolis-extras.repo

# 3. 重新安装 Docker
# 在配置好合适的仓库后,再次安装
sudo dnf makecache
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 4. 配置 Docker 使用 systemd 作为 cgroup 驱动(重要!)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’
{
  “exec-opts”: [“native.cgroupdriver=systemd”],
  “log-driver”: “json-file”,
  “log-opts”: {
    “max-size”: “100m”
  },
  “storage-driver”: “overlay2”,
  “registry-mirrors”: [“https://cr.loongnix.cn”] # 使用龙芯镜像加速
}
EOF

# 5. 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker

5.2 方案二:手动配置 containerd 和 runc

如果安装后 containerd runc 仍有问题,可以尝试手动检查和配置。

# 1. 确认 containerd 和 runc 的二进制文件
ls -lh /usr/bin/containerd* /usr/bin/runc* /usr/sbin/runc*

# 2. 如果 runc 缺失或版本不对,可以从可靠来源安装
# 例如,从龙芯的软件包中提取,或从源码编译(复杂)
# 假设已有正确的 runc 二进制包
# sudo dnf install runc-<version>.loongarch64.rpm

# 3. 生成 containerd 的默认配置
sudo containerd config default | sudo tee /etc/containerd/config.toml

# 4. 在 config.toml 中,确保 runc 的路径正确
# 使用 sed 修改或手动编辑
sudo sed -i ‘s#SystemdCgroup = false#SystemdCgroup = true#’ /etc/containerd/config.toml

# 5. 重启 containerd 和 docker
sudo systemctl restart containerd
sudo systemctl restart docker

5.3 方案三:内核参数与模块调整

确保内核支持容器运行所需的所有功能。

# 1. 加载必要的内核模块
sudo modprobe overlay
sudo modprobe br_netfilter

# 2. 设置系统启动时自动加载模块
echo “overlay” | sudo tee -a /etc/modules-load.d/containerd.conf
echo “br_netfilter” | sudo tee -a /etc/modules-load.d/containerd.conf

# 3. 配置网络桥接的 iptables 处理
cat <<EOF | sudo tee /etc/sysctl.d/99-docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system

5.4 方案四:使用特定 LoongArch 镜像测试

在修复环境后,使用已知良好的 LoongArch 镜像进行测试。龙芯社区维护了一个镜像仓库。

# 配置 Docker 镜像加速器(如果上一步的 daemon.json 已配置,可跳过)
# 拉取 LoongArch 架构的 busybox 镜像进行测试
sudo docker pull cr.loongnix.cn/library/busybox:latest

# 查看镜像架构
sudo docker inspect cr.loongnix.cn/library/busybox:latest | grep Architecture

# 运行测试容器
sudo docker run -it --rm cr.loongnix.cn/library/busybox:latest echo “Hello from LoongArch Container!”

如果这一步成功,恭喜你,Docker 环境已经基本正常。

6. 常见问题与排查思路

即使按照上述步骤操作,仍可能遇到一些“坑”。下表汇总了常见问题现象及其解决思路:

问题现象 可能原因 排查与解决思路
OCI runtime create failed: unable to retrieve OCI runtime error 1. runc 版本不兼容或损坏。
2. 内核不支持某些特性(如 cgroup v2)。
3. containerd 配置错误。
1. 检查 runc --version ,尝试安装/更新 runc
2. 检查内核版本和 cgroup 类型 ( mount -t cgroup2 )。
3. 检查 /etc/containerd/config.toml 中的 runc 配置路径。
failed to start shim: fork/exec ... no such file or directory containerd-shim-runc-v2 二进制文件缺失或路径错误。 1. 查找文件: find / -name “containerd-shim-runc-v2”
2. 如果缺失,重新安装 containerd 或从正常机器拷贝。
3. 在 config.toml 中核对 shim 路径。
docker run 挂起无响应 1. 镜像拉取失败(网络问题)。
2. 存储驱动问题(如 overlay2 与文件系统不兼容)。
3. 资源不足(内存、磁盘)。
1. 配置镜像加速器,使用 docker pull 单独拉取镜像测试。
2. 检查 docker info 中的存储驱动和文件系统。
3. 检查 dmesg 和系统资源使用情况。
权限错误(即使使用 sudo) 1. /var/run/docker.sock 权限问题。
2. SELinux/AppArmor 策略限制。
3. 用户未加入 docker 组。
1. ls -l /var/run/docker.sock ,确保 docker 组有权限。
2. 临时禁用 SELinux ( setenforce 0 ) 测试,或配置正确策略。
3. 将用户加入 docker 组并重新登录。
无法拉取镜像( no matching manifest 镜像仓库中没有 linux/loongarch64 架构的镜像。 1. 使用支持 LoongArch 的镜像仓库,如 cr.loongnix.cn
2. 在拉取时指定平台(如果镜像支持多架构): --platform linux/loongarch64
3. 自己构建 LoongArch 架构的镜像。

7. 最佳实践与工程建议

在龙芯等国产化平台上稳定运行 Docker,除了解决问题,更需要建立规范。

  1. 源的选择与管理

    • 优先使用经过验证的软件源 :如 OpenAnolis 社区为 AnolisOS 提供的扩展仓库、龙芯的官方或社区仓库。避免混用来源不明的 RPM/DEB 包。
    • 固定版本 :在生产环境中,固定 Docker、containerd、runc 的版本,避免因自动升级引入不兼容问题。
  2. 镜像构建与迁移

    • 多架构构建 :如果你的应用需要跨平台部署,使用 docker buildx 进行多架构镜像构建(包括 linux/loongarch64 )。
    • 基础镜像选择 :优先选择基于 AnolisOS、Loongnix 或 Alpine Linux(已支持 LoongArch) 等发行版构建的基础镜像,以获得更好的兼容性。
    • 镜像仓库 :搭建私有镜像仓库,并主动同步或构建 LoongArch 架构的常用基础镜像,减少对公网不可控仓库的依赖。
  3. 配置标准化

    • 统一 daemon.json :将 cgroupdriver storage-driver registry-mirrors log-opts 等关键配置在 /etc/docker/daemon.json 中标准化。
    • 内核参数调优 :将容器相关的内核参数(如 net.ipv4.ip_forward , vm.max_map_count 等)写入 /etc/sysctl.d/ 下的配置文件,并确保系统启动时加载。
  4. 监控与日志

    • 启用 Docker 日志轮转 :在 daemon.json 中配置 log-driver log-opts ,防止日志占满磁盘。
    • 监控容器资源 :使用 cadvisor node-exporter 等工具监控龙芯主机上容器的 CPU、内存、IO 使用情况,观察是否有架构特定的性能特征。
  5. 安全考虑

    • 非 Root 用户运行 :考虑使用 rootless 模式运行 Docker,尽管在 LoongArch 上可能需要更多测试,但这是提升安全性的重要方向。
    • 最小权限原则 :容器内应用以非 root 用户运行,避免使用 --privileged 特权模式。
    • SELinux/AppArmor :在理解策略的基础上,为容器配置适当的 SELinux 上下文或 AppArmor 配置文件,而不是简单粗暴地禁用。
  6. 备份与恢复

    • 定期备份 /etc/docker /var/lib/docker (在服务停止时)目录下的关键配置和镜像数据。
    • 记录最终可用的软件包版本组合( docker-ce , containerd.io , runc ),形成环境配置清单。

在龙芯 3B6000 的 AnolisOS 23.4 系统上部署 Docker,核心挑战在于软件生态的完整性与兼容性。通过本文的步骤——从通过默认仓库安装复现问题,到层层深入分析日志、检查运行时和内核模块,最终通过切换软件源、调整配置、加载内核模块等组合方案解决问题——我们不仅解决了一个具体的技术障碍,更梳理出了一套在非 x86 架构上部署容器环境的通用排查方法论。

关键收获在于,不能简单照搬 x86 环境的经验。在龙芯平台上,每一个组件(内核、Docker 引擎、containerd、runc、基础镜像)的架构兼容性都必须得到确认。优先采用社区验证过的软件源和镜像,仔细核对配置文件,并充分利用系统日志进行排查,是成功的关键。

下一步,你可以探索如何在龙芯平台上利用 Docker Compose 编排多容器应用,或者结合 Kubernetes 进行容器集群的管理。同时,关注 OpenAnolis 社区和龙芯生态的最新动态,获取更优的软件包和更稳定的镜像,将使你的国产化容器之旅更加顺畅。

更多推荐