银河麒麟V10 aarch64 Docker安装与版本锁定实践 简介面向在国产化服务器上部署容器环境的中高级运维人员这份手册聚焦银河麒麟 V10 SP1 Server 缺少官方 docker server 软件包的实际困境给出可落地的安装路径。内容围绕第三方阿里源与麒麟官方源的双源配置展开逐步记录 docker-ce-cli 与 docker-ce 18.09.7 的安装、服务启动及版本验证并特别说明新版 docker 因 container-selinux 依赖无法满足而安装失败的报错与取舍便于读者少走弯路。资源包仅含 1 个 docx 文件约 17KB篇幅精炼按目录分为配置 yum 源与通过 yum 安装 docker 两部分适合边操作边对照。目前已有 7220 人学习下载可作为国产化平台容器部署的排错参考与步骤清单。1. 一套 aarch64 服务器上的 Docker 安装卡住的往往不是命令国产化替代的项目里给银河麒麟 V10 SP1 Server 装 Docker最容易出问题的地方几乎从来不在命令本身。yum install docker-ce这条路谁都认得但真正让人卡上半天的是两个问题系统官方源里根本没有 docker-ce第三方源 aarch64 目录下最新版又依赖一个系统里装不上的 container-selinux。这份手册给出的解法是把版本固定在 18.09.7-3.el7用两个源凑齐依赖关系再把安装拆成 cli → ce 两步走。它适合手里有一台麒麟服务器、要在这上面跑容器但不想从源码编译的人也适合要给一批机器做批量部署、需要一套能复现步骤的运维。2. 配两个 yum 源baseurl 里那个7和$basearch填错就全盘皆输2.1 先接受「官方源里没有 docker-ce」这个事实麒麟 V10 SP1 的包管理是 rpm dnf$releasever在这套系统上会解析成10而 docker-ce 的仓库目录只按 CentOS 的7和8两套组织。这就意味着 baseurl 里必须手写死centos/7一旦照抄网上那种$releasever的写法dnf 会拼出.../linux/centos/10/aarch64/stable/这种路径然后给你一个 404 或者Failed to download metadata for repo。这是第一个坑也是最不值得踩的一个坑。第二个事实是 aarch64 上的 docker-ce 版本比 x86_64 少得多。20.10 系列起docker-ce对container-selinux 2:2.74是硬依赖而这个包在麒麟的官方源里要么没有、要么版本停在更低的号上dnf 解析依赖时就只能报「nothing provides」。理解了这两点后面的所有配置就都是在给依赖关系做补全。2.2 docker-ce.repo 的五个字段逐个拆开仓库文件放在/etc/yum.repos.d/下文件名随便起但建议带.repo后缀内容按下面写。镜像站的主机名我留了占位符换成你能连通的国内公开镜像站即可注意路径部分别改# /etc/yum.repos.d/docker-ce.repo [docker-ce-stable] nameDocker CE Stable - 7 # 关键是 centos/7 这一段不能用 $releasever否则会解析成 10 # $basearch 在 aarch64 机器上会自动展开成 aarch64不用手写 baseurlhttps://mirror-host/docker-ce/linux/centos/7/$basearch/stable enabled1 # gpgcheck 和 gpgkey 必须成对出现只开 check 不给 key 会直接失败 gpgcheck1 gpgkeyhttps://mirror-host/docker-ce/linux/centos/gpg$basearch这层抽象值得单独说一句它取的是 rpm 的架构宏不是uname -m的原始输出在部分 arm 机器上uname -m给的是aarch64而宏可能是aarch64两者一致但如果你在 x86 上做交叉验证$basearch会变成x86_64路径自然就不同了。想确认展开结果用dnf repolist -v看实际请求的 URL 最稳。stable目录里放的是 GA 版本也就是正式发布版。同级的还有test和nightly除非你在做特性验证否则不要碰。另外还有一个细节docker-ce.repo一旦启用docker-ce、docker-ce-cli、containerd.io、docker-ce-rootless-extras这些包都会从这个源解析如果镜像站只同步了部分包就会出现「包找不到」的假象用dnf --showduplicates list docker-ce-cli能立刻分辨是源没同步还是版本号写错。2.3 麒麟官方源负责补全依赖关系第三方源只提供 docker 自己的包container-selinux、libcgroup、device-mapper-libs这些底层依赖仍然要从系统源拿。装过麒麟的系统/etc/yum.repos.d/下通常已经有一份名字类似kylin_aarch64.repo的文件先ls看一眼再动手别急着新建把原来的覆盖掉。仓库段大概长这样# 若系统自带则直接沿用不要重复新建同名文件 [ks10-os-media] name Kylin Linux Advanced Server 10 - Os # 地址从系统自带的 repo 文件或安装 ISO 里的 media.repo 抄别手敲 baseurl 官方源地址/v10/sp1-openstack-q/aarch64/os/ gpgcheck 0 enabled 1gpgcheck 0在这里是常见做法原因是内网或离线源的签名链经常没同步完整开了校验反而装不上。这是一个用安全性换可用性的取舍心里要有数能开校验就开开不了就把源地址限制在受控网段内。提示两个源的enabled必须同时为 1。有人配完 docker 源就把麒麟源整个注释掉结果container-selinux拉不到报错信息还停留在 docker 包上很容易误判成源地址写错了。2.4 刷新缓存并验证源真的生效配置写完不要直接装先花三十秒验证能省掉后面半小时的排查# 清掉旧缓存避免旧元数据干扰解析 dnf clean all # 重新拉取所有启用仓库的元数据 dnf makecache # 看仓库列表确认两个源都是 enabled 且 URL 展开正确 dnf repolist -v | grep -E docker-ce|kylin|Repo-baseurl # 只列 docker-ce 的可用版本倒序方便看最新的几个 dnf --showduplicates list docker-ce 2/dev/null | sort -r | head -20--showduplicates这个参数是关键默认list只显示每个包的最高版本而我们要找的恰恰是一个不在最高位的 18.09.7。如果这条命令的输出里看不到18.09.7-3.el7说明镜像站的 aarch64 目录没同步到这个版本换一个镜像站比继续折腾更快。3. 把版本钉在 18.09.7cli → ce 的两步安装与三条验证3.1 为什么不能一条yum install docker-ce了事直接敲yum install docker-ce时dnf 会在所有可用版本里挑「最优候选」也就是版本号最高的那个。在麒麟上这个候选通常是 20.10.x而它的依赖container-selinux 2:2.74在当前源里满足不了dnf 就抛出那条经典的cannot install the best candidate for the job。错误信息指向的是 docker-ce根因却在依赖包上这就是为什么很多人第一反应是源配错了。拆成两步的实际收益有三个第一docker-ce-cli的依赖树浅先装能把「源是否可用」这个变量单独隔离出来验证第二docker-ce对docker-ce-cli的版本要求是精确匹配18.09.7-3.el7 对 18.09.7-3.el7先把 cli 钉死第二步就不会被解析器拉到别的版本上去第三真出错时你能明确知道是 cli 阶段还是 daemon 阶段的问题。至于--skip-broken和--nobest这两个参数在报错信息里被 dnf 主动推荐但在这个场景下都是陷阱。--skip-broken会跳过装不上的包继续装结果就是 docker-ce 装上了、cli 没装docker命令直接不存在--nobest会让 dnf 退而求其次选低版本看起来成功了但选到哪个版本不可控。血泪经验是这两个参数只在明确知道后果时用排错阶段不要碰。3.2 安装、启动与开机自启# 1) 先装 CLI版本号写死-y 避免交互卡在脚本里 dnf install -y docker-ce-cli-18.09.7-3.el7 # 2) 再装 daemon 本体版本必须与 CLI 严格对齐 dnf install -y docker-ce-18.09.7-3.el7 # 3) 开机自启 立即启动一条命令搞定两件事 systemctl enable --now docker # 4) 看服务状态--no-pager 防止输出被 less 截住 systemctl status docker --no-pager第二步如果仍然报container-selinux相关错误说明麒麟源里确实没有满足条件的版本这时候的正确做法是去麒麟源里查一下现有版本dnf list container-selinux如果版本号低于2.74只能退回到 18.09.7 这条线别硬升级底层 selinux 包——那会牵动整个系统的安全策略风险远大于收益。systemctl enable --now是两件事的合并写法等价于systemctl enable docker systemctl start docker。有些老脚本里还会见到service docker start在 systemd 环境下不建议再用因为它绕过了 unit 文件里的ExecStartPre检查出问题时日志里看不到关键信息。3.3 三条验证版本、运行时状态、容器能跑起来# 版本号核对输出应为 18.09.7, build 2d0083d docker --version # 服务端信息重点看 Server Version、Storage Driver、Cgroup Driver docker info --format Server{{.ServerVersion}} Driver{{.Driver}} Cgroup{{.CgroupDriver}}docker info里三个字段值得逐个看。Server Version要和客户端版本一致不一致说明 cli 和 ce 装成了不同版本属于典型的「分两步装但第二步被解析到别的版本」Storage Driver在麒麟上一般是overlay2如果显示vfs或者devicemapper性能和磁盘占用都会差一个量级需要检查内核模块Cgroup Driver默认是cgroupfs这是后面接 Kubernetes 时最常见的改动点。真正跑通一个容器才算验证完成。内网机器拉不到公网镜像用save/load这组命令把镜像搬过去这是离线环境的标准做法# 在一台能联网、架构相同aarch64的机器上准备镜像 docker pull hello-world docker save hello-world -o hello-world.tar # 把 tar 拷到麒麟机器后导入 docker load -i hello-world.tar # 跑一次--rm 让容器退出后自动清理 docker run --rm hello-worlddocker save保留的是镜像的完整层结构和元数据docker export导出的是容器文件系统快照、会丢元数据两者别混用。导入后docker images看到的REPOSITORY和TAG可能与源端一致也可能变成none后者说明导出时用了错误的方式。4. 避坑排查五条从报错到修好的实录4.1 报错nothing provides container-selinux 2:2.74现象是dnf install docker-ce直接失败错误末尾提示try to add --skip-broken。原因是 dnf 选中了 20.10 系列作为最优候选而这个版本的硬依赖在麒麟源里满足不了。解决办法不是加参数跳过而是把版本降到 18.09.7 这条不依赖高版本 selinux 的线按 3.2 的两步走。如果业务上确实需要 20.10那就得单独编译或找一个适配的container-selinux包成本会高出很多。4.2Job for docker.service failed且日志停在 bridge 初始化现象是systemctl start docker失败journalctl -u docker -n 50里最后一行是Error initializing network controller: could not create bridge。原因通常是宿主机上已经有别的组件占用了docker0这个网段或者 firewalld 的 FORWARD 链策略是 DROP导致 bridge 建不起来。解决分两步先用ip addr show docker0确认网段冲突冲突就在daemon.json里改bip和default-address-pools没有冲突就检查iptables -L FORWARD -n的默认策略把它改成 ACCEPT 再重启服务。4.3 拉镜像超时或报x509: certificate signed by unknown authority现象是docker pull卡在Pulling from然后超时或者直连内网 registry 时报证书错误。前者的原因是默认走公网 registry内网根本不通后者是自建仓库用了自签证书。解决方式都在daemon.json里内网环境配registry-mirrors指向可达的加速地址自签证书的仓库把地址写进insecure-registries注意这里只写host:port不要带https://前缀带了反而不生效。4.4/var/lib/docker把根分区撑满系统起不来现象是跑了一段时间后df -h显示/使用率 100%systemctl各种服务开始报错。原因是镜像层、容器日志、volume 全默认落在/var/lib/docker而麒麟装机时根分区经常只给了几十 G。解决要分两步走先临时清理docker system prune -a腾出空间让系统恢复再把>{ exec-opts: [native.cgroupdriversystemd], data-root: /data/docker, log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, insecure-registries: [registry.internal:5000], registry-mirrors: [https://mirror-host], live-restore: true }逐个说exec-opts把 cgroup driver 从cgroupfs换成systemd这是后面上 Kubernetes 的前置条件早改早省事># 1) 停服务确保没有进程占用 /var/lib/docker systemctl stop docker # 2) 用 rsync 而不是 cp保留权限位和硬链接-a 归档模式 rsync -aHAX --progress /var/lib/docker/ /data/docker/ # 3) 确认大小对得上再删原目录别急着 rm du -sh /var/lib/docker /data/docker # 4) 改 daemon.json 的># 组已存在时 -f 不会报错 groupadd -f docker # 把用户加入 docker 组重新登录后生效 usermod -aG docker deploy # 当前会话立即生效省得退出重登 newgrp docker这里有个安全边界要说清楚docker组的成员等价于 root因为能挂载宿主机根目录进容器。所以这个组只给需要的人加别图省事给所有人开。防火墙这边麒麟默认跑 firewalld而 docker 会自己写 iptables 规则两者容易打架。最常见的表现是容器能启动但访问不了外网。稳妥做法是把docker0网卡放进 trusted 区# 把 docker0 加入 trusted 区避免被默认 zone 的规则拦掉 firewall-cmd --permanent --zonetrusted --add-interfacedocker0 firewall-cmd --reload反过来如果你需要限制容器只能访问特定网段就别用 trusted改成在DOCKER-USER链里写规则这条链是给用户自定义预留的容器重启不会把它冲掉。6. 让这套流程可重放版本锁、离线 rpm 与一张验收表单台机器装完就完事了一批机器就不一样了。第二批机器装的时候镜像站可能同步了新版本dnf install docker-ce-18.09.7-3.el7依然能装但docker-ce-cli如果没写版本号就会被拉到新版然后 cli 和 daemon 版本错位docker命令能敲但连不上 daemon。6.1 用 versionlock 把版本固定住# versionlock 在 dnf-plugins-core 里没装过要先装 dnf install -y dnf-command(versionlock) # 把两个包一起锁住少锁一个等于没锁 dnf versionlock add docker-ce-18.09.7-3.el7 docker-ce-cli-18.09.7-3.el7 # 确认锁生效 dnf versionlock list锁住之后dnf update不会动这两个包要升级必须先versionlock delete。这个习惯我建议在所有需要长期稳定运行的机器上都养成尤其是在源指向公开镜像站、版本随时会变的环境里。完全离线的场景还得把 rpm 提前下下来。dnf download --resolve --alldeps会把整棵依赖树拉齐注意必须在同架构、同系统版本的机器上下载x86 上下的包搬到 aarch64 上一个都装不上# 下载 docker 及其全部依赖到本地目录 dnf download --resolve --alldeps --destdir/tmp/docker-rpms \ docker-ce-18.09.7-3.el7 docker-ce-cli-18.09.7-3.el7 # 目标机上禁用所有源只用本地 rpm 安装避免又去联网解析 dnf install -y --disablerepo* /tmp/docker-rpms/*.rpm6.2 一张验收表装完照着打勾检查项命令合格标准客户端版本docker --version18.09.7, build 2d0083d服务端版本docker info --format {{.ServerVersion}}与客户端一致存储驱动docker info --format {{.Driver}}overlay2cgroup 驱动docker info --format {{.CgroupDriver}}systemd对接 K8s 时数据目录docker info --format {{.DockerRootDir}}指向独立分区开机自启systemctl is-enabled dockerenabled容器连通性docker run --rm hello-world输出 Hello from Docker!这张表的价值不在单次安装而在批量部署时能一眼看出哪台机器没配好。我一般会把它写成一个 shell 脚本七条检查全过才返回 0接进批量执行工具里几十台机器跑一遍就知道哪几台需要返工。从那以后我每次给麒麟机器装 docker都会先把dnf repolist -v的 URL 展开结果贴进变更单再走两步安装、再跑一遍这张表——看着啰嗦但确实没再出现过「装完能用、重启就挂」的情况。希望帮到你。本文还有配套的精品资源点击获取