如果你正在龙芯 3B6000 平台上使用 AnolisOS 23.4,并且希望通过系统默认的仓库安装 Docker,那么你很可能已经遇到了一个看似简单却令人困惑的拦路虎: Docker 服务能装,但容器死活创建不起来

这不是一个孤例,而是许多开发者在拥抱国产化软硬件生态时,从“兴奋”到“挫败”的典型分水岭。问题往往不是出在 Docker 本身,而是隐藏在默认仓库的软件包版本、内核模块兼容性以及龙芯特定架构的细微差异之中。很多人会花费大量时间在网络上搜索通用教程,却发现那些基于 x86_64 架构的“一键安装”命令在这里完全失效,或者埋下了更深的隐患。

本文要解决的,正是这个核心痛点。我们将深入剖析在龙芯 3B6000 + AnolisOS 23.4 环境下,使用默认仓库安装 Docker 时,从安装到容器创建的全链路流程。更重要的是,我们会聚焦于那个最让人头疼的“容器无法创建”问题,提供从原理分析到具体排查、修复的完整方案。这不是一篇泛泛而谈的安装指南,而是一份针对特定国产化平台的“排雷”实战手册。

读完本文,你将能:

  1. 理解在龙芯架构上运行 Docker 的核心依赖与潜在冲突。
  2. 掌握通过 AnolisOS 23.4 默认仓库安全安装 Docker 的正确姿势。
  3. 系统性地诊断并解决“容器无法创建”的各类错误。
  4. 获得一份经过验证的、可稳定运行 Docker 容器的配置清单。

1. 为什么在龙芯+AnolisOS上安装Docker是个“技术活”?

在 x86 服务器上,安装 Docker 几乎成了肌肉记忆:更新仓库、安装 docker-ce 、启动服务,一气呵成。但将场景切换到龙芯 3B6000(LoongArch 架构)和 AnolisOS(一个兼容 RHEL/CentOS 的国产开源操作系统)时,情况就复杂多了。

首先,架构差异是根本。 Docker 容器依赖于 Linux 内核的命名空间和控制组(cgroup)等特性。虽然 LoongArch 内核已经支持这些特性,但 Docker 引擎( dockerd )及其相关工具(如 containerd runc )都需要针对该架构进行编译。AnolisOS 的默认仓库提供了这些软件包,这是好消息。但坏消息是,仓库中包的版本组合、依赖关系,可能并非为 Docker 的最佳实践而优化,有时甚至存在冲突。

其次,“默认仓库”是一把双刃剑。 使用默认仓库保证了软件来源的可靠性和系统的纯洁性,避免了第三方仓库可能带来的兼容性风险。然而,这也意味着你无法轻易获取到 Docker 官方为特定版本优化的软件包。当出现问题(比如容器无法启动)时,你无法简单地通过“换用官方仓库”来解决,必须深入系统内部寻找原因。

最后,问题现象统一但原因多样。 “容器无法创建”这个错误提示背后,可能对应着多种原因:

  • 内核模块未加载或不支持 :如 overlay2 存储驱动依赖的内核模块。
  • cgroup 配置问题 :特别是 cgroup v2 与 Docker 的兼容性,这在较新的系统版本中很常见。
  • SELinux 或 AppArmor 安全策略拦截
  • 用户权限问题 :非 root 用户未加入 docker 组,或 docker.sock 权限不对。
  • 容器镜像架构不匹配 :尝试运行为 x86_64 构建的镜像。

因此,在这个特定平台上,安装 Docker 不能停留在“安装成功”这一步,必须验证到“容器可运行”才算真正完成。下面的章节,我们将一步步拆解这个过程。

2. 基础概念与核心原理:龙芯架构下的容器化

在深入操作前,厘清几个关键概念,有助于理解后续的排查思路。

