银河麒麟V10 ARM服务器离线部署Docker与Nacos实操指南
2026/9/16 20:53:52 网站建设 项目流程

最近给一台银河麒麟V10 ARM架构的服务器做离线部署,目标非常明确:内网环境完全不能连外网,要把 Docker 和 Nacos 都跑起来,还得开机自启。整个过程踩了不少坑,尤其是 ARM 架构这个词,看起来简单,实际却决定着你下载的每个包能不能用。这篇就把完整的离线安装流程整理出来,从安装包准备、系统预检查、Docker 部署到 Nacos 容器化启动,加上我实战中遇到的各种报错和排查思路,给要在银河麒麟 ARM 服务器上做离线部署的朋友一个可直接参考的清单。

准备工作做足了,整个流程其实就是“拷贝、解压、加载镜像、启动容器”这几步。真正让人翻车的,往往不是你操作不熟,而是包选错了架构、镜像平台不对、端口没放行这类细节。我会把这些地方重点标出来,希望能帮你少走几趟弯路。

1. 离线部署的整体思路与环境准备

1.1 为什么离线部署在 ARM 架构上特别容易出问题

绝大多数 Linux 软件的安装方式,在能联网的机器上都很简单:要么apt install,要么yum install,再复杂一点的拉个容器镜像完事。但在完全隔离的内网环境里,这条路直接堵死,你只能提前准备好所有安装包,再把它们手动传进服务器。

这时候 ARM 架构就成了最大的变量。银河麒麟 V10 可以运行在 x86_64、aarch64、loongarch64 等不同架构上,每一个架构都有自己的二进制格式和依赖库。如果在下载软件包时没有选择对应架构的版本,哪怕文件名看起来一模一样,拷进去之后一执行就会报Exec format error。这就像你把一把内六角扳手拿去拧十字螺丝,螺纹都能对上一点,但实际咬合不了。所以离线安装的第一步不是动手操作,而是先确认这套服务器到底是什么系统、什么架构、缺什么工具。

1.2 开工前先确认系统版本、架构和基础工具

不要凭直觉判断服务器架构,直接上命令看。我自己的习惯是执行这几条:

cat /etc/os-release uname -m uname -r getconf LONG_BIT

以我手头这台机器为例,输出大概是:

NAME="Kylin Linux Advanced Server" VERSION="V10 SP2" ID=kylin ID_LIKE="centos"

uname -m输出aarch64,说明这是 ARM 64 位架构,必须下载 aarch64/arm64 的软件包。如果输出是x86_64,那你下面所有包都要换成 amd64 架构。getconf LONG_BIT输出 64,则是 64 位系统,几乎可以确定不需要去考虑 32 位兼容的问题。

这一步的价值是帮你确定整个离线目录的“采购清单”。银河麒麟 V10 还有基于 Debian 体系的版本,这时包管理工具可能是dpkg/apt,也可能只有rpm/yum。我这次用的服务器是 RPM 系,但为了避开包依赖的差异,Docker 我直接选择了官方静态二进制包安装,Nacos 则用容器镜像方式启动。这样就避免了很多“缺一个依赖、少一个库”的问题。

1.3 离线安装包准备清单

离线安装包不是指某一个压缩包,而是一整套完整资源。我在离线环境部署 Nacos 时,会准备以下几类东西:

资源用途格式来源
Docker 静态二进制包安装 Docker 引擎tar.gzDocker 官方 static 包
Nacos Server 镜像以容器方式运行 Nacostar 镜像文件在联网机器上docker pull
MySQL 镜像Nacos 配置数据存储tar 镜像文件在联网机器上docker pull
Nacos 初始化 SQL初始化数据库表结构.sql 文件Nacos 官方仓库或镜像内拷贝
sha256sum 校验工具校验包完整性系统自带无需额外准备

