
简介面向麒麟Kylin V10操作系统与ARM架构CPU环境这套离线资源合集提供了基于containerd部署Kubernetes 1.26.15多主多从集群的完整素材适合国产化替代背景下需要自建高可用K8S的运维人员与架构师。包内共47个文件以系统镜像包gz、rpm安装包、shell脚本及yml/yaml/service等配置文件为主其中既包含kube-apiserver、etcd、coredns、calico等核心组件镜像也提供keepalived高可用配置、kubeadm初始化与节点加入脚本整体约622MB结构清晰可直接落地参考。已有254人学习浏览。其核心价值在于将离线部署所需的关键部分集中整理从containerd运行时、kubeadm/kubelet二进制到网络插件与负载均衡配置均有覆盖配合多主多从架构的编排思路可显著降低在ARM麒麟环境下搭建生产级K8S集群的调研与踩坑成本。1. Kylin ARM 集群为什么不选 Docker而是 containerd 直连在 Kylin V10 的 ARM 架构服务器上部署 K8S 1.26.15 多主多从集群我第一个踩的坑不是 kubeadm 命令而是容器运行时选型。网上大量教程默认先装 Docker 再让 K8S 调用但 K8S 从 1.24 开始就把 containerd 作为默认运行时ARM 版麒麟的 Docker 包不全不说装完还得处理 cgroup driver、手动改 pause 镜像绕一大圈回到原点。这份资源合集把 ARM 架构下需要的 containerd 1.7.2、pause-3.9、etcd 3.5.10、各组件镜像和 kubeadm 配置模板全部提前打包内网离线也能直接拉起一套多主多从集群。适合要在国产 ARM 服务器上快速交付 K8S 环境的运维和交付工程师。2. 环境初始化rpm 离线包、内核模块与 hosts 解析2.1 节点规划与架构确认先把拓扑定下来。多主多从我建议按三主两从来做三个 master 承载 apiserver、controller-manager、scheduler 和 etcd两个 node 跑业务负载。资源包里对应的就是 kubeadm-first-master.yml、kubeadm-join-master.yml 和 kubeadm-join-node.yml 三套模板分别对应第一台主节点、后续主节点和从节点三种初始化方式。角色主机名推荐配置说明master1master014C8G首个控制面节点master2master024C8G第二控制面节点master3master034C8G第三控制面节点node1node014C8G运行业务负载node2node024C8G运行业务负载动手前先用 uname -m 确认内核架构是 aarch64如果是 x86_64 的机器这套 ARM 资源包就用不上。cat /etc/os-release 确认系统是 Kylin Linux Advanced Server V10子版本一般是 Halberd内核停在 Linux 4.19 系列。这两个信息直接决定后续依赖包和镜像选型我习惯在每台机器上都跑一遍确认再继续。uname -m cat /etc/os-release cat /proc/versionuname -m 返回 aarch64 才说明这套资源里的 arm64 二进制和镜像能直接用/etc/os-release 里能看到 V10 的具体子版本号SP1 和 SP2 在部分依赖包的 glibc 版本上有细微差异不过资源包里的 rpm 都是兼容实测过的SP1/SP2 都能装。内核版本建议不低于 4.19太老的内核缺少 IPVS 模块支持。2.2 离线 rpm 依赖安装资源包里有个 pkgs 目录里面是针对 ARM 麒麟编译好的依赖包包括 ipvsadm、conntrack、ebtables、socat、ipset、sysstat。其中 ipvsadm 和 ipset 是 kube-proxy 开启 IPVS 模式时的核心依赖socat 是 kubeadm 做端口检查时要用到的ebtables 和 conntrack 被 kube-proxy 和网络插件调用。sysstat 不是集群必需但排查 CPU 和 IO 问题时非常好用我一般顺手装上。cd pkgs for rpm in $(ls *.rpm | sort); do rpm -ivh --nodeps $rpm || echo install $rpm failed done这里用 rpm -ivh 而不是 yum install是因为离线环境没有可用软件源--nodeps 可以跳过极少数无意义的依赖检查但前提是你清楚这个包的真实依赖已经满足。实际安装时我遇到过个别包因为 glibc 版本被卡住把报错里提示的冲突包用 rpm -e 先卸掉再装就能过。装完 ipvsadm 后建议用 ipvsadm -L 验证一下模块能否正常加载。2.3 内核模块与 sysctl 参数K8S 集群对内核有两个硬性要求桥接流量要能走 iptablesIPVS 相关模块要能加载。ARM 麒麟的 4.19 内核默认不会自动加载这些模块需要手动 modprobe并把开机自动加载写进 /etc/modules-load.d/k8s.conf。cat /etc/modules-load.d/k8s.conf EOF br_netfilter nf_conntrack ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh EOF for m in br_netfilter nf_conntrack ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh; do modprobe $m donebr_netfilter 让 bridge 上的流量也能被 iptables 规则过滤K8S 的 Service 和 Pod 通信都依赖这个。ip_vs 系列模块是 kube-proxy IPVS 模式的基础模块不全时 kube-proxy 会报错并从 IPVS 回退到 iptables。加载完用 lsmod | grep ip_vs 确认如果有缺失模块检查内核是否编译了对应功能。内核参数也要调整主要三条net.bridge.bridge-nf-call-iptables 控制 iptables 对 bridge 流量的过滤net.ipv4.ip_forward 开启路由转发vm.swappiness 调低避免 swap 干扰 kubelet。cat /etc/sysctl.d/k8s.conf EOF net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 vm.swappiness 0 EOF sysctl --systemvm.swappiness 0 是因为 kubelet 对 swap 很敏感1.26 虽然支持通过 --fail-swap-onfalse 容忍 swap但生产环境建议直接关闭 swap 或者只保留极少量的分页空间。sysctl --system 之后用 sysctl net.ipv4.ip_forward 确认参数已生效这个参数没开的话Pod 之间跨节点通信会静默失败。2.4 主机名与 hosts 解析多主多从集群里etcd、apiserver、kubelet 之间大量通过主机名互相访问机房 DNS 不给力或者干脆没有内网 DNS 时就得把 /etc/hosts 写死。hostnamectl set-hostname master01 cat /etc/hosts EOF 192.168.10.11 master01 192.168.10.12 master02 192.168.10.13 master03 192.168.10.14 node01 192.168.10.15 node02 EOF注意一定要把当前节点自己的 IP 和主机名也写进去否则 kubelet 注册节点时会因为无法解析本机 hostname 而卡在 NotReady。这一步不要省很多 join 之后节点状态异常的案例最后查出来就是 hosts 漏了本机条目。所有节点的主机名建议统一规划不要用 localhost 或带下划线的名字K8S 对主机名里的下划线会直接拒绝。3. containerd 1.7.2 配置从解压到 crictl 拉通3.1 解压 cri-containerd-cni 与 libseccomp 处理资源包里 cri-containerd-cni-1.7.2-linux-arm64.tar.gz 是 containerd 官方发布的 ARM 版打包里面已经包含了 containerd、ctr、crictl 和标准 CNI 插件不需要再额外装 runc。解压直接到根目录它会自动落到 /usr/local/bin、/etc/containerd、/opt/cni 等标准路径。tar -C / -xzf cri-containerd-cni-1.7.2-linux-arm64.tar.gz解压后验证一下 containerd 版本ARM 版和 x86 版在命令输出上没有任何差别但二进制文件格式是 aarch64 的不能在 x86 机器上跑。此时先别急着启动 containerdARM 麒麟自带的 libseccomp 版本可能偏老containerd 启动时加载 seccomp 过滤规则会报符号找不到的错误资源包里单独带的 libseccomp.so.2 就是用来替换的。cp libseccomp.so.2 /usr/lib64/ # 或 /lib/aarch64-linux-gnu/ ldconfig ldconfig -p | grep libseccomp具体放哪个目录取决于你系统里 libseccomp.so.2 目前所在的路径用 ldconfig -p | grep libseccomp 查一下原路径再覆盖。这一步做完之后再启动 containerd 就不会出现 seccomp 相关的加载失败。这个坑在 ARM 麒麟上出现频率很高x86 的 CentOS 很少遇到所以我单独列出来。3.2 config.tomlSystemdCgroup、sandbox_image 与 registrycontainerd 默认配置不满足 K8S 的要求必须改两处cgroup 驱动和 pause 镜像。K8S 1.26 的 kubelet 默认使用 systemd cgroup drivercontainerd 如果不对齐Pod 启动时 kubelet 会报 cgroup driver 不匹配直接拒绝创建沙箱。mkdir -p /etc/containerd containerd config default /etc/containerd/config.toml# 在 /etc/containerd/config.toml 中修改或确认以下关键项 [plugins.io.containerd.grpc.v1.cri] sandbox_image registry.k8s.io/pause:3.9 [plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc] [plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] SystemdCgroup trueSystemdCgroup true 让 containerd 用 systemd 来管理 pause 容器的 cgroup这样与 kubelet 的 cgroup driver 一致。sandbox_image 是每个 Pod 创建时最先拉取的 pause 镜像K8S 1.26.15 对应的是 pause:3.9资源包里 pause-3.9.tar.gz 已经打好导入后把这个值指向导入后的仓库地址即可避免离线环境下去 registry.k8s.io 拉取超时。registry 镜像加速的配置也建议顺手加上虽然离线环境用本地镜像为主但万一后面要拉公网镜像没有 mirror 配置的话会一直卡在 ImagePullBackOff。内网 Harbor 或者 Nexus 的地址按实际环境替换。3.3 load_images.sh 离线导入全量镜像资源包 images 目录下放着所有组件镜像的 tar.gz包括 kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、etcd、coredns、pause 和 Calico 全家桶。导入时用 ctr 而不是 docker load因为 containerd 环境下 ctr 直接对接 containerd 的本地存储。#!/bin/bash # load_images.sh for img in images/*.tar.gz; do ctr -n k8s.io images import $img done关键点在于 -n k8s.io 这个命名空间参数。kubelet 默认通过 CRI 访问 containerd 的 k8s.io 命名空间而 ctr 默认访问的是 default 命名空间如果导入时不指定kubelet 会看不到这些镜像。导入完成后用 ctr -n k8s.io images list 核对确认每个镜像的 repo 和 tag 都正确。这里有个容易被忽略的细节镜像的 repo 名称必须和你 kubeadm 配置里要用的名称一致。比如 kube-apiserver 打包时如果带的前缀是 registry.k8s.io那么 kubeadm 默认拉取路径就是 registry.k8s.io/kube-apiserver:v1.26.15只要本地存在这个 tagkubeadm 就不会再尝试去网络拉取。所以导入后不要随意改 tag除非你同时改了 kubeadm 配置里的 imageRepository。3.4 crictl 验证运行时链路crictl 是排查 containerd 问题的核心工具但它默认连的是 docker socket必须配置 /etc/crictl.yaml 指向 containerd 的 socket否则一执行就报 connection refused。cat /etc/crictl.yaml EOF runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 5 EOF systemctl daemon-reload systemctl enable --now containerd crictl version crictl imagescrictl version 能看到 CRI 版本和 containerd 版本确认服务端正常响应。crictl images 列出镜像列表检查 pause 和 kube-apiserver 是否都在。这步相当于把容器运行时链路先拉通再去做 kubeadm 初始化能够把问题边界切得非常干净后面 kubeadm 报错时你不会再怀疑 containerd 本身没装好。4. kubeadm 多主多从first-master 初始化到两类 join4.1 kubelet、kubeadm、kubectl 二进制安装资源包里有编译好的 v1.26.15 版本 kubeadm、kubelet、kubectl 二进制直接放到 /usr/bin 并加上可执行权限。这三个二进制是从官方 1.26.15 版本抽出来的直接用即可注意不要混用其他小版本的 kubelet 和 kubeadm组件版本不一致会出现 API 版本协商失败。cp kubeadm kubectl kubelet /usr/bin/ chmod x /usr/bin/kubeadm /usr/bin/kubectl /usr/bin/kubelet kubeadm version kubelet --versionkubelet 需要 systemd 托管资源包里带了 kubelet.service 和 10-kubeadm.conf。10-kubeadm.conf 是 systemd drop-in 配置核心作用是给 kubelet 指定启动参数包括 bootstrap-kubeconfig 和 kubelet 配置文件路径这部分不用自己写直接放到 /etc/systemd/system/kubelet.service.d/ 目录下即可。cp kubelet.service /etc/systemd/system/kubelet.service mkdir -p /etc/systemd/system/kubelet.service.d cp 10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf systemctl daemon-reload systemctl enable --now kubelet此时 kubelet 会因为还没有集群而反复重启报错这是正常的不要慌。kubelet 启动后会一直尝试连接 apiserver只有在 kubeadm join 或 init 之后才能稳定运行。只要 systemctl status kubelet 能看到 active 并且在不断重试就说明配置本身没问题。4.2 kubeadm-first-master.yml 关键参数第一台 master 的初始化模板是 kubeadm-first-master.yml它决定了整个集群的控制面端点、Pod 网段和 Service 网段。这个文件是三台 master 共用的因为 controlPlaneEndpoint 指向的是 VIP而不是某个具体节点的 IP。apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.10.11 --- apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.26.15 controlPlaneEndpoint: 192.168.10.100:6443 networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12controlPlaneEndpoint 必须写成 keepalived 提供的 VIP 加端口这样所有 join 进来的节点都会通过 VIP 访问 apiserverVIP 在三台 master 之间漂移时节点端的 kubelet 不需要做任何调整。podSubnet 用 10.244.0.0/16 是因为 Calico 默认的 IPAM 池和这个网段一致如果不改 Calico 配置这里就不要改网段。serviceSubnet 保持默认的 10.96.0.0/12 即可。4.3 初始化与 kubeconfig 分发配置检查无误后在 master01 上执行初始化。整个初始化过程会拉取 etcd、apiserver、controller-manager、scheduler、coredns 等镜像因为前面已经完成了离线导入本地仓库里有对应镜像kubeadm 会直接使用本地镜像不会去外网拉取。kubeadm init --config kubeadm-first-master.yml --v5初始化成功的标志是最后输出一段提示包含 kubeconfig 配置命令和一条完整的 kubeadm join 命令。先把 kubectl 的 kubeconfig 配置好这一步不做的话 kubectl 无法连接集群。mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config kubectl get nodes然后把 admin.conf 分发到其他节点后续在 master02、master03 和 node 节点上操作时都需要这个文件。建议统一都放到用户家目录的 .kube/config 路径下避免每台机器都重新生成证书。scp /etc/kubernetes/admin.conf rootmaster02:/root/.kube/config scp /etc/kubernetes/admin.conf rootmaster03:/root/.kube/config scp /etc/kubernetes/admin.conf rootnode01:/root/.kube/config scp /etc/kubernetes/admin.conf rootnode02:/root/.kube/config4.4 join-master 与 join-node 的模板差异多主多从的本质区别在于master 用 kubeadm-join-master.ymlnode 用 kubeadm-join-node.yml。先拿 token 和 CA 哈希再到新节点上执行 join。kubeadm token create --print-join-command kubeadm init phase upload-certs --upload-certskubeadm token create --print-join-command 会输出一行标准的 join 命令包含 token 和 discovery-token-ca-cert-hash。kubeadm init phase upload-certs --upload-certs 用来把控制面的证书加密上传输出的 certificate-key 是 join 新 master 时的必填参数依赖这个 key 来解密控制面证书然后复制到新 master 上。# master02 / master03 执行增加 --control-plane 和 --certificate-key kubeadm join 192.168.10.100:6443 \ --token token \ --discovery-token-ca-cert-hash sha256:hash \ --control-plane \ --certificate-key key # node01 / node02 执行不带 --control-plane kubeadm join 192.168.10.100:6443 \ --token token \ --discovery-token-ca-cert-hash sha256:hashmaster 和 node 的 join 命令差别就这两行参数control-plane 和 certificate-key。带 control-plane 的节点会额外部署 etcd 成员、apiserver、controller-manager、scheduler 这些控制面组件不带 control-plane 的节点只启动 kubelet 和 kube-proxy。证书 key 是一次性用品如果过期或者换 token重新执行一次 kubeadm init phase upload-certs 再拿新的即可。5. 高可用与 Calicokeepalived、kube-lb 与 CNI 配合5.1 keepalived 配置与 VIP 生效控制面高可用依赖 VIP 在三台 master 之间漂移。VIP 就是 kubeadm 配置里写死的 controlPlaneEndpoint 地址它由 keepalived 负责维护正常情况落在 master01 上master01 故障时自动跳到 master02 或 master03。# /etc/keepalived/keepalived.conf master01 配置 global_defs { router_id K8S_LVS } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass K8S_VIP } virtual_ipaddress { 192.168.10.100/24 dev eth0 } }master02 和 master03 的配置只改两处state 改为 BACKUPpriority 改为 90 和 80。priority 决定抢占顺序数值越大优先级越高。VIP 的 netmask 要和业务网段一致否则其他节点访问 VIP 时会因为路由问题通不了。配置完成后启动 keepalived用 ip addr show eth0 能看到 VIP 已经在 master01 上。systemctl enable --now keepalived ip addr show eth0 | grep 192.168.10.100有个坑容易忽略firewalld 会拦 VRRP 广播协议如果 VIP 在节点间切不出去先检查防火墙是否放行了 vrrp或者干脆在测试环境临时停掉 firewalld。keepalived 本身不做流量转发它只负责通告 VIP真正的 apiserver 流量要靠下一层的 kube-lb。5.2 kube-lb 四层转发VIP 到 apiserverkeepalived 把 VIP 挂到本机网卡后访问 VIP:6443 的流量会进入本机内核此时需要一个四层代理把流量转发到三台 master 的 apiserver。资源包里的 kube-lb 就是干这个的它是轻量级四层负载均衡配置在 kube-lb.conf 里指定后端列表。cp kube-lb /usr/local/bin/ cp kube-lb.conf /etc/kube-lb/kube-lb.conf cp kube-lb.service /etc/systemd/system/ systemctl daemon-reload systemctl enable --now kube-lbkube-lb.conf 的核心是定义一个监听 6443 的前端和后端列表后端就是三台 master 的 apiserver 地址。三个后端都标记为 checkkube-lb 会周期性做 TCP 健康检查某个节点挂掉后自动从转发列表中摘除。frontend k8s-apiserver bind *:6443 default_backend k8s-masters backend k8s-masters server master01 192.168.10.11:6443 check inter 3s fall 3 rise 2 server master02 192.168.10.12:6443 check inter 3s fall 3 rise 2 server master03 192.168.10.13:6443 check inter 3s fall 3 rise 2kube-lb 必须和 keepalived 同时运行在同一台 master 上keepalived 负责让 VIP 出现在本机kube-lb 负责接管本机 6443 端口的流量并转发。验证方法很简单在三台 master 的任何一台执行 curl https://192.168.10.100:6443/healthz -k能看到 ok 就说明 VIP 到 apiserver 的链路是通的。如果返回 refused先确认当前 VIP 在哪台机器上再到那台机器看 kube-lb 是否在运行。5.3 Calico 3.26.4 ARM 镜像与网段对齐控制面起来之后Pod 网络还是空的kubectl get nodes 会看到节点全部 NotReady因为容器网络插件没有安装。资源包里的 calico.yaml 是 3.26.4 版本对应 ARM 架构的镜像也已经在 images 目录里打好了包。Calico 安装前要改两处镜像地址和 Pod 网段。离线环境下 kubelet 不会去拉公网镜像所以 calico.yaml 里的 image 字段必须和你导入镜像时的 repo 完全一致。资源包里的镜像名是 calico-node-v3.26.4.tar.gz导入后的默认 tag 一般是 calico/node:v3.26.4把 yaml 里的 image 字段同步改掉即可。grep -n image: calico.yaml | head -20 sed -i s|docker.io/calico/node:v3.26.4|calico/node:v3.26.4|g calico.yaml sed -i s|docker.io/calico/calico-cni:v3.26.4|calico/cni:v3.26.4|g calico.yaml kubectl apply -f calico.yaml网段对齐也很关键。Calico 默认的 IPv4 池是 192.168.0.0/16而 kubeadm-first-master.yml 里 podSubnet 写的是 10.244.0.0/16两者不一致的话Calico 会给 Pod 分配 192.168 网段的 IPkubelet 却认为 Pod 应该在 10.244 网段Pod 直接创建失败。需要在 calico.yaml 里把 CALICO_IPV4POOL_CIDR 改成 10.244.0.0/16。# calico.yaml 中的 ConfigMap 部分 - name: CALICO_IPV4POOL_CIDR value: 10.244.0.0/16Calico 启动后还需要确认每个节点的转发网卡。ARM 服务器经常有多网卡Calico 默认自动选择第一个可用网卡做隧道如果选错会导致跨节点 Pod 不通。一般在 calico-node 的 DaemonSet 环境变量里加一条 IP_AUTODETECTION_METHOD 指定内网网卡名比如 eth0这个值根据实际规划改。6. 验证与常见问题排查让集群真正可交付6.1 集群健康检查清单集群搭建完不要急着部署业务先把基础链路验证一遍。我从资源包里的 test、nginx、busybox 这套验证组合里挑最简单的方式起一个 nginx 无头服务从其他节点访问检查跨节点打通情况。kubectl get nodes -o wide kubectl get pods -A kubectl get svc -A kubectl run nginx-test --imagenginx --restartNever --port80 kubectl wait --forconditionReady pod/nginx-test --timeout120s kubectl get pod nginx-test -o widekubectl get nodes 所有节点 Readykubectl get pods -A 里 coredns 和 calico 全部 Running基础网络就算通了。nginx-test 跨节点访问验证确认调度到 node01 上的 Pod 能从 node02 访问通这一步检查的是 Calico 的跨节点路由很多集群 Pod 本地通、跨节点不通的问题都是在这一步暴露的。6.2 高频踩坑记录kubelet 报 cgroup driver 不匹配。现象是 kubelet 日志反复出现 failed to run Kubelet: cgroup driver 相关内容kubelet 起不来。原因是 containerd 的 SystemdCgroup 没有开启而 kubelet 默认用 systemd driver。解决方法是改 /etc/containerd/config.toml 里 SystemdCgroup true重启 containerd 和 kubelet。crictl images 能看到镜像但 Pod 一直 ErrImagePull。现象是 Pod 事件里报 Failed to pull image明明本地有镜像。原因是 sandbox_image 的 repo 和你导入时的 tag 不一致kubelet 按配置的完整地址去本地仓库找找不到就尝试外网拉取。解决方法是把 sandbox_image 改成 ctr -n k8s.io images list 里显示的完整名称。node join 后一直 NotReadydescribe 显示 CNI 未初始化。现象是 kubectl get nodes 看到节点 NotReadydescribe 里 network plugin is not ready: cni config uninitialized。原因是 Calico 的 Pod 还没在这个节点上运行或者 calico.yaml 里的网段与 kubeadm 配置不一致。解决方法是先确认 calico.yaml 的 CALICO_IPV4POOL_CIDR再 kubectl apply 完整应用 Calico。第二个 master join 后 etcd 集群异常。现象是 kubectl get nodes 能看到三台 master但 etcd 容器反复重启日志报 member 加入失败。原因是 join 时丢失 --certificate-key 参数或者 certificate-key 过期。解决方法是重新执行 kubeadm init phase upload-certs --upload-certs 生成新 key再次执行干净的 join。VIP 在 master 间漂移后 kubectl 失联。现象是 master01 宕机后 VIP 切到 master02但 kubectl 连不上集群。原因是 kube-lb 只运行在 master01 上其它 master 没接管流量转发。解决方法是把 kube-lb 做成 systemd 服务并在三台 master 上都启用keepalived 和 kube-lb 必须同时运行在同一台机器VIP 漂到哪台哪台的 6443 就必须有转发进程在监听。从那以后我在 ARM 麒麟上搭 K8S每次都是先跑一遍 get_images.sh 确认仓库再 load_images.sh 导入镜像然后才动 kubeadm init。这五条坑覆盖了从运行时到网络插件的大部分故障场景资源包里配套的脚本和 test 镜像都齐照着这套流程走一遍基本上一个工作日能拉起一套可交付的多主多从集群。希望帮到你。本文还有配套的精品资源点击获取