简介这份资源面向需要在国产化信创环境中落地容器编排的运维与云原生工程师聚焦Kylin V10操作系统搭配ARM架构服务器、采用外部etcd与containerd运行时部署Kubernetes 1.26.15一主多从集群的完整离线安装包。压缩包共41个文件约645.74MB以gz离线镜像包、rpm系统依赖、sh部署脚本、yaml与yml编排清单为主另含kubeadm、kubectl、kubelet等核心二进制及kubelet.service、10-kubeadm.conf等配置文件覆盖etcd、containerd、Calico网络与CoreDNS等组件的镜像与依赖便于在无外网环境下完成集群搭建。资源同时提供镜像加载与拉取脚本、kubeadm初始化与join节点配置可帮助读者快速复现ARM平台上的高可用控制面与多工作节点拓扑理解外部etcd与containerd的对接方式并积累国产化环境下的排错与调优经验。目前已有130人学习下载适合具备一定Linux与K8S基础、希望深入信创场景的中高级读者参考。1. 麒麟 V10 ARM 上把 K8S 1.26.15 跑起来为什么这套组合值得折腾手里有一批鲲鹏或飞腾的 ARM 服务器系统是银河麒麟 V10要求容器运行时不用 Docker 而用 containerdetcd 还要独立部署在集群外部最后拉起一个 K8S 1.26.15 的一主多从集群——这套需求在信创交付现场出现频率极高。它解决的核心问题是在国产 ARM 芯片加国产操作系统的底座上搭出一套不依赖 Docker、etcd 与 Master 解耦、可横向扩 Node 的 Kubernetes 集群。适合正在做信创迁移、离线交付、或者被要求「全栈国产化」的运维和平台工程师。难点不在 K8S 本身而在 ARM 架构的镜像适配、麒麟 V10 的软件源差异以及外部 etcd 带来的证书和网络配置变化。这篇把每一步的命令、参数和踩过的坑都摊开讲。2. 动手前的底座确认麒麟 V10 ARM 环境与外部 etcd 的选型理由2.1 为什么 etcd 要独立于 Master 节点K8S 默认把 etcd 和 kube-apiserver 塞在同一台机器上用 kubeadm 一键拉起。但生产环境里etcd 是整个集群唯一的强一致数据源它一旦抖动API Server 直接不可用。把 etcd 拆到独立节点好处有三第一etcd 对磁盘 IO 极其敏感独立部署可以给它配 SSD 而不受 Master 上其他组件干扰第二Master 节点可以随时重建etcd 数据不受影响第三多 Master 场景下etcd 集群和 Master 节点数量解耦扩缩容更灵活。在麒麟 V10 ARM 上etcd 必须用 ARM64 版本。官方 release 页面提供 linux-arm64 的静态二进制包直接下载解压即可不依赖系统包管理器。这一点很关键因为麒麟 V10 的 yum 源里 etcd 版本往往偏旧用官方二进制能精确控制版本。2.2 麒麟 V10 上必须提前做的系统配置麒麟 V10 基于 CentOS/RHEL 体系但默认的安全策略和内核参数与标准 CentOS 有差异。以下操作在所有节点etcd 节点、Master、Node上都要执行。关闭 swap这是 K8S 的硬性要求# 临时关闭 swapoff -a # 永久关闭注释掉 /etc/fstab 中的 swap 行 sed -i /swap/s/^/#/ /etc/fstab # 确认已关闭 free -h加载内核模块并设置网络参数# 加载 br_netfilter 和 overlay 模块 cat /etc/modules-load.d/k8s.conf EOF br_netfilter overlay EOF modprobe br_netfilter modprobe overlay # 设置网桥和转发参数 cat /etc/sysctl.d/k8s.conf EOF net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 EOF sysctl --system逻辑说明br_netfilter让 iptables 能过滤网桥流量overlay是 containerd 的默认存储驱动。ip_forward不开Pod 跨节点通信直接断。麒麟 V10 默认可能没加载这两个模块不提前处理后面 kubelet 启动会报错。关闭防火墙和 SELinuxsystemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config提示如果交付环境不允许关闭 SELinux需要为 containerd 和 kubelet 单独配置策略工作量会大很多建议在测试环境先验证。时间同步也必须做etcd 集群对时间偏差敏感# 使用 chrony yum install -y chrony systemctl enable --now chronyd chronyc sources -v2.3 主机名与 hosts 规划一主多从的典型规划如下实际 IP 按现场替换角色主机名IP 示例安装组件etcdetcd01192.168.1.10etcdMasterk8s-master192.168.1.20kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、containerdNode1k8s-node1192.168.1.21kubelet、kube-proxy、containerdNode2k8s-node2192.168.1.22kubelet、kube-proxy、containerd每台机器设置主机名并写入 hostshostnamectl set-hostname k8s-master cat /etc/hosts EOF 192.168.1.10 etcd01 192.168.1.20 k8s-master 192.168.1.21 k8s-node1 192.168.1.22 k8s-node2 EOF3. 外部 etcd 集群部署ARM64 二进制安装与证书签发3.1 下载与安装 etcd ARM64 二进制麒麟 V10 ARM 上不能用 x86 的包必须拿 arm64 版本。常见做法是从 etcd 官方 GitHub release 下载对应版本的 linux-arm64 压缩包传到 etcd 节点。# 解压并安装到 /usr/local tar -xzf etcd-v3.5.12-linux-arm64.tar.gz cd etcd-v3.5.12-linux-arm64 cp etcd etcdctl /usr/local/bin/ chmod x /usr/local/bin/etcd /usr/local/bin/etcdctl # 验证架构 file /usr/local/bin/etcd # 应输出 ARM aarch64 相关信息参数说明etcd 版本建议选 3.5.x 系列与 K8S 1.26 兼容性经过验证。不要用 3.4 以下版本API 有差异。3.2 用 cfssl 签发 etcd 证书etcd 集群通信必须加密。用 cfssl 生成 CA 和证书在任意一台有 cfssl 的机器上操作即可。# 安装 cfsslARM64 版本 # 下载 cfssl、cfssljson、cfssl-certinfo 三个二进制 chmod x cfssl cfssljson cfssl-certinfo mv cfssl cfssljson cfssl-certinfo /usr/local/bin/ # 生成默认 CA 配置 cfssl print-defaults config ca-config.json cfssl print-defaults csr ca-csr.json编辑ca-config.json定义 etcd 的 profile{ signing: { default: { expiry: 87600h }, profiles: { etcd: { expiry: 87600h, usages: [ signing, key encipherment, server auth, client auth ] } } } }编辑ca-csr.json{ CN: etcd-ca, key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: Beijing, L: Beijing, O: etcd, OU: etcd } ] }生成 CA 证书cfssl gencert -initca ca-csr.json | cfssljson -bare ca # 生成 ca.pem ca-key.pem ca.csr接着生成 etcd 服务端证书。编辑etcd-csr.json注意 hosts 要包含所有 etcd 节点 IP 和 127.0.0.1{ CN: etcd, hosts: [ 127.0.0.1, 192.168.1.10, etcd01 ], key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: Beijing, L: Beijing, O: etcd, OU: etcd } ] }签发cfssl gencert -caca.pem -ca-keyca-key.pem \ -configca-config.json -profileetcd \ etcd-csr.json | cfssljson -bare etcd # 生成 etcd.pem etcd-key.pem逻辑说明hosts字段决定证书对哪些地址有效漏掉任何一个 etcd 节点 IP该节点启动时会报证书不匹配。profileetcd对应 ca-config.json 里定义的 usages必须同时有 server auth 和 client auth因为 etcd 节点之间既做服务端也做客户端。3.3 编写 etcd 配置文件并启动把证书放到/etc/etcd/ssl/创建配置文件/etc/etcd/etcd.conf.ymlname: etcd01>[Unit] Descriptionetcd service Afternetwork.target [Service] Typenotify ExecStart/usr/local/bin/etcd --config-file/etc/etcd/etcd.conf.yml Restartalways RestartSec5 LimitNOFILE65536 [Install] WantedBymulti-user.target启动并验证systemctl daemon-reload systemctl enable --now etcd systemctl status etcd # 用 etcdctl 验证 export ETCDCTL_API3 etcdctl --endpointshttps://192.168.1.10:2379 \ --cacert/etc/etcd/ssl/ca.pem \ --cert/etc/etcd/ssl/etcd.pem \ --key/etc/etcd/ssl/etcd-key.pem \ endpoint health参数说明initial-cluster-state: new表示新建集群如果是加节点要改成existing。client-cert-auth: true强制客户端证书认证K8S 的 apiserver 连接 etcd 时必须带证书。># 下载 containerd ARM64 版本 tar -xzf containerd-1.6.28-linux-arm64.tar.gz cp bin/* /usr/local/bin/ # 生成默认配置 mkdir -p /etc/containerd containerd config default /etc/containerd/config.toml4.2 修改 containerd 配置对接 systemd cgroup这是最容易翻车的地方。K8S 1.26 默认使用 systemd cgroup 驱动containerd 默认配置用的是 cgroupfs两者不一致会导致 kubelet 报错、Pod 起不来。# 修改 config.toml 中的关键项 sed -i s/SystemdCgroup false/SystemdCgroup true/ /etc/containerd/config.toml # 确认 sandbox 镜像地址国内环境需要替换 grep -n sandbox_image /etc/containerd/config.toml如果拉不到官方 pause 镜像需要替换为可访问的镜像仓库地址[plugins.io.containerd.grpc.v1.cri] sandbox_image registry.aliyuncs.com/google_containers/pause:3.9创建 systemd 服务并启动cat /usr/lib/systemd/system/containerd.service EOF [Unit] Descriptioncontainerd container runtime Afternetwork.target [Service] ExecStartPre/sbin/modprobe overlay ExecStart/usr/local/bin/containerd Restartalways RestartSec5 LimitNOFILE1048576 LimitNPROCinfinity LimitCOREinfinity [Install] WantedBymulti-user.target EOF systemctl daemon-reload systemctl enable --now containerd systemctl status containerd验证 containerd 可用ctr version ctr images pull registry.aliyuncs.com/google_containers/pause:3.9 ctr images ls参数说明SystemdCgroup true必须与 kubelet 的--cgroup-driversystemd一致。sandbox_image是 Pod 的基础容器镜像ARM64 架构下必须确保该镜像有 arm64 版本否则 Pod 永远卡在 Sandbox 创建阶段。4.3 安装 kubelet、kubeadm、kubectlK8S 1.26.15 的 ARM64 二进制包可以从官方或镜像站获取。三个组件在所有 Master 和 Node 上都要装。# 下载 ARM64 二进制 # kubelet kubeadm kubectl 三个文件 chmod x kubelet kubeadm kubectl mv kubelet kubeadm kubectl /usr/local/bin/ # 验证 kubeadm version kubectl version --client创建 kubelet 的 systemd 服务[Unit] Descriptionkubelet: The Kubernetes Node Agent Aftercontainerd.service Wantscontainerd.service [Service] ExecStart/usr/local/bin/kubelet \ --config/var/lib/kubelet/config.yaml \ --kubeconfig/etc/kubernetes/kubelet.conf \ --hostname-override$(hostname) \ --v2 Restartalways RestartSec10 [Install] WantedBymulti-user.target注意kubelet 的 config.yaml 和 kubelet.conf 由 kubeadm init/join 生成此时先不要启动 kubelet等 kubeadm 执行完再启动。5. kubeadm 拉起一主多从外部 etcd 对接与 Node 加入5.1 编写 kubeadm 配置文件kubeadm 默认自己部署 etcd要对接外部 etcd 必须用配置文件指定etcd.external。创建kubeadm-config.yamlapiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.26.15 controlPlaneEndpoint: 192.168.1.20:6443 networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 etcd: external: endpoints: - https://192.168.1.10:2379 caFile: /etc/etcd/ssl/ca.pem certFile: /etc/etcd/ssl/etcd.pem keyFile: /etc/etcd/ssl/etcd-key.pem --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd参数说明controlPlaneEndpoint是 API Server 的访问入口单 Master 就写 Master IP。podSubnet要和后面装的 CNI 插件网段一致这里用 Flannel 默认的 10.244.0.0/16。etcd.external下的证书路径必须是 Master 节点上实际存在的路径需要把 etcd 的证书提前拷贝到 Master 的/etc/etcd/ssl/下。5.2 执行 kubeadm init# 预检提前发现问题 kubeadm init --configkubeadm-config.yaml --dry-run # 正式初始化 kubeadm init --configkubeadm-config.yaml --upload-certs # 初始化成功后配置 kubectl mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # 验证集群状态 kubectl get nodes kubectl get pods -n kube-system此时 Master 节点状态是 NotReady因为还没装 CNI。kubectl get pods -n kube-system里 kube-apiserver、kube-controller-manager、kube-scheduler 应该是 Runningetcd 不会出现在列表里因为它是外部的。5.3 安装 CNI 插件ARM64 架构下 CNI 插件的镜像必须有 arm64 版本。Flannel 和 Calico 都支持这里以 Flannel 为例# 下载 flannel 的 arm64 镜像并导入或直接使用支持 arm64 的镜像地址 kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml如果离线环境需要提前把 flannel 的 arm64 镜像导入到 containerdctr images import flannel-arm64.tar安装后确认kubectl get pods -n kube-flannel kubectl get nodes # Master 应变为 Ready5.4 Node 节点加入集群在 Master 上生成 join 命令kubeadm token create --print-join-command输出类似kubeadm join 192.168.1.20:6443 --token abcdef.1234567890abcdef \ --discovery-token-ca-cert-hash sha256:xxxxx在每个 Node 上执行这条命令。执行前确保 Node 上 containerd 已启动、kubelet 已安装、系统配置已完成。# 在 Node 上执行 kubeadm join 192.168.1.20:6443 --token abcdef.1234567890abcdef \ --discovery-token-ca-cert-hash sha256:xxxxx加入后在 Master 上验证kubectl get nodes -o wide # 所有节点应为 Ready6. 避坑排查麒麟 V10 ARM 部署 K8S 最容易翻车的 5 个点6.1 kubelet 启动报 failed to run Kubelet: misconfiguration: kubelet cgroup driver: cgroupfs is different from docker cgroup driver: systemd现象kubelet 反复重启日志里出现 cgroup driver 不一致的报错。原因containerd 的SystemdCgroup没设为 true或者 kubelet 的cgroupDriver没设为 systemd两边不一致。解决确认/etc/containerd/config.toml里SystemdCgroup true确认 kubeadm-config.yaml 里KubeletConfiguration的cgroupDriver: systemd然后重启 containerd 和 kubelet。6.2 Pod 卡在 ContainerCreatingdescribe 显示 failed to pull image pause:3.9现象所有 Pod 都起不来kubectl describe pod看到 sandbox 镜像拉取失败。原因containerd 默认的 sandbox_image 指向 registry.k8s.io国内网络拉不到或者该镜像没有 arm64 版本。解决修改 config.toml 里的sandbox_image为可访问的 arm64 pause 镜像地址重启 containerd。离线环境提前用ctr images pull拉好。6.3 kubeadm init 报 etcd 连接超时现象kubeadm init卡在连接 etcd 阶段报 context deadline exceeded。原因Master 节点无法访问 etcd 的 2379 端口或者证书路径不对、证书里没有 Master 的 IP。解决先在 Master 上用 etcdctl 测试连通性确认防火墙、端口、证书三要素。证书的 hosts 字段必须包含 etcd 节点 IPMaster 连接 etcd 用的是 etcd 的服务端证书不需要包含 Master IP但 etcd 的listen-client-urls必须监听正确地址。6.4 Node 加入后状态一直是 NotReady现象kubectl get nodes显示 Node 为 NotReadydescribe 显示 network plugin not ready。原因CNI 插件没装或者 CNI 的镜像没有 arm64 版本导致 DaemonSet 起不来。解决确认 flannel 或 calico 的 DaemonSet Pod 是否 Running检查镜像架构。ARM 环境下必须用支持 arm64 的 CNI 镜像。6.5 麒麟 V10 上 containerd 启动报 failed to load overlay module现象containerd 启动失败日志提示 overlay 模块加载不了。原因麒麟 V10 内核可能没编译 overlay 模块或者模块名不同。解决modprobe overlay手动加载如果失败检查内核版本和模块路径。部分麒麟版本需要安装kmod相关包。实在不行containerd 可以降级用nativesnapshotter但性能会差很多。7. 集群验证与日常运维的一个实用技巧集群拉起来只是开始真正交付前必须做一轮完整验证。我一般会按这个顺序过一遍先kubectl get nodes -o wide确认所有节点 Ready 且内网 IP 正确再kubectl get pods -n kube-system确认核心组件全 Running然后跑一个跨节点的测试 Pod验证网络连通性。# 部署一个测试 Deployment副本分布到不同 Node kubectl create deployment nginx-test --imageregistry.aliyuncs.com/google_containers/nginx:1.25 --replicas3 kubectl get pods -o wide # 确认 Pod 分布在不同 Node 且 Running # 测试跨节点网络 kubectl run test-pod --imageregistry.aliyuncs.com/google_containers/busybox:1.36 --rm -it -- sh # 在 Pod 内 ping 另一个 Pod 的 IPARM64 环境下镜像架构是最隐蔽的坑。很多 x86 上跑得好好的镜像在 ARM 上拉下来直接 exec format error。验证方法是在 Pod 里执行uname -m输出aarch64才对。日常运维中我习惯在 CI 流水线里加一步镜像架构检查用docker manifest inspect或skopeo inspect确认目标镜像有 arm64 层避免部署时才发现。另一个实用技巧是给 kubelet 配--hostname-override。麒麟 V10 在某些云环境下 hostname 会被 DHCP 改掉导致 Node 注册的名字和实际不符kubelet 反复注册失败。在 kubelet 启动参数里显式指定--hostname-override$(hostname)或者写死主机名能省掉很多玄学问题。证书过期也是绕不开的。K8S 1.26 的集群证书默认一年有效期交付后客户可能半年才想起来续。我一般会在部署完就配好自动续签的 cron用kubeadm certs renew all加systemctl restart kubelet组合提前写好脚本放在/etc/cron.monthly/下。血泪经验是别等证书过期了才处理那时候 apiserver 已经起不来连 kubectl 都用不了只能手动进容器恢复非常被动。这套麒麟 V10 加 ARM 加外部 etcd 加 containerd 的组合坑主要集中在架构适配和组件对接上把证书、cgroup、镜像架构这三样盯死基本就能一次跑通。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
Claude Code深度解析:AI编程代理如何重塑终端工作流 1. 先聊清楚:Claude Code 到底是什么,以及它凭什么值得关注我第一次注意到Claude Code这个关键词,是在一个技术社群里。有人贴了一段终端截图,里面是一个交互式命令行界面,AI 在逐行分析和修改代码,评论区全… · 2026/9/24 19:54:34
数据库课程设计入门:从四张空表理解表结构与约束设计 刚接手数据库课程设计时,任务书写得很简短:SchoolDB数据库,设计四张表,无数据。说实话,第一次看到“无数据”三个字,很多人是愣住的——不让我填数据,那我交什么?后来我才明白&#… · 2026/9/24 19:54:26
C++控制台游戏实战:深海炸弹项目从零实现 简介:这是一份面向C初学者的期末大作业实践资源,聚焦游戏开发入门,通过深海炸弹小游戏项目系统训练面向对象编程、基础物理模拟、碰撞检测与GUI交互能力。资源包含完整可运行工程:79个文件,涵盖9个.cpp源码、10个.h头文… · 2026/9/24 19:54:26
番茄工作法在软件测试中的实战应用与落地指南 我想先聊一个场景:你坐在工位上,刚把一条用例的前置数据准备好,正准备开始执行,微信弹了需求变更,紧接着测试环境挂了,等环境的时候顺手刷了十分钟网页,等环境好了,刚才那条用例的逻… · 2026/9/24 20:24:23
外贸必备:集装箱类型、尺寸对照与装柜计算全攻略 做外贸这些年,我最大的体会是:很多新手一开始把精力全扑在找客户、谈价格上,结果货快出了,却在"装什么柜子、能装多少、怎么装"上栽了跟头。集装箱的类型与尺寸,看似是物流环节里最不起眼的基础知识… · 2026/9/24 20:24:23
重组人IL-6蛋白实验应用全攻略:从信号通路到临床转化 在生物医学实验室泡久了的人,对IL-6这个名字绝对不会陌生。白介素-6(Interleukin-6)可以说是整个炎症网络里最核心的枢纽分子之一,几乎所有跟免疫、炎症、肿瘤、自身免疫病相关的课题,绕来绕去都会碰到它。但真正动手去… · 2026/9/24 20:24:17
IL-6重组蛋白研究从信号通路到临床应用的完整指南 我们实验室和IL-6打交道快十年了,从最初拿重组蛋白做细胞增殖实验,到后来用各种突变体和中和抗体去拆解信号通路,再到近几年参与几个抗体药物的临床前评估,这一路踩过的坑、积累的经验,确实值得好好写一写。很多人问我… · 2026/9/24 20:24:17
Flask+微信小程序构建寻亲平台:全栈实战与部署指南 “宝贝回家”这几个字,对做技术的人来说,不应该只是新闻里的感人故事。它背后是一个极其典型的 Web 全栈实战场景:地理位置、图片存储、模糊搜索、状态流转、消息通知,全部都在一个小程序里。用 Flask 做后端,配合微信… · 2026/9/24 20:24:17
蓝牙SoC产线反复升级问题排查:以中科蓝讯BT5756C为例 做蓝牙音频方案这些年,中科蓝讯的芯片没少折腾,BT5756C算是我手里出镜率比较高的一颗。前两天刚好有个做耳机的客户找过来,说产线测试盒升级固件的时候遇到了个怪现象:固件烧进去了,板子也重启了,可没跑两秒… · 2026/9/24 20:24:17
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44