在联网机器上,我会先建立一个/data/kylin-offline目录,把这些包全部按类别放好,再通过 U 盘或内网传输工具整个拷贝到目标服务器。不要一个个零散传,很容易丢包,也容易漏。后面我会详细说每个文件的获取方式和具体命令。

2. 银河麒麟 V10 系统预检查与基础配置

2.1 普通用户密码修改和 docker 权限组

很多朋友在拿到一台服务器时,只有一个普通用户账号,安装软件需要切换到 root,或者临时提权。修改普通用户密码用一条命令就能解决,并不复杂。

如果你是 root 用户,直接执行:

passwd 用户名

然后按照提示连续输入两次新密码即可。如果你是普通用户,想修改自己的密码,可以执行:

passwd

系统同样会要求输入当前密码和新密码。这个操作和架构、发行版关系不大,银河麒麟 V10 上也是这样处理。

另外,后面我们用普通用户执行 Docker 命令时,可能会遇到:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

明明 Docker 已经启动了,普通用户还是连不上,是因为/var/run/docker.sock的权限默认属于 root 组。解决办法就是把当前用户加入 docker 组:

usermod -aG docker 用户名

执行完之后必须退出重登,或者直接newgrp docker刷新会话,否则组权限不会立即生效。这是我经常看到新手卡住的地方。

2.2 防火墙、Swap 和文件句柄限制

内网环境很多人会图省事直接把防火墙关掉。做测试可以,生产环境我不建议这么做。更稳妥的做法是只放行需要用到的端口。

先确认防火墙状态:

systemctl status firewalld

如果这台机器以前没被配置过,你可以在当前测试阶段临时停掉:

systemctl stop firewalld systemctl disable firewalld

等你上线 Nacos 后,再根据实际端口策略放行。Nacos 2.x 版本除了 8848 端口,还需要放行 9848、9849 端口,这个我在后面的坑位里会重点说。

文件句柄上限对 Nacos 这类高并发服务也比较重要。可以临时查看:

ulimit -n

如果值比较小,比如 1024,建议调整到更大的数值。临时调整可以:

ulimit -n 65535

永久调整需要修改/etc/security/limits.conf,在文件末尾加上:

* soft nofile 65535 * hard nofile 65535

关于 Swap,如果你的服务器内存比较小,建议先加内存或者控制 Nacos 的 JVM 内存参数,不要指望 Swap 兜底。容器模式下频繁交换会导致性能忽高忽低,很不稳定。

2.3 目录规划与文件传输

在目标服务器上,我会先规划好目录:

mkdir -p /opt/offline/packages mkdir -p /opt/offline/images mkdir -p /opt/nacos/data mkdir -p /opt/nacos/logs

/opt/offline用来放离线包和镜像文件,部署完成后这些文件仍建议保留,方便日后扩容或回滚。/opt/nacos用作 Nacos 容器挂载的数据和日志目录。

文件传输方式看你的现场条件。有内网管理网,优先用scp或者sftp