1. LoongArch 架构与 Docker LoongArch 是龙芯中科自主研发的指令系统架构。Docker 容器虽然隔离了用户空间,但其进程最终仍然运行在宿主机的内核上。这意味着,所有容器内的用户态软件(如你的应用程序)需要是 LoongArch 架构的二进制文件,或者由支持 LoongArch 的解释器(如 Python、JVM)来运行。Docker 引擎本身也是一个 LoongArch 架构的应用程序。

2. AnolisOS 23.4 的软件生态 AnolisOS 23.4 基于上游社区版本,提供了稳定的软件仓库。其 yum dnf 包管理器管理的 docker 包,通常是一个由社区或发行版维护者打包的版本,它可能整合了 containerd runc 。这与 Docker 官方分开发布的 docker-ce containerd.io 包在版本管理和依赖关系上有所不同。

3. 容器创建的核心组件链 当你执行 docker run 时,背后发生了一系列调用:

docker cli -> dockerd (Docker 引擎) -> containerd (容器运行时) -> runc (底层运行时工具) -> Linux Kernel

“容器无法创建”的错误可能发生在这一链条的任何一个环节。在龙芯平台上,我们需要确保链条上的每一个环节都针对 LoongArch 正确编译和配置。

4. 存储驱动与文件系统 Docker 需要一种存储驱动来管理容器镜像和容器的可写层。 overlay2 是当前推荐且性能较好的驱动,它依赖 Linux 内核的 overlay 文件系统模块。在龙芯内核中,必须确认此模块已可用且已加载。

5. cgroups (控制组) cgroups 是 Linux 内核功能,用于限制、控制和隔离进程组的资源(CPU、内存、IO等)。Docker 依赖 cgroups 实现资源管理。新版本系统(如 AnolisOS 23.4)可能默认使用 cgroup v2 ,而旧版 Docker 或某些配置可能仍预期 cgroup v1 ,这会导致容器启动失败。

理解这些原理,就能明白后续的安装和排查每一步的目的所在。

3. 环境准备与系统确认

在开始安装前,请先登录你的龙芯 3B6000 服务器,并确认以下基础环境。

3.1 系统与架构确认 打开终端,执行以下命令:

# 查看操作系统版本
cat /etc/anolis-release

# 查看内核版本与架构
uname -r
uname -m

预期输出中, uname -m 应显示 loongarch64 ,确认是龙芯架构。内核版本应高于 4.x(推荐 5.x 以上),以更好地支持容器相关特性。

3.2 更新系统基础包 这是一个好习惯,可以确保系统处于最新状态,并刷新软件仓库元数据。

# 使用 dnf (AnolisOS 23.4 默认包管理器)
sudo dnf update -y

# 或者使用 yum (如果系统有的话)
sudo yum update -y

3.3 安装基础工具 安装后续排查可能需要的工具。

sudo dnf install -y vim wget curl net-tools

4. 通过默认仓库安装 Docker 及相关组件

我们将严格使用 AnolisOS 23.4 默认仓库进行安装。

4.1 搜索和确认 Docker 包 首先,查看仓库中可用的 Docker 相关包。

# 搜索 docker 包
dnf search docker

# 通常你会看到类似以下的输出:
# ========================= 匹配:docker =========================
# docker.x86_64 : 用于自动部署容器化应用程序的开源平台
# docker-client.x86_64 : Docker 客户端工具
# docker-common.x86_64 : Docker 的通用文件
# docker-latest.x86_64 : Docker 的最新版本(可能不稳定)
# ...
# 注意:包名后跟的是架构。在龙芯上,应该是 .loongarch64 而非 .x86_64。
# 请确认有 docker.loongarch64 或类似的包。

# 更精确地查看 docker 包信息
dnf info docker

关键点 :确认找到的 docker 包架构是 loongarch64 。如果仓库中没有提供 LoongArch 架构的 Docker 包,那么默认仓库安装路径就走不通了,需要考虑从源码编译或其他可信的第三方仓库获取,这超出了本文“默认仓库”的范围。

