简介:面向银河麒麟v10 sp1 Server国产化服务器运维人员,提供在ARM架构下通过yum安装Docker的可操作性手册。资源聚焦于解决官方源缺少docker server软件包、系统依赖组件无法匹配新版Docker等问题,给出配置阿里docker-ce源与麒麟官方源的具体步骤,并引导安装docker-ce-cli与docker-ce 18.09.7、启动服务及验证版本。整个资源包仅含1个docx文档,大小17KB,篇幅精简,命令可直接复制,适合现场实施时对照执行。文档按配置yum源、安装、启动、查看版本的顺序展开,并专门记录了尝试安装最新版Docker时因缺少container-selinux依赖而失败的报错实例,帮助读者规避同类版本兼容性陷阱。目前已有7000余人学习下载,可作为银河麒麟v10 sp1 Server环境下部署Docker的快速参考。
1. 银河麒麟V10 SP1 Server 装 Docker:先选对路线,再敲命令
银河麒麟V10 SP1 Server 上装 Docker,最容易翻车的不是命令敲错,而是你选的安装源根本不认麒麟这个发行版。信创机房交付时,我见过太多同行卡在同一个地方:x86 服务器、内网环境,有 Kylin 源但没有 docker 源;或者外网环境配了官方 docker 源,apt update 直接 404。这个坑的根源在于麒麟 V10 改动了自己的 codename,而 Docker 官方源的路径是按 Ubuntu 版本生成的,两者对不上就白折腾一下午。
这篇笔记按一条可以直接抄的落地路径来讲:先教你在装机前把内核、架构、源列表确认清楚,再给在线安装和离线安装两条完整命令链路,最后把启动失败、iptables 冲突、容器上不了外网这类高频问题逐个拆掉。虚拟机上实验和物理机真装都一样适用。适合三类人:正在做国产化替换的运维、要给内网交付容器环境的实施工程师,以及刚接手 Kylin 服务器还没摸清底细的新手。
2. 装之前先摸清家底:内核、架构、源列表决定了你走哪条安装路线
2.1 确认系统版本与 CPU 架构:apt update 之前先看这三条命令
在麒麟上装 docker,第一个动作永远是确认自己拿到的到底是什么系统。很多人拿着 V10 的安装盘装上,以为自己是 x86 的 Ubuntu 20.04,结果拿的是飞腾 ARM 版;还有人机器是新的,但系统自带了一个旧版 docker.io,后面新旧 daemon 抢 socket 冲突。先看状态再动手:
# 查看发行版信息:VERSION_ID、VERSION_CODENAME 决定你该用哪个 docker 源 cat /etc/os-release # 查看内核:Docker 要求内核 3.10 以上,overlay2 存储驱动需要 4.0+ uname -r # 查看架构:x86_64 还是 aarch64,决定下载哪个平台的 deb 包 arch这三条命令的输出,分别在后面几个环节使用。/etc/os-release里的VERSION_CODENAME用来映射 docker-ce 源的路径:麒麟 V10 SP1 的 Server 版一般基于 Ubuntu 20.04,对应代号 focal,但部分批次会显示麒麟自定义代号,这会直接导致 docker-ce 源 404;uname -r看内核是否支持 docker 需要的 overlay 和 netfilter 模块,我见过内核 4.19 的老批次机器跑 docker 25.x 没问题,但个别容器启动偶尔报错,后面第 5 章会展开;arch的 x86_64 还是 aarch64,在离线安装章节要用到,别把 amd64 的包往 ARM 机器上拷。
如果你拿到手的是桌面版的机器,先确认它是不是 Server 版:桌面版带了麒麟安全管理工具,默认策略会拦截 docker 的不少动作,生产环境建议一律使用 Server 版镜像重装。这条建议来自实际项目里的踩坑经验,不是危言耸听。
2.2 三种安装路线的选型:docker-ce 官方源、麒麟软件源、离线部署包
搞清楚系统状态之后,按网络条件选择路线。我一般把安装场景分成三类,对应三种完全不同的操作方式:
| 网络条件 | 推荐路线 | 装出来的版本 | 风险点 |
|---|---|---|---|
| 能访问公网且有内网镜像站 | 配置阿里云 docker-ce 源在线安装 | docker-ce 24.x 及以上 | 麒麟 codename 导致 404,需手动指定 focal |
| 只有麒麟官方源,无 docker 源 | 直接用apt install docker.io | 19.x/20.x 系列老版本 | 功能旧,但稳定;不支持新版 compose v2 |
| 完全无网内网环境 | 联网机器下载 deb 包,U 盘拷入安装 | docker-ce 24.x 及以上 | 依赖包要一次拉齐,签名校验可能拦截 |
表格里最后一行是大多数信创项目的真实状态。很多内网环境连 apt 源都不通,只有一台被安全审计过的跳板机可以出网,那第 4 章的离线方案就是你唯一的选择。我遇到不少实施人员,在无网环境硬试在线安装脚本,在 apt update 阶段卡半小时,最后才换离线路线——白白浪费一个晚上。先判断网络条件再动手,这笔时间省得值。
第二条路线apt install docker.io看起来最省事,但它装的是麒麟源里打包的老版 docker,通常停留在 19.03 到 20.10 这个区间。如果你的业务只需要跑几个常规镜像、不依赖 BuildKit、也不需要 compose v2,这条路线其实最稳,毕竟它和麒麟系统一起做过适配。但既然目标是“安装 docker 手册”,社区版 docker-ce 才是主线,下面第三章按这个来。
2.3 安装前的 3 个系统前置检查:模块、端口、存储驱动
正式安装之前,再花两分钟做三个检查,避免装到一半才发现系统层面不支持。
第一,加载br_netfilter模块并确认内核参数。docker 的 bridge 网络依赖它把 iptables 规则作用到桥接流量上,麒麟 Server 的裁剪版内核有时候不加载这个模块:
# 加载桥接过滤器模块,docker 网络依赖它 modprobe br_netfilter lsmod | grep br_netfilter # 确认内核参数,输出 1 才是对的 sysctl net.bridge.bridge-nf-call-iptables第二,如果系统里已经装了旧版 docker.io,先卸掉再装 docker-ce,否则两个 daemon 会抢 /var/run/docker.sock,装完你会发现 docker 命令时好时坏:
# 查看是否已有旧 docker 包 dpkg -l | grep docker # 有的话先移除,保留配置文件不删 apt-get remove -y docker.io docker-engine第三,确认存储空间。docker 的数据目录默认在/var/lib/docker,如果/var所在分区没空间,装完第一个镜像就会报no space left on device。至少预留 20GB,且优先把数据目录放到单独挂载的数据盘,这个迁移在第 6 章会给出具体做法。
3. 在线安装 Docker CE:阿里云源三步走,绕开麒麟 codename 的 404
3.1 先装基础依赖:ca-certificates 和 curl 是唯一前置
在线安装的第一步,不是直接加 docker 源,而是把 apt 的基础组件补齐。麒麟 Server 的精简安装很多时候连 curl 都没有,后面的 GPG key 下载会直接卡住:
# 更新索引,为后续安装做准备 apt-get update # 安装证书与下载工具,curl 用来拉取 docker 的 GPG key apt-get install -y ca-certificates curl gnupg lsb-release解释一下为什么需要这几个包:ca-certificates保证 curl 访问 HTTPS 镜像站时证书校验能通过,没有它你会看到一堆 SSL 报错;curl是拉取 GPG key 的工具;gnupg提供gpg --dearmor命令,把 ASC 格式的 key 转成 apt 能识别的二进制;lsb-release本意是给脚本自动识别发行版代号用的,但在麒麟上它的返回值不可靠,我们只是顺手装上,不依赖它。
如果你的服务器连的是内网自建的 apt 镜像源,把apt-get update换成指向内网源的命令即可,后面的 docker-ce 源如果内网也有缓存,就把 URL 也替换成内网地址。这些命令在 x86 和 ARM 上通用,不需要改任何参数——这是在线安装比离线省心的一个点。
3.2 添加 docker-ce 源:手动指定 focal,别用 lsb_release 的自动返回值
这一步是整个在线安装里唯一容易翻车的地方。Docker 官方和阿里云镜像站的源路径,格式是docker-ce/linux/ubuntu/<codename>/stable,麒麟 V10 SP1 如果改了系统代号,直接写在源里会导致 apt update 报 404。我通常的做法是手动指定 focal,V10 SP1 的 Server 版基本对应 Ubuntu 20.04 这个代号:
# 创建密钥目录,install 写法比 mkdir 更符合规范 install -m 0755 -d /etc/apt/keyrings # 拉取 Docker GPG key,转成 apt 可识别的二进制格式 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg # 给密钥文件设置读权限,apt 要求必须可读 chmod a+r /etc/apt/keyrings/docker.gpg # 写入 docker-ce 源,codename 手动写 focal echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu focal stable" > /etc/apt/sources.list.d/docker-ce.list # 刷新索引,看到 docker-ce 相关包说明源生效 apt-get update如果你拿到的麒麟批次不是 focal 这一代,把最后一行源里的focal改成bionic再apt-get update试一次。判断依据是/etc/os-release里VERSION_CODENAME的值。这里不建议用$(lsb_release -cs)自动填充,因为麒麟的返回值常是空或者自定义代号,写死反而可控。
dpkg --print-architecture这条命令会自动输出 amd64 或 arm64,保证 ARM 服务器上生成的源路径也是对的。apt 的signed-by参数指定用哪个密钥验证这个源,这样多源共存时不会串 key。
3.3 安装并启动 docker-ce:装完先做版本隔离
源配好之后,安装本身非常简单,但有一个细节值得注意——安装命令要带上containerd.io,这是新版 docker 的容器运行时,缺了它 dockerd 起不来:
# docker-ce 是 daemon,docker-ce-cli 是命令行,containerd.io 是运行时 apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 启动并设置开机自启 systemctl start docker systemctl enable docker # 验证版本与运行状态 docker version docker info四条命令解释一下:docker-ce是核心 daemon,docker-ce-cli是docker命令行工具,containerd.io是底层运行时,三者版本必须一致才能正常工作。docker-buildx-plugin和docker-compose-plugin是增强插件,如果业务只跑现成镜像,后两个可以不装,但我建议装上,因为用docker compose管理服务比裸docker run好维护太多。
启动后第一件事,docker info看Storage Driver是不是overlay2,以及Cgroup Driver是不是systemd。这两个值决定后续容器运行是否稳定。如果 Storage Driver 显示的是vfs,说明内核的 overlay 模块没加载,回到 2.3 节把模块补上再重启 docker:
# 确认 overlay 模块已加载,再重启 docker modprobe overlay systemctl restart docker4. 无网环境安装 Docker:一台联网机器把依赖一次拉齐,U 盘带进内网
4.1 在联网机器上按架构拉取安装包:--download-only 的正确用法
无网部署是最接近信创内网真实状态的场景。做法分两段:先在联网机器上把安装包全部拉下来,再把包带到目标内网机器安装。联网机器最好选择与目标机相同架构、相同系统的麒麟或 Ubuntu 20.04,这样拉下来的依赖不会因 glibc 版本差异而装不上:
# 在联网机器上,先加载 docker-ce 源(方法见 3.2 节) # 只下载不安装,docker-ce 及全部依赖都会进入 /var/cache/apt/archives apt-get install --download-only -y docker-ce docker-ce-cli containerd.io # 查看下载的包,确认版本与架构 ls -lh /var/cache/apt/archives/*.deb # 拷贝到一个统一目录,方便整包转移 mkdir -p /root/docker-debs cp /var/cache/apt/archives/*.deb /root/docker-debs/--download-only的效果是:apt 会解析依赖,把“这台机器上现在还缺的”deb 包全部下载下来,但不会执行安装。这里有一个坑:如果联网机器本身已经装了某个依赖库,apt 就不会下载它,而目标机器可能恰恰缺这个库。规避办法是,拿目标机器的包清单对照一遍:
# 在目标机器上导出现有包列表 dpkg -l | awk '{print $2}' > /root/target-pkgs.txt # 在联网机器上逐项确认 deb 目录里有没有清单外的库(决定是否补下载)在实际交付中,我见过因为 libseccomp2 版本不一致导致容器全程跑不起来的情况。所以离线装完 docker 之后,第 6 章的验证环节不能省,先把一个真实业务容器跑通再交工。
4.2 内网目标机器离线安装:dpkg -i 的顺序与 deepin-elf-verify 签名问题
把/root/docker-debs整个目录拷进内网机器,然后开始离线安装:
# 进入 deb 目录,按文件名顺序安装;dpkg 会自动处理包间的依赖关系 cd /root/docker-debs dpkg -i *.deb # 如果报缺依赖,先看具体的缺失包名,再决定补哪种包 apt-cache policy libseccomp2dpkg -i *.deb会一次性尝试安装所有 deb,只要目录里包含全部依赖,dpkg 自己就能完成依赖解析。但有几个情况会让你在这个环节翻车。
现象一,报错信息里带deepin-elf-verify字样,deb 包被拒绝安装。这是麒麟系统自带的二进制安全校验组件在做包签名检查,非官方渠道的 docker-ce deb 包会被拦。处理办法是:先用 apt 更新 deepin-elf-verify 组件再重试;如果内网连不上麒麟源,就改用 docker 官网的 static 二进制 tar 包,绕过 dpkg 校验,代价是要手工补 systemd 服务文件。
现象二,报dependency is not satisfiable: xxx。这说明 4.1 节里拉包不完整,按缺失的包名回到联网机器补拉。不要在内网机器上硬装--force-depends,那会把 docker 装成一个残缺状态,容器运行时大概率崩。
现象三,dpkg 安装成功后systemctl start docker报Failed to connect to bus。这通常是 dbus 服务异常,检查 systemd 状态后重启 dbus 再启 docker:
systemctl start dbus systemctl restart docker4.3 配套镜像离线迁移:docker save 与 docker load,内网镜像仓库同步搭
内网机器装好 docker 之后,最容易被忽略的一步是镜像从哪来。内网没有镜像站,docker pull一定会失败。常见做法是在联网机器上把业务镜像导出,带进内网再导入。我通常用 gzip 压缩后传输,体积能小一半以上:
# 在联网机器上,先拉取镜像并导出为 tar.gz docker pull mysql:8.0 docker save mysql:8.0 | gzip > mysql-8.0.tar.gz # 传到内网机器后导入;load 完成后 docker images 可见 docker load -i mysql-8.0.tar.gz注意docker save导出的是镜像本身,不能覆盖容器运行后写入的数据;如果业务容器里有新增数据,要用数据卷备份,这是另一套方案,这篇笔记不展开。多台内网机器要重复部署时,我习惯在一台机器上docker save,然后通过内网共享目录分发 tar 文件;如果内网机器数量超过三台,就去搭一个 registry 容器做私有镜像仓库,用docker pull的方式分发,省掉来回拷 tar 的体力活:
# 用 docker 启动私有 registry,端口 5000 docker run -d --name registry --restart=always -p 5000:5000 -v /data/registry:/var/lib/registry registry:2提示:搭建 registry 后记得在每台内网机器的
/etc/docker/daemon.json里加"insecure-registries": ["registry-server:5000"],否则 docker 默认拒绝 HTTP 协议的私有仓库。
5. 启动与常驻避坑:Docker 在麒麟 Server 上最容易翻车的 5 个点
5.1 容器秒退:libseccomp2 版本太老,runc 拒绝执行
现象:docker run返回容器 ID,但docker ps -a看到容器状态是Exited (0)或Created;查journalctl -u docker能看到 runc 相关的权限或调用错误。
原因:麒麟源里的libseccomp2若停留在 2.4.x,而新版 docker-ce 里的 runc 对 seccomp 支持有更高要求,容器创建时安全隔离初始化失败。
解决:
# 先查版本 dpkg -l | grep libseccomp # 版本低于 2.5 时,从联网机器下载 libseccomp2 的高版本 deb # dpkg -i libseccomp2_2.5.x_amd64.deb注意:升级 libseccomp2 后一定要重启 docker,不是重启容器。这个组件是系统级共享库,只重启容器不生效。
5.2 端口映射报 iptables failed:麒麟安全基线把 nat 表锁住了
现象:docker run -p 8080:80创建容器后端口不通,或者启动时直接报iptables failed: iptables --wait -t nat -A DOCKER ... Operation not permitted。
原因:麒麟 Server 的安全基线或 firewalld 服务在 docker 启动前预置了 iptables 规则,docker 想在 nat 表里插入自己的链但没有权限,或者 IPv6 的 NAT 模块没加载。
解决:按顺序排查——
# 查看防火墙状态,如果是 active,先临时停掉验证 docker 是否恢复 systemctl status firewalld systemctl stop firewalld # 确认 br_netfilter 已加载,并打开桥接流量转发 modprobe br_netfilter sysctl -w net.bridge.bridge-nf-call-iptables=1 # 确认 IPv6 NAT 模块(4.19 内核常见) modprobe ip6table_nat systemctl restart docker如果确认是 firewalld 冲突,并且生产环境不能关掉防火墙,就把 docker 使用的端口加入 firewalld 放行列表,不要让 docker 自己接管 iptables,这是安全且折中的做法。
5.3 容器内上不了外网:ip_forward 没开,或者被系统重启重置
现象:容器启动正常,docker exec进入容器后 ping 网关能通,但 curl 外网超时;宿主机的docker pull也慢到超时。这正是运维群里最常见的“docker网络不通”。
原因:docker 的桥接网络依赖宿主机net.ipv4.ip_forward=1,麒麟 Server 精简配置里默认关闭;重启后 sysctl 配置没有持久化,所以每次重启都要重新开。
解决:一次性配置并持久化:
# 临时生效 sysctl -w net.ipv4.ip_forward=1 # 永久生效:写入 sysctl 配置 echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/docker.conf # 重新加载并重启 docker sysctl -p /etc/sysctl.d/docker.conf systemctl restart docker如果容器内能 ping 通 IP 但域名解析失败,那是 DNS 问题,在/etc/docker/daemon.json里加"dns": ["223.5.5.5", "114.114.114.114"],内网环境改成内网 DNS。
5.4 镜像拉取慢与加速器失效:daemon.json 的常见写法错误
现象:docker pull卡住或超时;docker info里看不到 Registry Mirrors 生效。
原因:/etc/docker/daemon.json里写了不规范的镜像加速地址,或者 JSON 格式错误导致整个 daemon 读取失败,dockerd 会忽略全部配置。
解决:用一个可以被公网访问的加速器,并保证 JSON 语法通过校验:
{ "registry-mirrors": ["https://docker.m.daocloud.io"], "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "data-root": "/data/docker" }配置写好后:
# 先校验 JSON python3 -m json.tool /etc/docker/daemon.json # 再重启 docker systemctl restart docker docker info 2>/dev/null | grep -A2 "Registry Mirrors"内网环境下不要依赖任何公网加速器,直接在内网搭 registry 或把镜像 tar 包导入,这才是真正可靠的路径。
5.5 重启后 docker 起不来且网络异常:systemd 启动顺序与 iptables 被清空
现象:服务器重启后systemctl status docker显示 failed,错误信息里出现No chain/target/match by that name;或者 docker 起来了,但容器全都没有网络。
原因:docker 启动时 iptables 规则尚未建立,或 firewalld 在 docker 之后启动并清空了它建的链。这和 5.2 是“同一事故的两个方向”。
解决:确认 docker 服务与防火墙服务的先后关系,并设置正确顺序:
# 查看 docker 服务单元里对防火墙服务的依赖 systemctl cat docker.service | grep -E "After|Wants" # 设置 docker 开机自启 systemctl enable docker如果 firewalld 不参与生产防火墙策略,可以禁用它,减少启动顺序的变数:
systemctl disable firewalld禁掉 firewalld 之后,如果服务器本身还需要端口防护,就用 iptables 服务或 nftables 接管,并确保规则的写入顺序在 docker 之前。这个决策要根据公司的安全基线来定,不要图省事一刀切。
6. 装完只是开始:用 MySQL 8.0 验证环境,并把 Docker 固化成运维基线
6.1 跑一个 MySQL 8.0 验证环境:比 hello-world 可靠的真实业务验证
只跑 hello-world 验证不了端口映射、数据卷和日志驱动,所以我习惯用 MySQL 8.0 做验收容器,它几乎覆盖了生产容器会碰到的全部能力点:
# 先准备环境变量文件,避免密码留在 shell history 里 cat > /data/mysql/mysql.env <<'EOF' MYSQL_ROOT_PASSWORD=Your_Strong_Pass_2026 MYSQL_DATABASE=appdb EOF # 启动 MySQL,指定端口、数据卷与字符集 docker run -d --name kylin-mysql \ --restart=always \ --env-file /data/mysql/mysql.env \ -p 3306:3306 \ -v /data/mysql/data:/var/lib/mysql \ mysql:8.0 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci # 等待 30 秒后验证进程与日志 sleep 30 docker ps | grep kylin-mysql--restart=always保证宿主机重启后容器自动拉起,这是生产容器的最低要求;--env-file比-e写在命令里更安全,防止密码出现在docker inspect的明文参数里;-v把数据放在数据盘而不是容器可写层,避免容器删了数据全没。
6.2 把 Docker 固化成运维基线:钉版本、迁数据目录、备份 daemon.json
三个习惯。第一,装完立刻钉住版本,防的是麒麟源里的旧 docker.io 在系统升级时顶替掉 docker-ce;第二,数据目录迁移到数据盘,避免系统盘写满连带宿主机崩溃;第三,改动 daemon.json 前先备份,出了问题三分钟回滚:
# 钉住版本,防止 apt upgrade 误升级 apt-mark hold docker-ce docker-ce-cli containerd.io # 停服后迁移数据目录,软链接回原路径 systemctl stop docker mv /var/lib/docker /data/docker-data ln -s /data/docker-data /var/lib/docker systemctl start docker钉版本和迁数据目录这两步,是我接手麒麟服务器第一天就做的固定动作。这套流程之后,docker 相关的问题几乎不用半夜爬起来处理。希望帮到你。
本文还有配套的精品资源,点击获取