ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARM架构银河麒麟V10离线部署Docker与Nacos全攻略

ARM架构银河麒麟V10离线部署Docker与Nacos全攻略 前阵子给客户做项目交付对方丢给我一台ARM架构的银河麒麟V10服务器环境属于业务内网物理隔离没有外网权限。需求一句话在这台机器上先把Docker装好再把Nacos注册中心跑起来后面微服务联调要用。我原以为这是普通运维活真正做起来才发现离线安装最让人头疼的不是命令不会敲而是你根本不知道系统还缺哪些底层依赖该去哪里找合适架构的包。这篇文章把我这次部署的完整过程记录下来从环境确认、安装包收集、本地yum源搭建、Nacos接入MySQL到最后各种诡异坑的排查一次讲清楚。做内网部署、离线交付的兄弟可以参考能少走不少弯路。1. 先把环境摸清楚确认ARM麒麟版本和依赖闭环1.1 上机第一步别急着跑安装命令很多人习惯拿到服务器就开搞结果装到一半才发现系统版本不对、架构不对白白浪费时间。我在动手前先把三样东西打出来cat /etc/os-release cat /etc/kylin-release uname -m这次碰到的机器/etc/os-release里显示是Kylin Linux Advanced Server V10uname -m返回aarch64是ARM64架构没跑了。麒麟V10这玩意有很多马甲有基于CentOS的构建也有基于openEuler的构建还有SP1、SP2、SP3的区别。不同小版本的底层glibc版本、libseccomp版本、甚至systemd版本都不一样这直接影响后面的RPM依赖解析。所以第一件事永远是确认两个东西架构是x86_64还是aarch64系统是基于哪个发行版构建的。如果连这个都没搞清楚后面下载的安装包大概率白下载。1.2 版本选型为什么我建议这套组合离线环境不像线上可以随手yum update装错了版本再修正的成本非常高。因此组件版本我一般选“稳”而不是选“新”。组件推荐版本选择理由Docker Engine24.0.x支持aarch64比较成熟containerd、runc版本匹配稳定Nacos2.3.x2.x后支持gRPC配置管理、服务发现都稳定ARM下跑Java无压力JDKOpenJDK 8u或11Nacos 2.3.x对JDK 8兼容运维习惯也最熟悉MySQL/MariaDB8.0或系统自带MariaDB 10.x单机Nacos配置存储够用ARM下也有官方二进制我这次用的是Nacos 2.3.2。为什么不推荐最新的2.4.x/3.x一方面是我对2.3.x的配置项更熟摸得最透另一方面在离线环境里你没法指望临时查文档用自己最有把握的版本比追求“最新版”重要得多。1.3 离线安装的依赖闭环思维在线环境安装Docker一条yum install docker-ce就完事系统自动帮你把iptables、libseccomp、containerd.io这些依赖全部拉齐。但离线环境不一样装Docker不只是装那一个RPM它背后是一整棵依赖树。我这次选择的方式是在在线机器上用repotrack把Docker及其所有依赖RPM完整地拉下来然后上传到麒麟服务器在服务器本地用这些RPM做一个本地yum源最后还是通过yum命令来安装。这样做的最大好处是依赖关系跟在线环境几乎一致不会出现手动rpm -ivh时依赖缺失或顺序错乱的问题。2. 在能上网的机器上把安装包一次性备齐2.1 用repotrack拉Docker全家桶我先准备了一台能上网、架构同样是aarch64的CentOS 8/RHEL 8虚拟机没有的话直接在麒麟上把ARM开源镜像源的在线VM配好也行。然后在这台机器上下载软件包。先把docker-ce的源配好。国内环境我习惯用阿里云镜像yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo然后创建一个目录用repotrack把依赖完整拉下来mkdir -p /data/kylin-offline/rpms cd /data/kylin-offline/rpms repotrack docker-ce docker-ce-cli containerd.io docker-compose-plugin这里核心参数是repotrack而不是yumdownloader。yumdownloader --resolve虽然也能拉依赖但只会拉“当前yum环境下需要的那一层依赖”对缺少系统基础包的情况支持得不够完整。repotrack会把所有被依赖的包全部拉下来不管是不是已安装用起来更省心。拉完之后检查一下包架构find /data/kylin-offline/rpms -name *.rpm | xargs -I{} rpm -qp --qf %{ARCH} {}\n {} | sort | uniq -c正常应该能直接看到大量aarch64包。如果混入了x86_64包说明在线机架构或者yum源配置有问题这时候就要停下来排查别直接上传。另外记得把createrepo_c这个工具也拉下来。虽然平时毫不起眼但到了离线服务器上你才会发现本地yum源能不能建起来就靠它repotrack createrepo_c2.2 备用方案直接下Docker静态二进制包如果你不想折腾RPM依赖还有一个更“轻”的办法Docker官方为Linux提供静态二进制归档包。下载下来解压把里面几个二进制放到/usr/bin就能用。curl -fsSL https://download.docker.com/linux/static/stable/aarch64/docker-24.0.9.tgz -o docker.tgz tar -xzf docker.tgz cp docker/* /usr/bin/但静态包只是“能用”不会帮你生成systemd服务、不会帮你创建docker用户组、也不会自动处理containerd和dockerd之间的协作关系。我建议只是把它当作应急方案。RPM源方式是更可控、更规范的做法而且和yum的依赖管理能完美结合。2.3 下载Nacos和JDKNacos本身是Java程序不依赖特定CPU指令集只要有对应的JDK就能跑。我用的是官方release里的包wget https://github.com/alibaba/nacos/releases/download/2.3.2/nacos-server-2.3.2.tar.gz如果服务器yum源或麒麟系统里已经有OpenJDK可以直接用系统的不需要额外下载。没有的话建议把OpenJDK 8的RPM也拉到同一目录。JDK 8在ARM上跑Nacos完全没问题这也是Nacos自己官方文档里推荐过的组合。把这些包从在线机拷贝到离线服务器的方式我就不啰嗦了U盘、堡垒机、内网FTP都行。拷贝后务必做校验md5sum docker-*.rpm nacos-server-2.3.2.tar.gz checksum.txt2.4 顺便把MySQL/MariaDB准备掉如果Nacos要用MySQL存储配置和服务数据需要准备好MySQL或MariaDB。我这次直接用的系统自带的MariaDB离线环境下安装最省事yum install -y mariadb-server systemctl enable --now mariadb如果你需要走MySQL官方8.0务必下载linux-glibc2.17-aarch64的二进制包别拿到x86版。3. 在离线服务器上搭本地yum源把Docker装上3.1 搭建本地仓库把所有RPM上传到服务器的/data/kylin-offline/rpms目录后先装createrepo_ccd /data/kylin-offline/rpms rpm -ivh createrepo_c-*.rpm然后创建仓库元数据createrepo /data/kylin-offline/rpms这一步执行完会生成repodata目录。把仓库写进yum源cat /etc/yum.repos.d/docker-local.repo EOF [local-docker] nameLocal Docker RPM Repository baseurlfile:///data/kylin-offline/rpms enabled1 gpgcheck0 EOF yum clean all yum makecache3.2 正式安装Docker本地源生效后安装命令跟在在线环境几乎一样yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin装好之后先不急着启动我先调整了/etc/docker/daemon.json{ data-root: /data/docker, exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 } }这里有两个细节解释一下>systemctl daemon-reload systemctl start docker systemctl enable docker systemctl status docker验证一下Docker是否正常工作docker info docker run --rm hello-world如果离线环境连不上镜像仓库hello-world会拉取失败这是正常的不代表Docker引擎有问题。3.3 本地装好后先验证镜像导入离线环境下没法现场拉镜像所以预先在有网络环境的机器上准备好常用基础镜像比如openjdk:8-jdk-alpine、busybox之类的。导出用的是docker savedocker save openjdk:8-jdk-alpine busybox:stable -o /data/kylin-offline/images/base-images.tar后面在离线服务器上导入docker load -i /data/kylin-offline/images/base-images.tar docker images这一步能确确实实证明Docker引擎工作正常。4. Nacos单机部署与外部MySQL接入4.1 解压并准备Nacos运行目录Nacos我放在/data/app下mkdir -p /data/app tar -xzf /data/kylin-offline/nacos-server-2.3.2.tar.gz -C /data/app mv /data/app/nacos /data/app/nacos-2.3.2 ln -s /data/app/nacos-2.3.2 /data/app/nacos建一个软链方便以后升级版本时切换目录也方便写脚本时路径固定。启动前先确认java可用java -version如果输出openjdk version 1.8.0_xxx说明系统有JDK8。没有的话把之前下载的JDK RPM装上yum install -y java-1.8.0-openjdk-headless4.2 初始化MySQL数据库Nacos的配置内容、服务注册信息都要落到数据库所以先把库和账号建好mysql -uroot -pCREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER nacos% IDENTIFIED BY nacos2024; GRANT ALL PRIVILEGES ON nacos_config.* TO nacos%; FLUSH PRIVILEGES; USE nacos_config; SOURCE /data/app/nacos/conf/mysql-schema.sql;这里有个容易踩的坑Nacos 2.3.x安装包里初始化SQL脚本可能叫mysql-schema.sql而不是老版本的nacos-mysql.sql目录里也可能同时存在多个脚本。执行之前先ls /data/app/nacos/conf/看清楚文件名别按老经验一顿操作。另外如果用的是MySQL 8.xNacos的连接用户最好用mysql_native_password。实测中有些老版本Nacos连MySQL 8的默认caching_sha2_password加密插件会报认证失败干脆手动改一下ALTER USER nacos% IDENTIFIED WITH mysql_native_password BY nacos2024;4.3 修改application.properties编辑/data/app/nacos/conf/application.properties把默认的derby数据源切到MySQLspring.datasource.platformmysql db.num1 db.url.0jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncodingutf8connectTimeout1000socketTimeout3000autoReconnecttrueuseUnicodetrueuseSSLfalseserverTimezoneAsia/Shanghai db.usernacos db.passwordnacos2024如果你是先给服务注册中心用暂时不接配置中心也可以继续用内置Derby少牵扯一个数据库组件。但只要Nacos要支撑多个服务的注册和配置发布就趁早上MySQL否则后面数据迁移会让你很头疼。4.4 启动Nacos并调整JVM参数Nacos默认启动脚本里的JVM参数偏向大内存机器一些内网服务器内存只有8G甚至4G直接启动很容易把可用内存吃满。我先调整环境变量再启动export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk export JVM_XMS512m export JVM_XMX512m export JVM_XMN256m sh /data/app/nacos/bin/startup.sh -m standaloneNacos 2.x的startup.sh支持JVM_XMS、JVM_XMX、JVM_XMN这几个环境变量不用动脚本内容比较干净。启动后看日志确认tail -f /data/app/nacos/logs/start.out看到Started Nacos基本就成了。再检查8848和9848端口ss -lntp | grep -E 8848|9848|98498848HTTP主端口控制台和客户端HTTP请求用9848gRPC服务端口2.x客户端必须能访问别忘了开防火墙9849gRPC服务端端口后面的集群会用到。4.5 验证控制台和客户端注册浏览器直接访问http://服务器IP:8848/nacos默认账号密码是nacos/nacos进去后看一眼“服务列表”“配置管理”是否正常。第一次登录建议马上改密码生产环境还要开启鉴权。再验证一个真实应用注册。随便用一个支持Nacos Discovery的微服务或者用curl模拟Nacos注册curl -X POST http://127.0.0.1:8848/nacos/v1/ns/instance?serviceNametest-demoip192.168.1.20port8080然后在控制台“服务列表”里能看到test-demo就说明服务注册链路已经完全通畅。5. 可选操作把Nacos放进容器跑起来有些场景下你希望Nacos也容器化跟其他微服务统一用Docker管理。这一步我把离线镜像的方案也写出来。5.1 在线导镜像在能上网的aarch64机器上docker pull nacos/nacos-server:v2.3.2 docker save nacos/nacos-server:v2.3.2 -o /data/kylin-offline/nacos-server-v2.3.2.tar这里务必确认在线机是ARM架构。如果你在x86机器上docker pull拉下来的是amd64镜像传到ARM服务器上用docker load虽然能导入但docker run会直接报exec format error。5.2 离线导入并运行docker load -i /data/kylin-offline/nacos-server-v2.3.2.tar docker images | grep nacos启动容器前我建议先不要用默认的derby模式跑还是连外部MySQLdocker run -d --name nacos \ --restartalways \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST192.168.1.30 \ -e MYSQL_SERVICE_PORT3306 \ -e MYSQL_SERVICE_USERnacos \ -e MYSQL_SERVICE_PASSWORDnacos2024 \ -e MYSQL_SERVICE_DB_NAMEnacos_config \ -p 8848:8848 -p 9848:9848 -p 9849:9849 \ nacos/nacos-server:v2.3.2有一个最常见的坑必须说MYSQL_SERVICE_HOST不要填127.0.0.1因为容器里的127.0.0.1指向容器自己不是宿主机。如果你非要填本机要么用--network host模式启动Nacos容器要么填宿主机在局域网内的真实IP。启动后观察日志docker logs -f --tail 200 nacos容器方式部署Nacos时如果要用到宿主机网络也可以直接docker run -d --name nacos \ --network host \ -e MODEstandalone \ -e MYSQL_SERVICE_HOST127.0.0.1 \ ...--network host模式下端口映射参数不需要加容器直接占用宿主机8848/9848端口日志里看到的注册IP也更干净。5.3 本地目录挂载与备份容器作为无状态运行很爽但Nacos的数据和配置一旦没了会很麻烦。给容器挂载两个目录比较稳妥docker run -d --name nacos \ --restartalways \ -v /data/nacos/logs:/home/nacos/logs \ -v /data/nacos/conf:/home/nacos/conf \ ...这样日志和配置都落在宿主机改配置不用进容器折腾备份也简单。不过要注意官方镜像里conf目录有初始化脚本你做目录挂载时第一次启动前要保证宿主机目录里已经放好了application.properties和mysql-schema.sql否则容器会拿不到默认配置。6. 离线环境里那些防不胜防的坑6.1 Docker daemon启动失败报overlay2不支持常见错误类似failed to start daemon: error initializing graphdriver: driver not supported大概率是内核模块没加载或者文件系统不支持overlay2。先看文件系统df -T /data/docker确认是ext4或xfs再看xfs是否开启了ftype1。ARM板子上如果用的是外部数据盘格式化的时候没有指定-n ftype1overlay2就会拒绝工作。解决方法要么重新格式化数据盘并指定d_type要么把>Error starting daemon: Error initializing network controller: Error creating default bridge network: iptables failed离线环境经常出现系统里连iptables都没装全。装上yum install -y iptables ip6tables nftables装完后建议重启一次系统再启动docker。因为iptables和nftables的内核模块在运行中加载不完整重启后让systemd把服务拉起来能省掉很多莫名其妙的网络问题。6.3 Nacos服务注册IP变成容器IP或veth绑定的IP很多应用在Kubernetes或者Docker里注册到Nacos的地址是内网虚拟IP导致其他服务调不通。这个问题我直接在Nacos启动参数里指定IPexport JVM_FLAGS-Dnacos.inetutils.ip192.168.1.100 sh /data/app/nacos/bin/startup.sh -m standalone或者修改conf/application.propertiesnacos.inetutils.ip-whitelist192.168.1.100这样报给客户端的地址就是你希望暴露的地址。服务注册IP被抢成容器IP是Nacos容器化部署最常见的故障尤其是多个网卡或多网段环境。6.4 Nacos跑了两天控制台登录报502Nacos本身是Java进程CPU和内存一吃紧响应就会很慢网关直接判定服务不可用。我遇到过不止一次基本是JVM参数没调好或者磁盘IO太差。建议至少给Nacos 1G堆内存8G内存的服务器别抠抠搜搜只给256Mstart.out日志如果刷得太快把日志级别调成WARN用dmesg -T | tail看一眼有没有OOM Kill如果有说明要么加内存要么调小堆。6.5 重启后Nacos没起来Nacos的startup.sh不会自己注册成系统服务所以重启后经常忘了启动。建议写一个systemd服务文件[Unit] DescriptionNacos Server Afternetwork.target mariadb.service [Service] Typeforking EnvironmentJAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk ExecStart/data/app/nacos/bin/startup.sh -m standalone ExecStop/data/app/nacos/bin/shutdown.sh Restarton-failure Usernacos Groupnacos [Install] WantedBymulti-user.target然后systemctl daemon-reload systemctl enable nacos我这里用了nacos用户来跑安全一点。如果直接root跑把User和Group两行删掉就行。6.6 客户端连不上9848Nacos 2.x的客户端和服务端之间走gRPC端口是884810009848。很多人在控制台能看到服务但客户端启动时报connection refused一查就是防火墙只开了8848。记得把9848甚至9849都放通firewall-cmd --permanent --add-port8848/tcp firewall-cmd --permanent --add-port9848/tcp firewall-cmd --reload麒麟系统如果用的是firewalld就这样开如果是ufw语法不一样但道理一样。再说一点个人经验。整套环境在离线状态做完后我会把所有安装包、初始化脚本、配置文件汇总成一个目录并在目录里写一份简单的README记录系统版本、安装命令、改动过的配置项和踩坑记录。看似多花了二十分钟但下一次交付新机器或者出问题需要回滚时这份记录真能救命。
返回列表