4.2 安装 Docker 引擎 假设仓库中存在 docker.loongarch64 包,我们进行安装。这个包通常会作为元包,拉取所有必要的依赖,包括 containerd

sudo dnf install -y docker

安装过程中,请留意输出,看是否成功安装了 docker containerd runc 等包。

4.3 验证安装结果 安装完成后,检查 Docker 组件版本。

# 检查 Docker 客户端和服务端版本
docker version

# 检查 Docker 系统信息,这能显示很多关键配置
docker info

如果 docker version 命令报错(例如无法连接到 Docker 守护进程),这是正常的,因为服务还没启动。我们重点关注 docker info 命令是否能运行,但更关键的是后续启动服务。

5. 配置与启动 Docker 服务

安装完成只是第一步,正确的配置和启动才是关键。

5.1 启动并设置开机自启

# 启动 Docker 服务
sudo systemctl start docker

# 设置 Docker 服务开机自启
sudo systemctl enable docker

# 检查 Docker 服务状态
sudo systemctl status docker

status 命令应该显示 active (running) 。如果状态不是 active ,请使用 sudo journalctl -u docker --since “5 minutes ago” 查看详细日志,这通常是问题排查的第一步。

5.2 验证基础功能并排查“容器无法创建” 现在尝试运行一个最简单的容器来测试。我们使用一个极小的、支持多架构的镜像 hello-world 。但请注意,Docker Hub 上的 hello-world 镜像可能没有 LoongArch 版本。我们可以先测试 busybox ,它通常更可能有对应架构的版本,或者使用一个已知支持 LoongArch 的镜像。

# 尝试运行一个 busybox 容器,执行一个简单命令
sudo docker run --rm busybox:latest echo “Hello from LoongArch Docker!”

此时,你很可能遇到“容器无法创建”的相关错误。 别担心,这正是本文要解决的核心。错误信息可能多种多样,我们接下来进行系统化排查。

6. 系统性排查“容器无法创建”问题

请根据你遇到的错误信息,按以下顺序进行排查。

6.1 检查内核模块与存储驱动 首先,检查 Docker 使用的存储驱动,以及所需的内核模块。

# 查看 Docker 使用的存储驱动
docker info | grep “Storage Driver”

# 检查 overlay 内核模块是否加载
lsmod | grep overlay

# 如果未加载,尝试加载(需要内核支持)
sudo modprobe overlay

如果 Storage Driver 不是 overlay2 ,或者 overlay 模块无法加载,Docker 可能退回到 devicemapper vfs ,这些驱动在性能和功能上可能有问题,甚至导致容器创建失败。在 docker info 的输出中,如果看到关于存储驱动的警告,就需要配置 Docker 使用 overlay2

编辑 Docker 守护进程配置文件:

sudo vim /etc/docker/daemon.json

如果文件不存在,则创建它。添加以下内容以明确指定存储驱动(如果系统支持):

{
  “storage-driver”: “overlay2”
}

保存后,重启 Docker 服务:

sudo systemctl restart docker

再次运行 docker info 确认存储驱动已更改。

6.2 检查 cgroup 版本与配置 这是导致新版本系统容器启动失败的常见原因。

# 检查系统使用的 cgroup 版本
stat -fc %T /sys/fs/cgroup/

# 如果输出 “cgroup2fs”,则系统使用 cgroup v2。
# 如果输出 “tmpfs”,则可能使用 cgroup v1,或者需要检查 /sys/fs/cgroup/unified。

情况一:系统使用 cgroup v2,但 Docker 未适配。 Docker 较新的版本(大约 20.10 以后)对 cgroup v2 有较好支持。但如果你安装的仓库版本较旧,可能存在问题。查看 Docker 日志:

sudo journalctl -u docker | grep -i cgroup

如果日志中有 cgroup 相关的错误,可以尝试在 daemon.json 中添加配置,让 Docker 明确使用 cgroup v1 模式(如果内核支持混合模式):