scp -r /data/kylin-offline/* root@目标IP:/opt/offline/

如果只有 U 盘,插入后先挂载:

fdisk -l mkdir -p /mnt/usb mount /dev/sdb1 /mnt/usb cp -r /mnt/usb/* /opt/offline/

传完之后,用sha256sum对比一下文件哈希,确保包在传输过程中没损坏。我是会提前把每个安装包的 sha256 值写在一个SHA256SUMS.txt文件里,放到同一目录下,到目标机上执行:

cd /opt/offline sha256sum -c SHA256SUMS.txt

只有显示全部 OK,才能进入下一步。

3. Docker 离线安装与验证

3.1 Docker 离线包下载和校验

安装 Docker 我选的方案不是yum也不是apt,而是直接用 Docker 官方提供的静态二进制包。这种方式最干净,不依赖银河麒麟的软件仓库,也不会有莫名其妙的依赖缺失。

下载地址需要进入 Docker 官方静态二进制目录,选择aarch64目录,然后找到对应版本。例如我用的版本是 24.0.9:

wget https://download.docker.com/linux/static/stable/aarch64/docker-24.0.9.tgz

注意,这里目录必须是aarch64,不能手滑下成x86_64。下载完成后,把文件的 sha256 值和官方页面上给出的值做对比:

sha256sum docker-24.0.9.tgz

如果和官方公布的值一致,说明下载过程没有损坏。ARM 架构的安装包如果来源不正规,很影响后续排查,所以我建议每次都做校验,宁可多花三十秒也不要赌运气。

3.2 解压、安装二进制和服务文件

先解压:

tar xf docker-24.0.9.tgz

解压之后会产生一个docker目录,里面包括 docker、dockerd、containerd、containerd-shim-runc-v2、ctr、docker-init、docker-proxy 等文件。把这些文件全部复制到系统路径:

cp docker/* /usr/bin/

然后验证一下版本:

docker version

这一步只能看到 Client 版本,服务端还没有启动。要让 Docker 通过 systemd 托管,需要手动创建服务文件。

创建/etc/systemd/system/docker.service

[Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service containerd.service Wants=network-online.target Requires=docker.socket [Service] Type=notify ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target

再创建/etc/systemd/system/docker.socket

[Unit] Description=Docker Socket for the API [Socket] ListenStream=/var/run/docker.sock SocketMode=0660 SocketUser=root SocketGroup=docker [Install] WantedBy=sockets.target

这两个文件是 Docker 能开机自启、并通过 socket 方式被普通用户访问的关键。设好之后重新加载 systemd:

systemctl daemon-reload systemctl enable --now docker.socket systemctl enable --now docker.service

为什么非要走 systemd 管理?因为服务器重启后,我们希望 Docker 能自动拉起,后面 Nacos 容器也要设置restart=always,才能保证整套服务在断电重启后不用人工干预。

3.3 启动 Docker 并验证架构

启动完成后,立刻看一次版本号:

docker version

正常会同时输出 Client 和 Server 信息。再确认当前 Docker 运行的平台架构:

docker info | grep Architecture

我在 ARM 机器上执行后,输出是:

Architecture: aarch64

如果你看到的是x86_64,那说明你装错包了。还有一种情况是Failed to start docker.service: Unit docker.service not found.,多半是 service 文件没有放到正确路径,或者没有执行systemctl daemon-reload

如果你需要在内网使用 Docker 命令行,但机器上没有cgroup权限或者内核模块不完整,启动 dockerd 时会报:

failed to start daemon: Devices cgroup isn't mounted

这种情况通常是系统没挂载 cgroup 相关文件系统。可以执行:

mount -t cgroup -o devices cgroup /sys/fs/cgroup/devices

但更推荐先检查内核参数,确认/sys/fs/cgroup正常。银河麒麟 V10 服务器版一般内核都完整,只要你的容器运行时相关模块没被裁剪,问题不大。

3.4 在联网机器上准备 ARM 架构的镜像 tar 包

离线环境没有 Docker Hub 可拉,镜像必须在能联网的机器上提前拉好,并导出为 tar 文件。这里有个非常容易踩的坑:如果联网机器是 x86_64 架构,默认执行docker pull拉下来的镜像是 amd64 版本,拿到 ARM 服务器上docker load后虽然能加载成功,但一启动容器就会报:

exec format error

所以在联网机器上准备镜像时,必须保证镜像平台是linux/arm64。最简单的方式是在一台 ARM 架构且有公网访问的机器上拉取:

docker pull nacos/nacos-server:v2.3.2 docker pull mysql:8.0.36

如果只有 x86_64 的联网机器,可以用 Docker 的--platform参数拉取指定平台镜像:

docker pull --platform linux/arm64 nacos/nacos-server:v2.3.2 docker pull --platform linux/arm64 mysql:8.0.36

拉取后,检查一下镜像架构,确认无误再导出:

docker image inspect nacos/nacos-server:v2.3.2 --format '{{.Architecture}}'

输出应该是arm64。然后保存镜像:

docker save -o nacos-server-v2.3.2.tar nacos/nacos-server:v2.3.2 docker save -o mysql-8.0.36.tar mysql:8.0.36

docker save可以保留镜像的完整元数据,包括架构信息。导出的 tar 文件会和安装包一起传到目标服务器的/opt/offline/images/目录。

到了目标服务器上,加载镜像:

docker load -i /opt/offline/images/nacos-server-v2.3.2.tar docker load -i /opt/offline/images/mysql-8.0.36.tar

加载完成后,用docker images看一下镜像列表,确认标签和架构正常。

4. Nacos 离线部署与配置

4.1 Nacos 版本选型与安装方式

Nacos 在 ARM 上没有特殊限制,它是 Java 写的,只要镜像平台和 JDK 平台正确,运行方式基本一致。我在生产里倾向使用 2.x 版本,这里以v2.3.2为例,功能稳定,API 也比较成熟。

安装方式有两种:一种是直接用 tar 包部署原生 Nacos,需要自己装 JDK;另一种是用 Docker 容器运行,就省去了手动配 JDK 的麻烦。我这次选的是容器化方式,因为离线环境下 JDK 包又是个额外依赖,容器镜像里已经内置好了,省事很多。

4.2 快速跑通最简单的单机模式

最快速验证离线包是否正常的方法,是先用 Nacos 内置的 Derby 数据库跑单机模式。Derby 是嵌入式的,不需要额外准备数据库,适合第一次在内网把链路打通。

创建一个 Docker 网络,方便后面接入 MySQL:

docker network create nacos-network

然后启动单机 Nacos:

docker run -d \ --name nacos \ --network nacos-network \ -p 8848:8848 \ -p 9848:9848 \ -e MODE=standalone \ nacos/nacos-server:v2.3.2

启动后观察日志:

docker logs -f nacos

看到类似:

Nacos started successfully in stand alone mode. use embedded storage

说明 Nacos 已经启动成功。再用curl探测健康状态:

curl http://localhost:8848/nacos/v1/console/health/readiness

返回true就说明客户端接口正常。打开浏览器访问http://服务器IP:8848/nacos,就能看到控制台登录页,默认用户名密码都是nacos

需要注意,Nacos 2.x 同时依赖 8848 和 9848 端口。8848 是 HTTP 主端口,9848 是 gRPC 通信端口,如果只映射了 8848,客户端注册服务时依然会失败。这个坑我踩过一次,后面专门讲。

4.3 改用 MySQL 持久化(生产推荐)

单机 Derby 只适合验证环境,数据一旦容器删除就全没了。生产环境建议用 MySQL 持久化。我在离线包中准备了 mysql:8.0.36 镜像,现在把它启动到同一个网络里。

先创建 MySQL 容器:

docker run -d \ --name mysql8 \ --network nacos-network \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root \ -e MYSQL_DATABASE=nacos_config \ -v /opt/nacos/mysql-data:/var/lib/mysql \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci \ --restart=always \ mysql:8.0.36

MySQL 启动需要一点时间,用日志确认:

docker logs -f mysql8

看到ready for connections就说明数据库起来了。

然后导入 Nacos 官方初始化 SQL,表结构文件需要在联网阶段准备好。我通常是从 Nacos 镜像里直接拷贝出来:

docker run --rm nacos/nacos-server:v2.3.2 cat /home/nacos/conf/mysql-schema.sql > mysql-schema.sql

离线环境下,这一步在联网机器操作,得到mysql-schema.sql后随镜像一起带进内网。再把它传入 MySQL:

docker exec -i mysql8 mysql -uroot -proot nacos_config < mysql-schema.sql

导入成功后,重新启动一个使用 MySQL 存储的 Nacos 容器:

docker run -d \ --name nacos-mysql \ --network nacos-network \ -p 8848:8848 \ -p 9848:9848 \ -e MODE=standalone \ -e SPRING_DATASOURCE_PLATFORM=mysql \ -e MYSQL_SERVICE_HOST=mysql8 \ -e MYSQL_SERVICE_DB_NAME=nacos_config \ -e MYSQL_SERVICE_USER=root \ -e MYSQL_SERVICE_PASSWORD=root \ -e MYSQL_SERVICE_PORT=3306 \ -v /opt/nacos/logs:/home/nacos/logs \ --restart=always \ nacos/nacos-server:v2.3.2

注意这里MYSQL_SERVICE_HOST写的是 MySQL 容器名mysql8,因为两个容器在同一个自定义网络里,可以通过容器名互相访问。如果用 Docker 默认 bridge 网络,容器名解析不一定好用,所以我建议都放到nacos-network里。

4.4 Nacos 配置中心的实际验证

部署完不能只看控制台能打开,还要实际验证一下配置中心功能。最直接的方式是用 curl 发布一条配置,再读取出来。

发布配置:

curl -X POST "http://localhost:8848/nacos/v1/cs/configs?dataId=test.properties&group=DEFAULT_GROUP&content=app.name=nacos-demo"

读取配置:

curl "http://localhost:8848/nacos/v1/cs/configs?dataId=test.properties&group=DEFAULT_GROUP"

如果返回:

app.name=nacos-demo

说明配置中心读写正常。服务注册发现功能,可以通过控制台左侧“服务管理”页面看到注册上来的服务。如果只有 Nacos 本身,没有服务列表,也不用急,等后续业务服务接入后自然会有。

4.5 端口放行与开机自启

容器已经设置了--restart=always,服务器重启后 Docker 会把 Nacos 和 MySQL 自动拉起。这是容器部署相比原生部署最大的优势,我不需要再去写一堆开机脚本。

但如果环境里有防火墙,外部机器仍访问不了控制台。放行端口如下:

firewall-cmd --permanent --add-port=8848/tcp firewall-cmd --permanent --add-port=9848/tcp firewall-cmd --permanent --add-port=9849/tcp firewall-cmd --reload

9849 端口同样用于 gRPC,通常也用得上,直接一起放行。

如果系统用的是ufw,则对应:

ufw allow 8848/tcp ufw allow 9848/tcp ufw allow 9849/tcp

我个人的做法是:先确认容器能跑起来,再考虑防火墙规则。很多时候容器端口已经映射了,防火墙没放行,外部 socket 连不上,排查了很久才发现问题出在防火墙上,这种低级的坑最浪费时间。

5. 常见问题与排查技巧实录

5.1 容器启动报 exec format error

这个报错我遇到过不止一次,几乎都是镜像架构和宿主机架构不匹配引起的。比如你在 x86_64 机器上docker pull了默认的nacos/nacos-server镜像,然后把镜像传到 ARM 服务器上启动,就会报:

standard_init_linux.go:228: exec user process caused: exec format error

排查办法很简单:

docker image inspect nacos/nacos-server:v2.3.2 --format '{{.Architecture}}'

如果镜像在 ARM 服务器上显示的架构不是arm64,那就说明来源镜像不对。解决办法是回到联网机器,用--platform linux/arm64重新拉取,再 save 一次。

5.2 Docker 服务启不来,日志里有 device or resource busy

这个报错大多和旧版 Docker 残留进程有关。如果你以前用脚本启动过 Docker,再切到 systemd 托管时,旧进程可能还占着/var/run/docker.sock或相关文件。

现场可以直接:

systemctl stop docker pkill dockerd pkill containerd systemctl start docker

如果依然不行,可以检查 systemd 的服务状态:

systemctl status docker -l journalctl -u docker -n 100

日志是定位问题最直接的信息。不要只看最后一句,多翻几十行,有时候真正起不来的原因在中间部分。

5.3 Nacos 控制台能打开,但客户端总是注册不上服务

这个坑很隐蔽。Nacos 2.x 引入 gRPC 之后,客户端会额外连接 9848 端口。如果你只放行了 8848,控制台可以正常访问,但服务注册、配置订阅都会超时。

当时现场表现是:Spring Cloud 服务启动时反复重试连接,控制台里看不到服务列表,但 Nacos 容器本身日志却没有任何崩溃信息。

排查方法:

ss -lnt | grep -E '8848|9848'

确认两个端口都在监听。然后检查服务器防火墙和安全组策略,把 9848、9849 都加入放行列表。如果是 Docker 映射端口,注意-p 9848:9848不要漏掉。

5.4 Nacos 容器经常 OOM,日志显示内存不够

Nacos 默认 JVM 参数比较保守,所以在小内存服务器上比较容易撞到内存上限。低配服务器(比如 4G 内存)同时跑 MySQL 和 Nacos 时,我建议显式设置 JVM 内存环境变量:

-e JVM_XMS=512m \ -e JVM_XMX=512m \ -e JVM_XMN=256m \

这三个参数分别控制初始堆、最大堆和新生代大小。配合容器的内存限制一起使用:

--memory=1g

这样至少能保证不会因为 Nacos 把整台服务器的内存吃光,把 MySQL 也带崩。

5.5 离线安装其他软件时缺依赖的通用处理方式

如果在银河麒麟 V10 上用rpmdpkg安装软件时提示缺依赖,最简单的思路是优先找静态编译版本或容器镜像。Docker 容器之所以适合离线部署,就是因为它把所有依赖都封装好了。

如果一定要用系统包管理方式,RPM 系可以尝试:

rpm -ivh xxx.rpm --nodeps

或者:

yum localinstall xxx.rpm -y

--nodeps是强行走捷径,系统里如果真缺了运行库,装完后软件照样跑不起来,到时候排查更头疼。所以能用容器、尽量用容器,这个观点我每次离线部署都会反复提。

6. 安装包整理与后续扩展

6.1 做一个完整的离线软件仓库目录

离线部署最容易出现的问题不是不会装,而是不知道有哪些包漏了。我习惯把所有离线资源组织成固定目录,目录结构如下:

/opt/offline/ ├── packages/ │ └── docker-24.0.9.tgz ├── images/ │ ├── nacos-server-v2.3.2.tar │ └── mysql-8.0.36.tar ├── sql/ │ └── mysql-schema.sql └── SHA256SUMS.txt

其中SHA256SUMS.txt记录了每个文件的哈希值,方便在目标服务器上做完整性校验。这样即使部署中断、重新再来,也可以快速确认资源没有缺失。我也建议在目录里写一个README.md,把命令和注意事项随手记录下来,别太过相信自己的记忆力,过两三个月回看,很多细节都会变得模糊。

6.2 用同样的思路扩展部署 Nginx、MySQL 等中间件

当你把“离线安装包 + 镜像导入 + 容器启动”这套流程跑顺之后,再部署其他中间件基本都是复制黏贴的事。比如离线部署 Nginx,你只需要在联网机器拉取nginx:1.24.0镜像,保存、传输、加载,然后启动容器时挂载好配置目录和日志目录就行。

银河麒麟服务器上跑这些容器中间件,跟其他 Linux 发行版没有本质区别。你只需要记住三条原则:选择正确的 ARM 架构包、在隔离环境外提前准备镜像、用 systemd 或容器自启策略保证服务拉起。这三点想清楚,整个离线部署的稳定性和后续维护难度都会大大降低。

这次部署做完之后,我最大的一个体会是:离线环境并不可怕,怕的是在“不确定”的状态下动手。每下载一个包都要确认架构,每传一个文件都要做校验,每启动一个服务都要看日志。磨刀不误砍柴工,前期多花五分钟做检查,比后期排查半小时要强得多。如果你也在银河麒麟 V10 ARM 服务器上折腾离线安装,希望能从这篇记录里找到几条有用的路径。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询