ARTICLE DETAIL

资讯详情

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

麒麟V10 ARM服务器上用containerd部署K8s 1.26实战指南

麒麟V10 ARM服务器上用containerd部署K8s 1.26实战指南 简介本资源是面向国产化信创环境的Kubernetes实战部署合集专为在Kylin V10操作系统与ARM64架构服务器上构建云原生基础设施的技术人员设计解决ARM平台下K8S 1.26.15集群从零部署、containerd运行时适配及网络插件集成等关键问题适用于边缘计算、信创替代及高校科研实验场景。资源共38个文件涵盖14个ARM64专用tar.gz镜像包含kube-apiserver、etcd、Calico组件等、11个Kylin适配rpm依赖包如libseccomp、ipvsadm、4个自动化脚本load_images.sh/get_images.sh等、3个核心YAML配置kubeadm-config.yaml、calico.yaml等以及service、conf、二进制工具等总大小619.64MB。已有264人学习下载。用户可直接复用全部预编译二进制、定制化CNI配置与一键镜像加载脚本规避交叉编译与版本兼容风险并获得针对KylinARM组合的RBAC权限模板与持久化存储配置参考显著降低国产化K8S落地门槛。1. 为什么在麒麟V10 ARM服务器上用containerd跑K8s 1.26.15比Docker方案更稳、更省、更贴近生产真实态你手头有一台国产ARM服务器——可能是飞腾D2000、鲲鹏920或海光C86注意C86虽属x86指令集但麒麟V10对C86的适配常被误标为ARM实际部署需严格区分架构系统是银河麒麟高级服务器操作系统V10Halberd版内核4.19.90目标是快速拉起一个一主一从的Kubernetes集群用于跑国产化中间件如达梦数据库、东方通TongWeb或信创政务微服务。别再试Docker了——K8s 1.24已彻底移除dockershim而麒麟V10官方源里Docker CE的ARM包长期停留在20.10.x不支持cgroup v2与新内核冲突频发更关键的是Docker daemon自带的iptables规则和网络插件docker0桥接会与Calico/Flannel抢夺节点网络控制权导致Pod间通信玄学中断。containerd则完全不同它轻量二进制仅30MB、原生支持cgroup v2、与systemd深度集成、且麒麟V10 SP3起已将其作为默认容器运行时预装。本文实测在飞腾D2000麒麟V10 SP3环境下用containerd部署K8s 1.26.15当前LTS版本master节点内存占用比Docker方案低42%kubelet启动耗时缩短至1.8秒且能稳定通过CNCF官方conformance test v1.26。这不是理论推演而是我在某省政务云二期项目中踩坑27次后沉淀出的最小可行路径——所有命令、配置、镜像、校验值均来自真实离线环境打包不依赖外网仓库不调用任何非麒麟官方源专治ARM平台“装得上跑不动、跑得动连不上、连得上调度失败”三重翻车。2. 环境准备从裸机到可部署状态的四步硬核检查部署前必须确认底层是否真正就绪。ARM平台的坑往往藏在BIOS/固件层而非K8s YAML里。以下四步缺一不可跳过任意一步后续90%概率卡在kubeadm init的preflight阶段。2.1 确认CPU架构与内核兼容性别让“ARM”三个字骗了你提示麒麟V10存在多个子版本Advanced Server V10 (Halberd)是唯一明确支持ARM64的发行版Desktop版和某些SP2旧镜像仅提供ARM32支持无法运行K8s 1.26。执行以下命令逐项验证# 查看精确架构标识不是arm64就停 uname -m # 正确输出应为aarch64 # 检查内核是否启用cgroup v2K8s 1.26强制要求 cat /proc/cmdline | grep -E cgroup_enable.*|systemd.unified_cgroup_hierarchy # 必须同时出现cgroup_enablememory cgroup_enablecpuset systemd.unified_cgroup_hierarchy1 # 验证内核模块加载飞腾D2000需额外加载 lsmod | grep -E (overlay|br_netfilter|ip_vs|nf_conntrack) # 若缺失ip_vs_*模块需手动加载modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr # 检查SELinux状态麒麟V10默认enforcing必须设为permissive sudo setenforce 0 sudo sed -i s/SELINUXenforcing/SELINUXpermissive/g /etc/selinux/config参数说明uname -m输出aarch64是ARM64的铁证若为armv7l说明系统运行在32位模式K8s 1.26直接拒绝初始化cgroup_enablememory和systemd.unified_cgroup_hierarchy1是containerd运行的硬性前提缺一则kubelet报错failed to run Kubelet: unable to load client CA fileip_vs模块是Kube-Proxy IPVS模式必需麒麟V10 SP3默认未加载需在/etc/modules-load.d/k8s.conf中追加ip_vs、ip_vs_rr、ip_vs_wrr三行并重启。2.2 网络与防火墙麒麟V10的firewalld策略比CentOS更激进麒麟V10默认启用firewalld且预置规则会拦截K8s关键端口6443、10250、30000-32767。不能简单systemctl stop firewalld——这会导致systemd-networkd异常退出网卡失联。# 开放K8s必需端口按顺序执行顺序错则规则失效 sudo firewall-cmd --permanent --add-port6443/tcp sudo firewall-cmd --permanent --add-port10250/tcp sudo firewall-cmd --permanent --add-port10251/tcp sudo firewall-cmd --permanent --add-port10252/tcp sudo firewall-cmd --permanent --add-port2379-2380/tcp # etcd sudo firewall-cmd --permanent --add-port30000-32767/tcp # NodePort范围 sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 source address10.244.0.0/16 accept sudo firewall-cmd --reload # 关键禁用firewalld的自动网桥拦截否则Calico无法创建veth pair sudo firewall-cmd --permanent --remove-servicedocker sudo firewall-cmd --permanent --remove-servicekubelet sudo firewall-cmd --permanent --set-targetACCEPT逻辑说明第7行source address10.244.0.0/16是Calico默认Pod网段必须显式放行否则Node间Pod通信全断--set-targetACCEPT是麒麟V10特有操作它将firewalld默认策略从REJECT改为ACCEPT避免因规则匹配失败导致流量静默丢弃——这是ARM平台最隐蔽的网络黑匣子。2.3 containerd配置绕过麒麟V10默认配置的三个致命陷阱麒麟V10 SP3预装containerd 1.6.8但其/etc/containerd/config.toml存在三处与K8s 1.26不兼容的默认值# 备份原配置 sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak # 生成符合K8s 1.26要求的最小配置 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 /\[plugins.io.containerd.grpc.v1.cri.registry.mirrors\]/a\ \ [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io]\n \ \ endpoint [https://registry.aliyuncs.com] /etc/containerd/config.toml sudo sed -i /sandbox_image /c\sandbox_image registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 /etc/containerd/config.toml参数说明SystemdCgroup true强制containerd使用systemd cgroup驱动与麒麟V10的cgroup v2内核配置对齐设为false会导致kubelet反复报错failed to generate container xxx spec: failed to generate spec: failed to get cgroup pathregistry.aliyuncs.com镜像加速器麒麟V10 ARM源无Docker Hub代理必须指定国内ARM镜像源否则kubeadm init卡在pulling control plane imagespause:3.9K8s 1.26.15官方指定的pause镜像版本麒麟V10默认配置仍指向3.6会导致kubelet启动失败并打印Failed to create pod sandbox: rpc error: code Unknown desc failed to get sandbox image。2.4 离线镜像包准备麒麟V10 ARM环境没有“在线拉取”这回事所有K8s组件镜像必须提前下载并导入。我们采用kubeadm config images list --kubernetes-version 1.26.15生成清单再用ARM专用镜像源# 创建离线镜像目录 mkdir -p ~/k8s-images cd ~/k8s-images # 下载K8s 1.26.15全量ARM镜像使用阿里云ARM镜像仓库 curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/kube-apiserver-v1.26.15.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/kube-controller-manager-v1.26.15.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/kube-scheduler-v1.26.15.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/kube-proxy-v1.26.15.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/pause-3.9.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/etcd-3.5.10-0.tar curl -O https://mirrors.aliyun.com/kubernetes/images/arm64/coredns-v1.9.3.tar # 批量导入containerd for img in *.tar; do sudo ctr -n k8s.io images import $img done # 验证镜像完整性SHA256必须与kubeadm官方清单一致 ctr -n k8s.io images list | grep -E (kube-apiserver|pause) | head -5 # 正确输出应含registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.26.15sha256:...逻辑说明阿里云ARM镜像仓库地址https://mirrors.aliyun.com/kubernetes/images/arm64/是目前唯一稳定提供K8s全版本ARM镜像的公开源ctr -n k8s.io中的k8s.io命名空间是K8s 1.26硬编码的containerd命名空间写错成default会导致kubelet找不到镜像pause-3.9.tar必须与config.toml中sandbox_image值完全一致包括registry域名和tag否则Pod启动时触发ImagePullBackOff。3. K8s集群初始化用kubeadm定制化生成ARM友好的manifestkubeadm默认生成的manifest针对x86优化直接kubeadm init会在ARM平台触发exec format error。必须通过--config指定ARM适配配置并禁用所有x86专属特性。3.1 编写kubeadm-config.yaml精准控制每个control plane组件的CPU架构行为# 保存为 /root/kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: 1.26.15 controlPlaneEndpoint: 192.168.10.100:6443 # 替换为你的VIP或Master IP networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 dnsDomain: cluster.local imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers certificatesDir: /etc/kubernetes/pki clusterName: kylin-arm-cluster --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd failSwapOn: false nodeStatusUpdateFrequency: 10s rotateCertificates: true serverTLSBootstrap: true # 关键强制指定ARM平台runtime containerRuntimeEndpoint: unix:///run/containerd/containerd.sock # 关键禁用x86专属特性 featureGates: DevicePlugins: false CPUManager: false MemoryManager: false TopologyManager: false参数说明imageRepository必须与containerd config中的镜像源域名一致否则kubeadm仍会尝试从k8s.gcr.io拉取该域名在国产网络不可达featureGates中关闭CPUManager等特性麒麟V10 ARM内核对这些特性支持不完整开启会导致kubelet崩溃并打印SIGSEGVcontainerRuntimeEndpoint显式指向containerd socket避免kubeadm误判为Docker。3.2 执行kubeadm init带超时保护的原子化初始化# 设置环境变量规避kubeadm对ARM的架构检测bug export KUBECONFIG/etc/kubernetes/admin.conf export ARCHarm64 # 执行初始化添加超时和重试机制 timeout 600 kubeadm init \ --config /root/kubeadm-config.yaml \ --upload-certs \ --ignore-preflight-errorsNumCPU,Mem,Swap \ --v5 21 | tee /root/kubeadm-init.log # 检查初始化结果 if [ $? -eq 0 ]; then echo ✅ kubeadm init success mkdir -p $HOME/.kube sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config else echo ❌ kubeadm init failed, check /root/kubeadm-init.log exit 1 fi逻辑说明timeout 600防止因镜像拉取慢导致进程假死--ignore-preflight-errors忽略CPU核心数、内存、Swap检查——ARM服务器常因BIOS设置导致numactl识别异常触发NumCPU错误--v5开启详细日志关键线索藏在[preflight] Running pre-flight checks之后的[certs] Generating certificates阶段若卡在此处90%是containerd镜像未正确导入。3.3 部署CNI网络插件Calico ARM版的三处补丁Calico官方ARM镜像存在DNS解析缺陷需手动打补丁# 下载Calico v3.26.1 ARM manifest适配K8s 1.26 curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml # 修改镜像为ARM可用版本 sed -i s/image: docker.io\/calico\/cni:.*/image: registry.cn-hangzhou.aliyuncs.com\/calico\/cni:v3.26.1/g calico.yaml sed -i s/image: docker.io\/calico\/node:.*/image: registry.cn-hangzhou.aliyuncs.com\/calico\/node:v3.26.1/g calico.yaml sed -i s/image: docker.io\/calico\/kube-controllers:.*/image: registry.cn-hangzhou.aliyuncs.com\/calico\/kube-controllers:v3.26.1/g calico.yaml # 关键补丁修复ARM平台DNS解析失败问题 sed -i /name: CALICO_IPV4POOL_CIDR/a\ - name: FELIX_IGNORELOSTIFACE\n value: true calico.yaml # 应用配置 kubectl apply -f calico.yaml # 验证Calico Pod状态等待Running watch -n 2 kubectl get pods -n kube-system | grep calico参数说明FELIX_IGNORELOSTIFACEtrue强制Calico忽略ARM平台网卡热插拔导致的interface丢失事件否则calico-node频繁重启镜像域名必须与containerd配置一致否则ImagePullBackOffkubectl get pods中calico-node状态变为Running且READY列显示1/1才表示网络插件就绪。4. 节点加入与验证一主一从的ARM级联部署避坑指南ARM平台节点加入时kubeadm join命令生成的token有效期仅24小时且ARM节点常因时钟不同步导致TLS握手失败。必须做三重加固。4.1 生成永久Join Token绕过24小时时效限制# 在Master节点执行生成7天有效期token kubeadm token create --ttl 1728000s --print-join-command /root/join-command.sh # 提取token和discovery-hash用于离线节点 TOKEN$(cat /root/join-command.sh | grep -o kubeadm join.*--token [^ ]* | awk {print $4}) HASH$(cat /root/join-command.sh | grep -o --discovery-token-ca-cert-hash [^ ]* | awk {print $2}) echo TOKEN$TOKEN /root/join-env.sh echo HASH$HASH /root/join-env.sh4.2 Worker节点预检ARM特有的硬件兼容性检查在Worker节点执行# 检查CPU特性飞腾D2000需确认AES指令集可用 cat /proc/cpuinfo | grep -i aes # 必须输出flags : ... aes ... # 检查内存一致性ARM平台NUMA拓扑易出错 numactl --hardware | grep -E (available|node) # 若显示no NUMA available则需在BIOS中关闭NUMA # 同步系统时间ARM平台RTC精度差必须NTP校准 sudo timedatectl set-ntp true sudo systemctl restart systemd-timesyncd timedatectl status | grep System clock synchronized # 必须输出System clock synchronized: yes4.3 执行Join并验证用kubectl proxy暴露API验证ARM节点状态# 在Worker节点执行替换IP和token sudo kubeadm join 192.168.10.100:6443 \ --token $TOKEN \ --discovery-token-ca-cert-hash $HASH \ --v5 21 | tee /root/kubeadm-join.log # Master节点验证节点状态 kubectl get nodes -o wide # 正确输出应含STATUSReady, ROLESworker, AGE1m, VERSIONv1.26.15, INTERNAL-IP192.168.10.101, OS-IMAGEKylin Linux Advanced Server V10 (Halberd) # 关键验证跨节点Pod调度 kubectl run nginx-arm --imageregistry.cn-hangzhou.aliyuncs.com/library/nginx:alpine-arm64 --restartNever kubectl get pod -o wide # 观察nginx-arm的NODE列是否显示Worker节点IP且STATUSCompleted逻辑说明--v5日志中重点查看[discovery] Created cluster-info discovery client和[kubelet-start] Writing kubeconfig to file两行确认证书分发成功kubectl get nodes -o wide中OS-IMAGE字段必须显示Kylin Linux Advanced Server V10 (Halberd)证明节点OS信息被正确上报nginx-arm测试镜像必须使用alpine-arm64标签x86镜像在ARM节点会触发exec format error。5. 常见问题排查麒麟V10 ARM平台K8s部署的5个血泪坑注意以下问题均来自真实生产环境每条都附带现象 → 原因 → 解决闭环方案非理论推测。5.1 现象kubeadm init卡在[certs] Generating certificates日志循环打印failed to load key pair原因麒麟V10 SP3默认启用/etc/crypto-policies/default策略该策略禁用RSA-1024密钥而kubeadm 1.26.15默认生成RSA-1024证书。解决# 临时切换为LEGACY策略 sudo update-crypto-policies --set LEGACY # 重新执行kubeadm init kubeadm reset -f kubeadm init --config /root/kubeadm-config.yaml5.2 现象kubectl get nodes显示节点NotReadykubectl describe node提示NetworkPluginNotReady: cni config uninitialized原因Calico manifest中CALICO_IPV4POOL_CIDR值与kubeadm config中podSubnet不一致导致CNI配置文件/etc/cni/net.d/10-calico.conflist生成失败。解决# 检查两者是否一致 grep podSubnet /root/kubeadm-config.yaml grep CALICO_IPV4POOL_CIDR calico.yaml # 若不一致修改calico.yaml中该字段值重新kubectl apply -f calico.yaml5.3 现象Worker节点kubeadm join后kubectl get nodes显示No resources found但systemctl status kubelet显示active原因麒麟V10防火墙规则未同步到Worker节点10250端口被阻断kubelet无法向API Server上报状态。解决# 在Worker节点执行复用Master节点firewalld规则 sudo firewall-cmd --permanent --add-port10250/tcp sudo firewall-cmd --reload # 重启kubelet sudo systemctl restart kubelet5.4 现象Pod始终处于ContainerCreating状态kubectl describe pod显示FailedCreatePodSandBox: rpc error: code Unknown desc failed to get sandbox image原因containerd中pause镜像的digest与kubeadm配置中sandbox_image值不匹配常见于镜像导入时网络中断导致部分layer损坏。解决# 列出所有pause镜像 sudo ctr -n k8s.io images list | grep pause # 删除旧镜像 sudo ctr -n k8s.io images rm registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9sha256:... # 重新导入pause-3.9.tar sudo ctr -n k8s.io images import pause-3.9.tar5.5 现象Calico Pod反复重启kubectl logs -n kube-system calico-node-xxx打印Failed to initialize BPF maps: unable to open BPF object原因麒麟V10内核未启用BPF_JIT而Calico v3.26默认启用eBPF数据面。解决# 临时启用BPF_JIT echo vm.bpf_jit_enable 1 | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 或降级Calico推荐 sed -i s/image:.*calico\/node:.*/image: registry.cn-hangzhou.aliyuncs.com\/calico\/node:v3.25.2/g calico.yaml kubectl delete -f calico.yaml kubectl apply -f calico.yaml6. 进阶技巧用kubectl debug ARM原生工具链诊断Pod黑盒问题当Pod在ARM节点上异常退出kubectl logs返回空kubectl exec报错command not found说明容器内缺少ARM原生调试工具。此时需用kubectl debug注入ARM调试镜像而非依赖x86工具链。6.1 构建ARM调试镜像基于Alpine ARM64的最小诊断环境# 文件debug-arm64.Dockerfile FROM alpine:3.18 RUN apk add --no-cache \ strace \ tcpdump \ lsof \ iproute2 \ procps \ bash \ curl \ jq CMD [sleep, 3600]构建并推送至私有仓库# 在ARM机器上构建不能在x86上交叉编译 docker build -f debug-arm64.Dockerfile -t registry.internal/debug-arm64:1.0 . docker push registry.internal/debug-arm64:1.06.2 注入调试容器用ephemeral container捕获实时状态# 对故障Pod注入调试容器 kubectl debug -it nginx-arm \ --imageregistry.internal/debug-arm64:1.0 \ --targetnginx-arm \ --share-processes # 进入后执行ARM原生诊断 # 查看进程树 ps auxf # 抓取网络包目标Pod的eth0接口 tcpdump -i eth0 -w /tmp/pod.pcap port 80 # 追踪系统调用 strace -p 1 -f -o /tmp/strace.log关键技巧--share-processes参数使调试容器与目标Pod共享PID namespace可看到真实进程tcpdump抓包文件/tmp/pod.pcap可直接用Wireshark在x86机器上分析无需在ARM端安装GUIstrace.log中若出现connect(3, {sa_familyAF_INET, sin_porthtons(53), sin_addrinet_addr(10.96.0.10)}, 16) -1 ENETUNREACH说明CoreDNS服务未就绪需检查corednsPod状态。6.3 验证ARM平台K8s稳定性用kubetest2跑CNCF conformance test# 下载ARM版kubetest2 curl -L https://github.com/kubernetes/test-infra/releases/download/v20231201.43222/kubetest2-linux-arm64.tar.gz | tar xz # 运行conformance test需提前配置KUBECONFIG ./kubetest2 kubernetes \ --testconformance \ --providerskeleton \ --kubeconfig/root/.kube/config \ --report-dir/root/conformance-report \ --timeout120m # 检查报告 cat /root/conformance-report/junit_01.xml | grep -E (failure|error) | head -5 # 无输出即表示通过CNCF认证参数说明kubetest2-linux-arm64是官方发布的ARM64二进制x86版本在ARM节点运行会报Exec format error--timeout120m延长超时ARM平台测试用例执行较慢通过conformance test是信创项目验收硬指标此步骤不可跳过。我在这套流程上摔过太多跟头第一次在飞腾D2000上跑K8s因为没关SELinuxkubelet日志里全是permission denied却查不到源头第二次用错pause镜像版本Pod卡在Init:0/1三天没定位到第三次Calico DNS解析失败以为是网络问题折腾一周才发现是FELIX_IGNORELOSTIFACE开关没开。现在每次新部署我都把kubeadm-config.yaml和firewalld规则存为模板用sha256sum校验镜像包用kubectl debug代替exec——这些不是最佳实践而是用27次翻车换来的后悔药。希望帮到你。本文还有配套的精品资源点击获取
返回列表