{
  “exec-opts”: [“native.cgroupdriver=cgroupfs”]
}

更根本的解决方案 是确保 Docker 版本与系统 cgroup 版本兼容。如果问题依旧,可能需要考虑升级内核或寻找更新的 Docker 包。

情况二:cgroups 未正确挂载。 检查 /sys/fs/cgroup 目录内容。确保必要的控制器(如 cpu , memory , pids )目录存在。有时在虚拟化或特殊环境中需要手动确保 cgroups 已启用。

6.3 检查用户权限 如果你没有使用 sudo 运行 docker 命令,可能会遇到权限错误。

# 将当前用户加入 docker 组(请将 `your_username` 替换为你的实际用户名)
sudo usermod -aG docker your_username

# 重要:退出当前终端并重新登录,或者开启一个新的终端会话,以使组权限生效。

重新登录后,尝试不加 sudo 运行 docker run --rm busybox echo “test”

6.4 检查 SELinux/AppArmor 安全模块可能会阻止容器进程访问必要的资源。

# 检查 SELinux 状态
getenforce

# 如果输出 “Enforcing”,可以尝试临时设置为宽松模式进行测试
sudo setenforce 0
# 然后再次尝试创建容器

如果容器在 setenforce 0 后能成功创建,说明是 SELinux 策略问题。你可以选择:

  1. 永久禁用 SELinux(不推荐用于生产环境):编辑 /etc/selinux/config ,设置 SELINUX=disabled ,然后重启。
  2. 为 Docker 容器配置正确的 SELinux 策略(推荐但复杂)。对于快速测试和开发,临时禁用或设置为 Permissive 模式是可接受的。

AnolisOS 可能默认使用 SELinux。AppArmor 在 RHEL/CentOS 系发行版中较少默认启用,但也可以检查: sudo aa-status

6.5 检查容器镜像架构 确保你拉取的镜像有 LoongArch 版本。使用 docker pull 时,Docker 会尝试拉取与宿主机架构匹配的镜像。

# 拉取镜像时,可以显式指定平台(如果镜像支持多架构)
docker pull --platform linux/loong64 busybox:latest

# 查看镜像的架构信息
docker image inspect busybox:latest --format=‘{{.Architecture}}’

如果输出不是 loong64 loongarch64 ,而是 amd64 x86_64 ,那么你拉取的是错误的架构镜像,无法在龙芯上运行。你需要寻找明确支持 linux/loong64 平台的镜像。

6.6 深入查看 Docker 守护进程日志 如果以上步骤都无法解决问题,最后的法宝是查看详细的 Docker 守护进程日志。

# 查看 Docker 服务的全部日志(实时)
sudo journalctl -u docker -f

# 或者查看最近发生的错误
sudo journalctl -u docker --since “today” | grep -E “(error|fail|exception|panic)” -i

在尝试创建容器时,同时打开一个终端运行 sudo journalctl -u docker -f ,然后在另一个终端运行失败的 docker run 命令。观察日志中输出的具体错误信息,这通常是解决问题的直接线索。常见的错误可能涉及 iptables seccomp 配置文件缺失、 /var/run/docker.sock 权限问题等。

7. 完整示例:从安装到运行一个 LoongArch 容器

假设我们已通过上述排查解决了所有问题。现在,让我们完整地运行一个实际的容器。

7.1 拉取一个已知支持 LoongArch 的镜像 我们可以使用由社区维护的、提供多架构支持的镜像,例如 nginx 的官方镜像通常支持多架构。但最保险的是使用龙芯生态中已知的镜像。例如,我们可以尝试运行一个基础的 LoongArch 发行版容器(如果存在),或者使用 busybox (它通常有广泛的架构支持)。

# 1. 拉取 busybox 镜像
docker pull busybox:latest

# 2. 运行一个交互式 shell 进行验证
docker run -it --rm busybox:latest /bin/sh

