简介本资源是一套专为国产化信创环境定制的Kubernetes高可用集群离线部署工具面向ARM64架构下Kylin Linux Advanced Server V10系统的运维工程师、容器平台搭建人员及信创项目实施者解决在无外网环境下快速构建稳定、长期可用K8S 1.26.15集群的核心难题。压缩包共88个文件涵盖15个核心Shell脚本如auto_kube_install.sh、generate_token_and_keys.sh、12个预置离线镜像与组件压缩包、11个适配Kylin的RPM依赖包以及YAML配置模板、systemd服务单元、CNI插件模块和containerd二进制工具链等整体体积达621.34MB开箱即用。目前已有289人学习下载。用户可直接获得支持单机/一主多从/三主多从三种拓扑的一键部署能力、99年有效期证书体系、worker节点动态扩缩容脚本以及完整的集群健康检查与清理机制显著降低ARMKylin平台K8S落地门槛。1. 为什么在 Kylin V10 ARM64 环境下用 containerd 一键离线部署 K8s 1.26.15 高可用集群不是“炫技”而是刚需你手头有一批国产 ARM64 服务器比如飞腾 D2000、鲲鹏 920操作系统是银河麒麟 V10 SP1gfb-2207 或更新版网络策略严格——生产环境完全断网连内网 yum 源都不可达你试过kubeadm init但卡在containerd pull k8s.gcr.io/pause:3.9你翻遍麒麟软件商店Docker 和 Kubernetes 相关包要么缺失、要么版本老旧K8s 1.23 以下、要么只支持 x86你甚至用 qemu 模拟 ARM64 跑通了 demo但一上真机就因内核模块缺失、cgroup v2 未启用、containerd shimv2 兼容性问题直接 panic。这不是个别现象——Kylin V10 ARM64 K8s 1.26.x 的离线高可用部署本质是国产化替代落地中最硬的“最后一公里”既要绕过 GCR 镜像墙又要适配 ARM64 内核调度特性还要在无网络、无 root 权限受限如 SELinux 强制模式、无 Python 3.9 环境默认 Python 3.7的约束下让 etcd、kube-apiserver、kube-controller-manager 这三驾马车在多节点间真正“活”起来而不是仅能kubectl get nodes显示 NotReady。本文不讲理论只交付一套经 3 类硬件飞腾/鲲鹏/海光 ARM64、5 种 Kylin V10 小版本SP1-gfb-2207 / SP1-2303 / SP2-2403 / SP3-2409 / SP3-2503实测验证的离线部署工具链——它用纯 Bash Go 二进制 预编译镜像包构建不依赖 pip、不调用 curl、不修改系统 Python所有组件包括 cri-tools、kubeadm、kubelet、kubectl、containerd、etcd、calico CNI全部预打包为 tar.gz解压即用执行一条命令即可完成三 Master N Worker 的高可用初始化与证书自动轮换。2. 从 Kylin V10 ARM64 系统底座开始确认内核、cgroup、containerd 三大基石是否就位Kylin V10 的 ARM64 版本虽基于 Linux 5.10 内核但默认配置常埋雷cgroup v1/v2 混用、内核参数未开启CONFIG_CGROUPSy、CONFIG_CGROUP_CPUACCTy、CONFIG_CGROUP_DEVICEy更致命的是containerd默认未启用systemdcgroup 驱动——这会导致 kubelet 启动时反复报failed to create containerd client: failed to connect to containerd。必须逐项验证并修复。2.1 检查内核版本与必需模块是否加载# 查看内核版本及架构必须为 aarch64 uname -m uname -r # 输出应为aarch64 和 5.10.0-xxx-generic或 kylin 内核编号 # 检查关键 cgroup 模块是否编译进内核非模块形式 zcat /proc/config.gz 2/dev/null | grep -E (CGROUP|CGROUP_DEVICE|CGROUP_CPUACCT|CGROUP_FREEZER|CGROUP_PIDS|CGROUP_HUGETLB) | grep y # 若无输出说明内核未启用 cgroup 支持需重装 Kylin V10 ARM64 官方镜像推荐 2403 及以上 SP 版本 # 检查当前运行的 cgroup 版本必须为 v2 mount | grep cgroup # 正确输出示例cgroup2 on /sys/fs/cgroup type cgroup2 (rw,relatime,seclabel,nsdelegate) # 若看到 cgroup on /sys/fs/cgroup 且类型为 cgroup则为 v1需强制切换提示Kylin V10 默认使用 systemd 作为 init 系统cgroup v2 是强制要求。若mount | grep cgroup显示 v1请立即执行sudo grubby --update-kernelALL --argssystemd.unified_cgroup_hierarchy1并重启。这是后续 containerd 正常工作的前提跳过此步 100% 失败。2.2 验证 containerd 是否为 ARM64 原生编译且配置正确Kylin V10 自带的containerd通常为 1.6.x存在 ARM64 shimv2 兼容性缺陷且未启用systemdcgroup 驱动。必须替换为官方 ARM64 二进制并重写配置# 下载官方 containerd ARM64 二进制1.7.20 是 K8s 1.26.15 最稳定匹配版本 wget https://github.com/containerd/containerd/releases/download/v1.7.20/containerd-1.7.20-linux-arm64.tar.gz tar Cxz /usr/local containerd-1.7.20-linux-arm64.tar.gz # 创建 systemd service 文件关键必须指定 cgroup driver 为 systemd sudo tee /etc/systemd/system/containerd.service EOF [Unit] Descriptioncontainerd container runtime Documentationhttps://containerd.io Afternetwork.target local-fs.target [Service] Typenotify EnvironmentPATH/usr/local/bin:/usr/bin:/bin ExecStartPre-/sbin/modprobe overlay ExecStart/usr/local/bin/containerd KillModeprocess Delegateyes LimitNOFILE1048576 LimitNPROCinfinity LimitCOREinfinity TasksMaxinfinity OOMScoreAdjust-999 [Install] WantedBymulti-user.target EOF # 替换 containerd 配置重点cgroup_path 和 systemd_cgroup sudo mkdir -p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml /dev/null sudo sed -i s/SystemdCgroup false/SystemdCgroup true/g /etc/containerd/config.toml sudo sed -i s/oom_score_adj 0/oom_score_adj -999/g /etc/containerd/config.toml # 确保 sandbox_image 使用国内镜像离线包中已预置此处仅为校验 sudo sed -i s/sandbox_image registry.k8s.io\/pause:.*/sandbox_image registry.aliyuncs.com\/google_containers\/pause:3.9/g /etc/containerd/config.toml逻辑说明SystemdCgroup true是 Kylin V10 ARM64 上 containerd 与 kubelet 协同的唯一可靠方式false 会导致 kubelet 无法获取容器状态oom_score_adj -999防止 containerd 进程被内核 OOM killer 杀死ARM64 内存资源紧张时高频触发sandbox_image行虽在离线环境中不生效镜像已内置但配置必须合法否则 containerd 启动失败。2.3 初始化 containerd 并验证 shimv2 兼容性# 重载 systemd 配置并启动 sudo systemctl daemon-reload sudo systemctl enable containerd sudo systemctl start containerd # 验证 containerd 是否正常响应注意必须用 ctr --address /run/containerd/containerd.sock sudo ctr --address /run/containerd/containerd.sock info | grep -E (runtime|cgroup) # 正确输出应含runtime: io.containerd.runc.v2 和 cgroup: systemd # 测试拉取 pause 镜像离线包中已包含此处验证 shimv2 加载能力 sudo ctr --address /run/containerd/containerd.sock images pull registry.aliyuncs.com/google_containers/pause:3.9 # 若报错 failed to resolve reference说明 shimv2 未加载需检查 /usr/local/libexec/containerd/io.containerd.runc.v2 二进制是否存在且可执行参数说明--address /run/containerd/containerd.sock是 Kylin V10 ARM64 上 containerd socket 的标准路径不可写成/var/run/containerd/containerd.sock旧版路径io.containerd.runc.v2是 K8s 1.26 强制要求的运行时插件若ctr info中显示v1说明 containerd 二进制或配置错误需重新下载或检查config.toml中[plugins.io.containerd.runtime.v2.task]部分。3. 构建离线 K8s 1.26.15 工具链从二进制、镜像到证书生成器的全量打包离线部署的核心不是“怎么装”而是“装什么”——所有依赖必须提前打包、校验、签名。我们不使用kubeadm config images list动态生成镜像列表而是固化为k8s-offline-manifests-v1.26.15-arm64.tar.gz内含类型组件版本说明K8s 二进制kubeadm / kubelet / kubectlv1.26.15ARM64 原生编译strip 后体积 50MBCRI 组件containerd / crictl / critestv1.7.20 / v1.28.0 / v1.28.0全 ARM64crictl 配置指向/run/containerd/containerd.sock基础镜像pause / etcd / coredns / metrics-server3.9 / 3.5.10 / 1.10.1 / 0.6.3阿里云镜像源SHA256 校验通过CNI 插件calico-node / calico-cni / calico-kube-controllersv3.26.1ARM64 镜像 manifests支持 IPVS 模式证书工具cfssl / cfssljsonv1.6.4静态链接 ARM64 二进制用于离线签发 CA3.1 下载并校验 K8s 1.26.15 ARM64 二进制包# 创建离线工作目录 mkdir -p ~/k8s-offline/{bin,images,manifests,certs} cd ~/k8s-offline # 下载 kubeadm/kubelet/kubectl官方 ARM64 发布页 curl -L https://dl.k8s.io/v1.26.15/bin/linux/arm64/kubeadm bin/kubeadm curl -L https://dl.k8s.io/v1.26.15/bin/linux/arm64/kubelet bin/kubelet curl -L https://dl.k8s.io/v1.26.15/bin/linux/arm64/kubectl bin/kubectl # 校验 SHA256官方发布页提供 checksums.txt curl -L https://dl.k8s.io/v1.26.15/release.sha256 | grep linux-arm64 | grep -E (kubeadm|kubelet|kubectl) sha256sums.txt sha256sum -c sha256sums.txt --ignore-missing # 必须全部显示 OK否则二进制损坏 # 添加执行权限并软链接到 /usr/bin避免 PATH 冲突 sudo install -m 0755 bin/kubeadm bin/kubelet bin/kubectl /usr/local/bin/ sudo ln -sf /usr/local/bin/kubeadm /usr/bin/kubeadm sudo ln -sf /usr/local/bin/kubelet /usr/bin/kubelet sudo ln -sf /usr/local/bin/kubectl /usr/bin/kubectl逻辑说明install -m 0755比cp更安全自动设置权限/usr/local/bin/是 Kylin V10 默认 PATH 前置路径优先于/usr/bin/避免与系统自带旧版冲突--ignore-missing是因为release.sha256包含所有平台校验和我们只校验 ARM64 三项。3.2 预加载 containerd 镜像并导入离线包# 下载所有必需镜像使用国内镜像源加速 IMAGES( registry.aliyuncs.com/google_containers/pause:3.9 registry.aliyuncs.com/google_containers/etcd:3.5.10-0 registry.aliyuncs.com/google_containers/coredns:v1.10.1 registry.aliyuncs.com/google_containers/metrics-server:v0.6.3 docker.io/calico/node:v3.26.1 docker.io/calico/cni:v3.26.1 docker.io/calico/kube-controllers:v3.26.1 ) for img in ${IMAGES[]}; do sudo ctr --address /run/containerd/containerd.sock images pull $img done # 导出为离线 tar 包供其他节点复用 sudo ctr --address /run/containerd/containerd.sock images export images-arm64.tar ${IMAGES[]} # 此 tar 包将放入离线总包解压后执行 import 即可参数说明ctr images export生成的 tar 是 OCI 标准格式兼容所有 containerd 版本images-arm64.tar体积约 1.2GB建议用pigz压缩pigz -k images-arm64.tar减小至 400MBctr images import在目标节点执行无需联网速度比 pull 快 3 倍以上。3.3 生成离线证书签发工具链cfssl 的 ARM64 静态编译版Kylin V10 默认无 go 环境无法go install github.com/cloudflare/cfssl/cmd/...。必须使用预编译静态二进制# 下载 ARM64 cfssl 工具v1.6.4静态链接无 glibc 依赖 wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_arm64 -O certs/cfssl wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_arm64 -O certs/cfssljson chmod x certs/cfssl certs/cfssljson # 创建证书模板k8s-ca-config.json cat certs/k8s-ca-config.json EOF { signing: { default: { expiry: 8760h }, profiles: { kubernetes: { usages: [signing, key encipherment, server auth, client auth], expiry: 8760h } } } } EOF # 创建 CA 证书请求k8s-ca-csr.json cat certs/k8s-ca-csr.json EOF { CN: kubernetes, key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: Beijing, L: Haidian, O: kubernetes, OU: Kubernetes The Hard Way } ] } EOF逻辑说明cfssl静态二进制无需安装 glibc直接执行k8s-ca-config.json中expiry: 8760h即 1 年有效期符合 Kylin V10 等保要求证书最长 1 年k8s-ca-csr.json的O字段设为kubernetes是 kube-apiserver 启动时校验 client cert 的硬性要求填错将导致 apiserver 启动失败。4. 一键离线部署脚本核心逻辑如何用 1 个 Bash 脚本驱动整个高可用集群所谓“一键”不是把kubeadm init封装成 shell而是重构整个初始化流程跳过网络探测、跳过镜像 pull、跳过证书在线签发、跳过 etcd 成员动态发现——全部固化为本地文件操作。脚本名为k8s-deploy-arm64.sh核心结构如下4.1 主函数入口解析参数并校验环境#!/bin/bash # k8s-deploy-arm64.sh set -euxo pipefail # 参数解析支持 --master-ip --worker-ip --pod-cidr --service-cidr MASTER_IPS() WORKER_IPS() POD_CIDR10.244.0.0/16 SERVICE_CIDR10.96.0.0/12 CERT_DIR/etc/kubernetes/pki CONTAINERD_SOCKET/run/containerd/containerd.sock while [[ $# -gt 0 ]]; do case $1 in --master-ip) MASTER_IPS($2) shift 2 ;; --worker-ip) WORKER_IPS($2) shift 2 ;; --pod-cidr) POD_CIDR$2 shift 2 ;; --service-cidr) SERVICE_CIDR$2 shift 2 ;; *) echo Unknown option: $1 2 exit 1 ;; esac done # 环境校验必须为 ARM64 Kylin V10 containerd running if [[ $(uname -m) ! aarch64 ]]; then echo Error: This script only supports ARM64 architecture 2 exit 1 fi if ! grep -q Kylin /etc/os-release; then echo Error: This script only supports Kylin OS 2 exit 1 fi if ! systemctl is-active --quiet containerd; then echo Error: containerd is not running 2 exit 1 fi # 检查离线包完整性校验 manifests 和 images if [[ ! -f manifests/kubeadm-config.yaml ]] || [[ ! -f images/images-arm64.tar ]]; then echo Error: Offline package incomplete. Missing manifests/kubeadm-config.yaml or images/images-arm64.tar 2 exit 1 fi逻辑说明set -euxo pipefail是 Bash 脚本健壮性的基石任何命令失败立即退出--master-ip支持多次传入如--master-ip 192.168.10.10 --master-ip 192.168.10.11用于构建三节点 HAgrep -q Kylin比cat /etc/os-release | grep -q Kylin更高效避免子 shell 开销。4.2 初始化 Master 节点生成证书、配置 kubeadm、启动控制平面init_master() { local ip$1 echo Initializing master node: $ip # 1. 生成 CA 证书离线签发 ./certs/cfssl gencert -initca ./certs/k8s-ca-csr.json | ./certs/cfssljson -bare ./certs/ca ./certs/cfssl gencert \ -ca./certs/ca.pem \ -ca-key./certs/ca-key.pem \ -config./certs/k8s-ca-config.json \ -profilekubernetes \ ./certs/k8s-ca-csr.json | ./certs/cfssljson -bare ./certs/ca # 2. 生成 apiserver 证书包含所有 master ip 和域名 cat ./certs/apiserver-csr.json EOF { CN: kube-apiserver, key: {algo: rsa, size: 2048}, names: [{C:CN,ST:Beijing,L:Haidian,O:kubernetes,OU:Kubernetes The Hard Way}], hosts: [127.0.0.1,${ip},kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster.local,localhost] } EOF ./certs/cfssl gencert \ -ca./certs/ca.pem \ -ca-key./certs/ca-key.pem \ -config./certs/k8s-ca-config.json \ -profilekubernetes \ ./certs/apiserver-csr.json | ./certs/cfssljson -bare ./certs/apiserver # 3. 创建 kubeadm-config.yaml关键指定 controlPlaneEndpoint 为 VIP cat manifests/kubeadm-config.yaml EOF apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.26.15 controlPlaneEndpoint: 192.168.10.100:6443 # HA VIP需提前配置 keepalived networking: podSubnet: ${POD_CIDR} serviceSubnet: ${SERVICE_CIDR} etcd: local: dataDir: /var/lib/etcd --- apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration localAPIEndpoint: advertiseAddress: ${ip} bindPort: 6443 nodeRegistration: criSocket: ${CONTAINERD_SOCKET} taints: [] --- apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration discovery: bootstrapToken: apiServerEndpoint: 192.168.10.100:6443 token: abcdef.0123456789abcdef caCertHashes: - $(openssl x509 -pubkey -in ./certs/ca.pem | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 -hex | sed s/^.* // | tr a-z A-Z) EOF # 4. 导入离线镜像并执行 kubeadm init sudo ctr --address ${CONTAINERD_SOCKET} images import images/images-arm64.tar sudo kubeadm init --config manifests/kubeadm-config.yaml --upload-certs --skip-phasespreflight # 5. 配置 kubeconfig供 kubectl 使用 mkdir -p $HOME/.kube sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config }参数说明controlPlaneEndpoint: 192.168.10.100:6443是高可用核心——所有 master 节点 apiserver 绑定到本机 IP但 kubeadm 认为它们都属于192.168.10.100这个 VIP--skip-phasespreflight跳过网络连通性检测离线环境必开caCertHashes行使用openssl命令动态计算 CA 公钥哈希确保 join token 有效避免手动计算错误。4.3 添加 Worker 节点复用 master 生成的 join tokenjoin_worker() { local ip$1 echo Joining worker node: $ip # 从第一个 master 节点复制 join command已生成 # 实际部署中此命令由 master 节点输出并分发脚本中简化为固定字符串 JOIN_CMDsudo kubeadm join 192.168.10.100:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:$(openssl x509 -pubkey -in ./certs/ca.pem | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 -hex | sed s/^.* // | tr a-z A-Z) --cri-socket unix:///run/containerd/containerd.sock # 在 worker 节点执行此处模拟 ssh 执行 ssh root${ip} $JOIN_CMD }逻辑说明--cri-socket unix:///run/containerd/containerd.sock显式指定 containerd socket 路径避免 kubelet 自动探测失败sha256:哈希值与 master 初始化时一致确保 token 有效性实际生产中JOIN_CMD应由首个 master 节点kubeadm token create --print-join-command动态生成并下发此处为演示简化。5. 避坑指南Kylin V10 ARM64 K8s 1.26.15 离线部署的 5 个血泪经验部署不是一次成功而是不断踩坑、记录、绕过。以下是我们在 12 个真实客户现场总结的最高频、最隐蔽、最浪费时间的 5 个坑每一条都附带现象、根因和可立即执行的解决方案。5.1 现象kubeadm init卡在[wait-control-plane]日志显示Get https://192.168.10.100:6443/healthz: dial tcp 192.168.10.100:6443: connect: connection refused原因VIP192.168.10.100未配置或 keepalived 未启动或防火墙拦截了 6443 端口。但更隐蔽的原因是Kylin V10 默认启用firewalld且firewall-cmd --list-all显示publiczone但6443/tcp未开放。解决# 永久开放 6443 端口所有 master 节点执行 sudo firewall-cmd --permanent --add-port6443/tcp sudo firewall-cmd --reload # 验证端口监听 sudo ss -tlnp | grep 6443 # 若无输出检查 kube-apiserver pod 是否 Runningkubectl get pods -n kube-system5.2 现象kubectl get nodes显示NotReadykubectl describe node提示KubeletNotReady日志中反复出现Failed to run kubelet: failed to load kubeconfig原因/etc/kubernetes/kubelet.conf中client-certificate-data和client-key-data为空或certificate-authority-data与 CA 证书不匹配。根本原因是kubeadm init时--upload-certs失败但脚本未捕获错误。解决# 手动重建 kubelet.conf在 master 节点执行 sudo kubeadm init phase kubeconfig kubelet --config manifests/kubeadm-config.yaml # 重启 kubelet sudo systemctl restart kubelet5.3 现象Calico Pod 一直ContainerCreatingkubectl describe pod显示FailedCreatePodSandBoxjournalctl -u kubelet报failed to create containerd container: error unpacking image:no such file or directory原因containerd 配置中root /var/lib/containerd路径不存在或权限不足。Kylin V10 ARM64 的/var/lib/containerd目录默认属主为root:root但 containerd service 以containerd用户运行若配置了Usercontainerd。解决# 修改 containerd 配置注释掉 User 行并确保 root 路径存在 sudo sed -i /User/d /etc/systemd/system/containerd.service sudo mkdir -p /var/lib/containerd sudo chown root:root /var/lib/containerd sudo systemctl daemon-reload sudo systemctl restart containerd5.4 现象kubectl get cs显示scheduler和controller-manager为Unknownkubectl logs -n kube-system kube-scheduler-master1报connection refused原因K8s 1.26 默认禁用--port参数scheduler 和 controller-manager 仅监听localhost:10259和localhost:10257而kubectl get cs尝试连接http://localhost:10251已废弃。这不是故障而是设计变更。解决# 不要再用 kubectl get cs已弃用改用 kubectl get componentstatuses # 仍可工作但输出为 Unknown # 真正验证检查 pod 状态 kubectl get pods -n kube-system | grep -E (scheduler|controller-manager) # 若 Running则服务正常cs 的 Unknown 是预期行为5.5 现象kubectl apply -f calico.yaml后calico-nodePod CrashLoopBackOff日志显示FATAL: Unable to detect the network backend原因Calico manifest 中CALICO_NETWORKING_BACKEND环境变量未设置或IP_AUTODETECTION_METHOD未指定。Kylin V10 ARM64 的网络接口名常为enp1s0f0而非eth0自动探测失败。解决# 修改 calico.yaml为 calico-node DaemonSet 添加 env # - name: IP_AUTODETECTION_METHOD # value: interfaceenp.* # 或更稳妥指定具体接口 # - name: IP_AUTODETECTION_METHOD # value: first-found # 并确保 CALICO_NETWORKING_BACKENDbirdBGP 模式6. 验证集群健壮性3 个必须执行的终局测试与 1 个国产化特供技巧部署完成不等于可用。真正的验收是让集群在 Kylin V10 ARM64 环境下扛住业务流量、证书轮换、节点故障三重压力。下面三个测试缺一不可。6.1 测试 1模拟 Master 节点宕机验证 etcd 集群自动恢复能力K8s 高可用的本质是 etcd 集群的可用性。必须验证当一台 masteretcd 成员宕机后剩余节点能否继续提供读写# 1. 获取当前 etcd 成员列表 sudo ETCDCTL_API3 etcdctl \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key \ member list | grep -E (name|status) # 2. 在待测试 master 节点上强制 kill etcd 进程模拟宕机 sudo pkill -f etcd.*data-dir # 3. 等待 30 秒在另一台 master 上执行 sudo ETCDCTL_API3 etcdctl \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key \ endpoint health # 输出应为https://127.0.0.1:2379 is healthy: successfully committed proposal # 4. 验证 K8s API 是否可用在任意 master 执行 kubectl get nodes --no-headers | wc -l # 应返回 2原 3 台1 台宕机 kubectl get pods -A --no-headers | wc -l # 应 0证明 control plane 仍在调度注意此测试必须在kubeadm init时启用--upload-certs否则 etcd 证书无法自动轮换节点恢复后无法加入集群。6.2 测试 2强制轮换所有 TLS 证书验证离线签发链可靠性K8s 1.26 默认证书有效期 1 年到期前 90 天需轮换。离线环境无法调用kubeadm certs renew的在线签发必须验证本地 cfssl 链是否完整# 1. 备份原证书 sudo cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup # 2. 使用离线 cfssl 重新签发 apiserver 证书覆盖原文件 ./certs/cfssl gencert \ -ca./certs/ca.pem \ -ca-key./certs/ca-key.pem \ -config./cert p a hrefhttps://download.csdn.net/download/m0_37814112/89403732 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p