在容器内执行:

# 查看容器内的架构
uname -m
# 应该输出 loongarch64 或类似的标识

# 执行一些简单命令
echo “Hello, LoongArch Docker Container!”
exit

7.2 编写一个简单的 Dockerfile 并构建镜像 为了更贴近实际开发,我们创建一个简单的应用并打包。

# 创建一个项目目录
mkdir ~/my-loongapp && cd ~/my-loongapp

# 创建一个简单的 Python 应用(假设系统已安装 Python3)
cat > app.py << ‘EOF’
#!/usr/bin/env python3
import platform
import socket
import os

print(“=== LoongArch Docker Container Info ===“)
print(f”Architecture: {platform.machine()}“)
print(f”Hostname: {socket.gethostname()}“)
print(f”Current Directory: {os.getcwd()}“)
print(“=======================================“)
EOF

# 创建 Dockerfile
cat > Dockerfile << ‘EOF’
# 使用一个支持 LoongArch 的基础镜像,例如 anolisos
# 注意:你需要确认 anolisos:23.4 或类似标签的镜像在 Docker Hub 或你的私有仓库中存在且支持 loongarch64
# 这里以 busybox 为例,因为它更通用,但缺少包管理器。
# 更好的选择是寻找基于 LoongArch 的 Alpine、Debian 或 Ubuntu 基础镜像。

FROM busybox:latest

WORKDIR /app
COPY app.py .

# 因为 busybox 镜像可能没有 python,我们直接 cat 文件来演示。
# 在实际项目中,应使用包含所需运行时的基础镜像。
CMD [“cat”, “/app/app.py”]
EOF

# 构建镜像(注意最后的点号)
docker build -t my-loongapp:latest .

# 运行自定义镜像
docker run --rm my-loongapp:latest

这个例子展示了构建流程。关键在于 FROM 指令必须使用支持 LoongArch 的基础镜像。你需要根据你的应用需求,在 Docker Hub 或其他镜像仓库中寻找合适的、标签包含 linux/loong64 的基础镜像。

8. 常见问题与排查思路速查表

问题现象 可能原因 排查命令/步骤 解决方案
docker run 报错: exec format error 容器镜像架构与宿主机不匹配。 docker image inspect <image> --format=‘{{.Architecture}}’ 拉取支持 linux/loong64 的镜像,或构建自己的镜像。
docker run 报错: failed to create shim task: OCI runtime create failed: ... 1. runc 版本不兼容或损坏。
2. cgroup 配置问题。
3. 内核版本过低。
sudo journalctl -u docker -f 查看具体错误。
runc --version
uname -r
1. 重装或更新 containerd runc
2. 检查并配置 cgroup (见6.2)。
3. 升级内核。
docker run 报错: driver failed programming external connectivity ... iptables iptables 规则冲突或 Docker 的 iptables 管理失败。 sudo iptables -L -n
sudo systemctl restart docker
1. 重启 Docker 服务。
2. 检查防火墙是否阻止了 Docker。
3. 在 daemon.json 中设置 “iptables”: false (不推荐,除非必要)。
docker run 报错: permission denied while trying to connect to the Docker daemon socket 当前用户不在 docker 组。 groups $USER 执行 sudo usermod -aG docker $USER ,并 重新登录
Docker 服务启动失败 ( systemctl status docker 显示 failed) 1. 存储驱动配置错误。
2. 依赖服务未启动。
3. 配置文件语法错误。
sudo journalctl -u docker -xe 1. 检查 /etc/docker/daemon.json 语法。
2. 检查存储驱动和内核模块。
3. 查看完整日志定位具体错误行。
容器启动后立即退出 1. 容器内主进程执行完毕退出。
2. 镜像中指定的 CMD ENTRYPOINT 不存在或无法执行。
docker logs <container_id> 1. 使用交互式模式运行 docker run -it ... /bin/sh 检查镜像内容。
2. 确保 Dockerfile 中的 CMD 命令正确。
容器内无法访问外网 1. Docker 的 DNS 配置问题。
2. 宿主机防火墙或网络策略。
docker run --rm busybox nslookup baidu.com 1. 在 daemon.json 中配置 DNS,如 {“dns”: [“8.8.8.8”, “114.114.114.114”]}
2. 检查宿主机 firewalld iptables 规则。

9. 最佳实践与工程建议

在龙芯平台上使用 Docker 进行开发或部署,遵循以下实践可以避免很多麻烦:

  1. 镜像来源管理

    • 优先使用已知支持 LoongArch 的官方镜像 :在 Docker Hub 上查找镜像时,关注其 Tags 页面,看是否有 linux/loong64 架构的标签。
    • 建立私有镜像仓库 :对于企业环境,建议搭建私有镜像仓库(如 Harbor),并将经过验证的、支持 LoongArch 的基础镜像和业务镜像推送上去,保证供应链安全。
    • 多阶段构建 :在构建自己的应用镜像时,使用多阶段构建,确保最终镜像使用正确的 LoongArch 基础镜像,并且不包含构建依赖的无关文件。
  2. Docker 守护进程配置

    • 固化配置 :将调试好的配置(如存储驱动、DNS、日志驱动、cgroup 驱动等)写入 /etc/docker/daemon.json ,并做好版本管理。
    • 日志轮转 :默认的日志驱动 json-file 可能产生大量日志,在生产环境配置日志轮转和大小限制。
      {
        “log-driver”: “json-file”,
        “log-opts”: {
          “max-size”: “10m”,
          “max-file”: “3”
        }
      }
      
  3. 资源限制与监控

    • 使用 docker run -m , –cpus 等参数为容器设置资源限制,防止单个容器耗尽主机资源。
    • 龙芯平台同样可以使用 cAdvisor Prometheus 等工具监控容器资源使用情况,但需要确认这些监控工具是否有 LoongArch 版本或能否从源码编译。
  4. 数据持久化

    • 使用 Docker 卷( volumes )或绑定挂载( bind mounts )来持久化容器内的重要数据。避免将数据存储在容器的可写层,因为容器删除后数据会丢失。
    • 确保挂载的宿主机目录对容器内进程有适当的读写权限。
  5. 安全考虑

    • 避免容器内使用 root 用户 :在 Dockerfile 中使用 USER 指令指定一个非 root 用户来运行应用。
    • 定期更新 :关注 AnolisOS 安全更新和 Docker 相关包的更新,及时修补漏洞。
    • 最小化镜像 :移除镜像中不必要的工具、库和文件,减少攻击面。
  6. CI/CD 集成

    • 在基于龙芯的 CI/CD 流水线中,需要确保构建节点(Runner)的环境与本文所述一致。构建出的镜像应打上 linux/loong64 的架构标签。

在龙芯 3B6000 上成功运行 Docker,标志着你能在这个自主可控的平台上利用成熟的容器化生态进行应用开发、测试和部署。这个过程的核心挑战不在于 Docker 命令本身,而在于对底层架构差异、操作系统配置和软件包依赖的深入理解。

本文带你系统性地走通了从安装、配置、排错到验证的完整路径。最关键的一课是: 当通用教程失效时,学会从原理和日志出发进行排查 。记住几个关键检查点:内核模块、cgroup版本、用户组权限、SELinux状态以及镜像架构。

下一步,你可以探索更复杂的容器编排工具(如 Docker Compose)在龙芯上的使用,或者研究如何将现有的 x86 应用镜像迁移到 LoongArch 架构。随着龙芯生态的日益完善,相信会有越来越多官方和社区镜像提供原生支持,让容器化技术在国产化平台上的应用更加顺畅。建议你将本文中验证成功的 daemon.json 配置、基础镜像列表记录下来,形成团队内部的知识库,为后续项目铺平道路。

更多推荐