首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
ARM64+openEuler+iSula构建Kubernetes集群的实践指南
📅 2026/10/22 13:52:05
✍️ 爱科研究院
👁 阅读 3,247
1. 拆解这套部署的核心选型ARM64、openEuler、iSula 怎么搭1.1 ARM64 平台不是“二等公民”但兼容性必须提前验证ARM64aarch64服务器这几年在 Web 服务、边缘节点、AI 推理这些场景里出现得越来越频繁核心卖点就是单核成本低、功耗控制好。很多人一听 ARM 就担心 Kubernetes 跑不跑得起来其实这个担心过时了。Kubernetes 官方早就把 aarch64 作为一等支持和发布架构kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、etcd 这些核心组件都有对应的 linux/arm64 镜像。kubeadm、kubelet、kubectl 这些二进制也有 ARM64 版本直接从官方源下载或者走发行版仓库就能装。真正会出问题的不是 Kubernetes 本身而是周边生态。比如你习惯用的某些中间件镜像、日志采集工具、Ingress 控制器仓库里可能只有 amd64 的 manifest没有 ARM64 版本硬拉镜像会直接报 manifest unknown。所以选型前置是第一原则在动手部署之前把计划跑在 Pod 里的镜像一个个过一遍确认是否有 linux/arm64 的 tag。这一步做得越早后面集群跑起来之后踩的坑越少。这里可以分享一个偏方如果镜像仓库支持 manifest 列表可以直接用 skopeo 之类的工具去检查不需要专门找一台 ARM 服务器。我的习惯是列一个表格把控制面组件、CNI 插件、业务镜像分别标上行不行凡是标不行的就提前找替代品。比如 flannel 和 calico 这两个主流 CNI 都提供了 ARM64 版本所以下网络结论不慌。1.2 openEuler 和 iSula一个求稳一个求轻openEuler 在服务器端发行版里的定位一句话就是“可控、可预期、长维护”。它有 LTS 版本软件仓库里从内核模块、编译器工具链到虚拟化组件都齐全对 aarch64 的支持很完整不会出现某些发行版那样 arm64 仓库缺包的情况。对交付项目来说这一点尤其重要系统装完包管理器里的东西能直接覆盖大半需求不需要到处找第三方源。iSula 是配套的轻量容器引擎和 Docker 不是一个路数。Docker 的体系是 daemon 加客户端再配一堆插件功能全但厚重。iSula 走的是轻量路线核心是一个常驻进程加一个命令行资源占用更低和 openEuler 的适配程度也更深直接通过 dnf 就能安装升级。最关键的是iSula 原生实现了 CRIContainer Runtime Interface意思是 kubelet 不需要任何中间转换层直接通过 Unix socket 和它通信。Kubernetes 1.24 版本之后已经移除了 dockershim这套 CRI 直连的方案反而是最契合官方方向的。把三样东西放在一起看这个组合的合理性就很清楚了ARM64 解决硬件平台的选型问题openEuler 解决操作系统层面的长期维护问题iSula 解决容器运行时的高效接入问题。三者的交集正好是一个能在 ARM 服务器上稳定跑 Kubernetes 的最小闭环。1.3 什么场景适合这套方案什么场景需要谨慎这套方案最适合的场合是硬件已经定死为 ARM64、系统已经定死为 openEuler 的集群类项目。典型如边缘计算平台、ARM 服务器节点的容器化改造、或者要求底层系统统一可控的 PaaS 底座。在这些场景里iSula 做 CRI 是个很自然的选择Kubernetes 集群可以像常规环境一样用 kubeadm 初始化后续维护和 x86 平台的差异很小。但要提醒的是如果你准备在这个环境下跑大量非标准的容器工作负载比如频繁依赖 docker compose、需要一堆 docker 插件、或者要对接某些只适配 Docker API 的第三方工具iSula 会比较别扭。它提供的命令行工具是 isula功能锁定在容器生命周期管理不会去复制 Docker 的全套生态。可以把它理解成专为 Kubernetes 定制的运行时而不是 Docker 的平替。做选型时先想清楚使用方式再决定上不上这套组合。2. 部署前的基础环境初始化系统参数、防火墙、软件源2.1 节点规划与网络清单我先说节点规划。以三节点集群为例一台 master两台 worker这个规模最适合跑通全流程。实际环境里节点可以按需扩到更多但思路完全一致。假设网段是 192.168.56.0/24三台机器固定 IP 如下节点角色主机名IP 地址硬件建议control-planemaster01192.168.56.104C8G磁盘 50Gworkernode01192.168.56.112C4G磁盘 50Gworkernode02192.168.56.122C4G磁盘 50G主机名在安装系统时就可以设好也可以在部署前临时改但我强烈建议一开始就定死主机名并且写入 /etc/hosts。后面 kubeadm 初始化、kubeconfig 生成、证书签发都会依赖主机名中途改名非常痛苦。所有节点都需要配置 /etc/hosts内容如下cat /etc/hosts EOF 192.168.56.10 master01 192.168.56.11 node01 192.168.56.12 node02 EOFPod 网段和服务网段也要提前规划不要用网段里的真实 IPKubernetes 内部会用它们做虚拟网络。我这里 Pod 网段用 10.244.0.0/16Service 网段用 10.96.0.0/12后面写 kubeadm 配置时会严格对应尤其注意不要重复。2.2 基础系统参数防火墙、swap、内核模块、sysctl在所有节点上执行下面的操作。openEuler 默认会启用 firewalldKubernetes 涉及大量端口和服务间通信为了省事直接把 firewalld 停掉或者至少放行所有节点间的必要端口。我个人在部署阶段的做法是直接停掉防火墙等集群完全验证通过后再考虑按端口收紧。命令行如下systemctl stop firewalld systemctl disable firewalldswap 需要关闭这是 kubelet 的硬性要求。kubelet 默认会检查 swap不开 --fail-swap-onfalse 的话直接起不来。永久关闭方式是把 /etc/fstab 里的 swap 行注释掉然后执行 swapoff -a。注意修改 fstab 要特别小心不要误改了其他分区条目。swapoff -a sed -ri s/.*swap.*/#/ /etc/fstab还需要加载 br_netfilter 内核模块并调整网络参数让 bridge 上的流量能正确经过 iptables/nftables这是 Kubernetes 网络模型的基础。modprobe br_netfilter cat /etc/modules-load.d/k8s.conf EOF br_netfilter EOF 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时间同步同样不要忽略。Kubernetes 集群成员之间的时间偏差过大会导致证书验证和日志排查都出现诡异问题。openEuler 一般默认带 chrony确认服务在跑就可以不确定的话用如下命令检查没装就装上systemctl status chronyd # 再顺手核对一下时间 date如果发现时间不对先打开 chrony 的配置确认 NTP 源能连上再手动同步一次。这个细节我见过很多人漏掉后面证书验证失败的时候才追悔莫及。2.3 软件源和基础依赖openEuler、Kubernetes 源、conntrackopenEuler 自带的软件源如果已经正常系统软件包可以直接用。但 Kubernetes 的 kubeadm、kubelet、kubectl 不在系统源里需要额外配置 Kubernetes 的 yum 源。这里注意一点很多教程直接复制 x86_64 的源地址在 ARM64 机器上会报错或者找不到包。要确认 repo 路径里带的架构是 aarch64。我习惯把 Kubernetes 源单独放到一个 repo 文件里避免污染系统源。以当前环境为例源地址指向 kubernetes-el7-aarch64 或 el8-aarch64 取决于 openEuler 版本一般 openEuler 22.03 LTS 兼容 el8 的包依赖但如果源里没有对应目录可以选 el7-aarch64。实际配置时如果提示依赖问题换另一套再看。写入 /etc/yum.repos.d/kubernetes.repocat /etc/yum.repos.d/kubernetes.repo EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el8-aarch64/ enabled1 gpgcheck0 repo_gpgcheck0 EOFgpgcheck 我一般关掉否则还要额外导入 GPG 密钥在离线或内网环境下容易增加无谓的障碍。如果你的环境安全等级要求高可以打开 gpgcheck 并配置相应的 key 文件。还要装两个关键依赖conntrack-tools 和 socat。kubeadm 初始化时会检查 conntrack 这个可执行文件少了直接报“executable file conntrack not found in $PATH”。openEuler 上包名是 conntrack-tools不要装错。socat 主要用于 kube-proxy 端口转发没有它某些场景下会异常。dnf install -y conntrack-tools socat iproute-tc这里顺带提一句如果后续 kubeadm 拉镜像走系统仓库不方便可以在安装 kubeadm 时提前把 kubelet 的 pause 镜像源想清楚下一节配置 iSulad 时会用到。网络比较顺畅的环境直接跳过不顺畅的话这里就要提前准备内网镜像仓库或者离线 tar 包。3. iSulad 容器引擎安装关键配置详解与验证3.1 dnf 安装和启动iSulad 在 openEuler 的软件仓库里直接就有不需要额外配第三方源。安装命令非常简洁dnf install -y iSulad systemctl enable --now isulad systemctl status isulad服务名是 isulad注意不是 isula命令行的客户端才是 isula。安装完成后在 /run 下会生成 isulad.sock这是 CRI 通信用的 socket 文件路径一般是 unix:///run/isulad.sock 或 unix:///var/run/isulad.sock两个通常是软链关系。后面 kubelet 和 kubeadm 配置 CRI 时填的就是这个路径填错一个字符 kubelet 就会报连不上运行时。我第一次部署时就是在这个 socket 路径上绕了半天建议现在就确认清楚ls -l /var/run/isulad.sock /run/isulad.sock3.2 /etc/isulad/config.json 里的几个关键项iSulad 的配置文件在 /etc/isulad/config.json。默认配置对普通容器够用但跑 Kubernetes 必须调几个关键字段。先把配置理解透再改。第一个是 pod-sandbox-image也就是 sandbox 镜像Kubernetes 每个 Pod 会先启动一个 pause 容器作为网络和命名空间的底座这个镜像就是它。不同 Kubernetes 版本对应的 pause 镜像版本不一样比如 Kubernetes 1.28 系列对应 pause 3.9。不要在配置文件里写老版本否则 kubelet 创建 sandbox 时镜像拉取和实际组件版本对不上问题很隐蔽。第二个是 network-plugin必须设置成 cni。iSulad 默认网络插件是 null只适合跑单机容器。改成 cni 后 iSulad 会在创建沙箱时调用 CNI 插件完成网络配置这样 Pod 才能获得集群内的虚拟 IP。同时还要指定 cni-bin-dir 和 cni-conf-dir分别指向 CNI 插件的二进制目录和配置文件目录习惯上和 containerd 保持一致用 /opt/cni/bin 和 /etc/cni/net.d。第三个是 cgroup-driver。kubelet 和容器运行时之间的 cgroup 驱动必须一致否则节点状态会反复 NotReady。openEuler 默认大概率不是 cgroup v2 全量模式iSulad 默认用 cgroupfs所以我后面配置 kubelet 时也统一用 cgroupfs。如果系统启用了 cgroup v2那两边都要改成 systemd这一点根据实际环境来。配置文件给一个参考形态不同 iSulad 版本字段命名可能略有差异以大版本的实际生成的配置为准{ group: isulad, log-level: INFO, pidfile: /var/run/isulad.pid, pod-sandbox-image: registry.k8s.io/pause:3.9, network-plugin: cni, cni-bin-dir: /opt/cni/bin, cni-conf-dir: /etc/cni/net.d, cgroup-driver: cgroupfs }改完配置后记住重启 isuladsystemctl restart isulad如果 pod-sandbox-image 指定的镜像源在你的环境里拉不通比如 registry.k8s.io 访问不稳定可以换成你本地能访问的镜像仓库只要镜像名字和 tag 保持对应关系就行。修改后同样要重启 isulad并且建议手动验证一下能拉取。3.3 验证 iSulad 正常工作配置完成之后先做一些基础验证确认引擎本身是好的避免后面 K8s 组件出了问题还要回来排查容器层。首先看引擎信息isula info正常会输出 iSulad 的版本、容器运行时类型、存储驱动、日志驱动、cgroup 驱动这些信息。重点检查 cgroup driver 和你预期的一致network-plugin 显示为 cni。再跑一个小容器做冒烟测试比如isula pull busybox:1.36 isula run --rm busybox:1.36 echo hello isula如果输出 hello isula说明镜像拉取、容器创建、进程执行都正常。最后再确认 socket 文件存在iSulad 日志里没有报错journalctl -u isulad --no-pager | tail -20做到这里容器运行时这一层就算完全就绪了。注意 isula run 命令本身并不负责创建 Pod 网络它只是一个简单的容器运行命令和 Kubernetes 里的运行时调用是两条路径。所以冒烟测试只要验证基本功能不用追求 Pod 级别的网络效果。4. Kubernetes 集群部署kubeadm 配置 iSula CRI 全流程4.1 安装 kubeadm、kubelet、kubectl在 master 和 worker 节点上都执行这组安装因为 worker 节点同样需要 kubelet 来管理 Pod 生命周期。确认上一节的 kubernetes.repo 配置好后直接安装dnf install -y kubeadm kubelet kubectl如果在 x86 上习惯用 apt 装 kubeadm套路不太一样这里不加赘述。安装完成后先不要着急启动 kubelet因为此时 kubelet 不知道该连哪个运行时直接 start 会在日志里刷“failed to connect to runtime service”。正确的顺序是先把所有配置写好再让 kubeadm 初始化时去拉起 kubelet。检查一下版本确保三个组件版本一致kubeadm version kubelet --version kubectl version --client版本不一致虽然未必立刻出错但升级和排查时很容易混乱。建议统一使用相同版本比如这里就用 1.28.2 作为目标版本实际部署时以仓库里最新稳定版为准。4.2 编写 kubeadm 配置文件核心是 criSocket 和容器运行时端点kubeadm 支持直接在命令行传参也支持写 yaml 配置文件。节点多了以后配置文件方式明显更可靠尤其能用 Git 管理后续重复部署也方便。这里给出一个三节点集群的 master 初始化配置保存为 kubeadm-config.yamlapiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.56.10 bindPort: 6443 nodeRegistration: name: master01 criSocket: unix:///run/isulad.sock --- apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: 1.28.2 controlPlaneEndpoint: 192.168.56.10:6443 networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: cgroupfs containerRuntimeEndpoint: unix:///run/isulad.sock这里有一个点必须说透为什么既要指定 nodeRegistration.criSocket又要指定 KubeletConfiguration 里的 containerRuntimeEndpoint前者是 kubeadm 初始化时用来探测运行时、生成节点信息的后者是写入 kubelet 启动参数、告诉 kubelet 每次创建沙箱时连哪个运行时。两者如果不一致或者只写前一个忘记写后一个kubelet 启动后会发现配置的运行时端点还是默认的 docker-socket 或者 empty于是反复重启失败。另外注意 cgroupDriver 这里显式写成 cgroupfs和上一节 iSulad 的配置保持一致。如果你的网络环境需要不同镜像仓库可以在 ClusterConfiguration 里增加 imageRepository 字段但这一步在标准环境里可以省略。4.3 master 节点初始化配置写好后在 master 节点上执行初始化。这一步会拉取一堆控制面镜像耗时取决于网络状况kubeadm init --config kubeadm-config.yaml如果一切顺利最后会输出一段类似这样的内容kubeadm 初始化完成、控制面进入 Running 状态、生成了 /etc/kubernetes/admin.conf并且附带一个 kubeadm join 的命令模板。这个 join 命令记得保存下来worker 节点加入集群要用。默认 token 有效期 24 小时如果过期了可以用 kubeadm token create 再生成但命令模板里的 CA 证书 hash 不会变可以反复用。初始化过程中常见的问题是控制面镜像拉取超时。此时用 isula images 看一下已拉到的镜像isula images如果 kube-apiserver、etcd 这些镜像都不在列表里说明镜像仓库不可达需要调整 imageRepository 或者提前在各节点本地导入镜像。这种问题在网络受限环境里几乎必现后面踩坑部分会专门讲。初始化完成后配置 kubectl 的访问权限mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config执行 kubectl get nodes 如果能看到 master01 处于 NotReady这是正常的因为还没装 CNI 网络插件。控制面处于 Ready 状态前节点网络肯定是断的。4.4 安装 flannel 网络插件注意 ARM64 镜像解决节点 NotReady 的标准动作是部署 CNI 插件。我用 flannel 举例因为它最简单、对 ARM64 的支持也最直接。从官方仓库拿到 yaml 清单kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml如果是离网环境可以先把 yaml 下载到本地再 apply。注意 flannel 的镜像地址新版 flannel 镜像已经支持多架构 manifest直接拉取即可理论上会自动匹配 aarch64。但是我在实际部署时遇到过一个场景节点通过本地私有仓库获取镜像而私有仓库只同步了 amd64 的 tag结果 flannel Pod 一直 ImagePullBackOff。这种情况要回到镜像同步环节把 arm64 的 manifest 一起同步进去。还有一种比较土但可靠的处理方式先在一台网络正常的 ARM 机器上用 isula pull 拉好 flannel 镜像再用 isula save 打成 tar 包分发到所有节点用 isula load 导入。因为 DaemonSet 的 imagePullPolicy 默认是 IfNotPresent本地有镜像就不会再去远端拉取这在离线场景或者镜像仓库同步不完整时非常管用。isula pull docker.io/flannel/flannel:v0.22.0 isula save -o flannel.tar docker.io/flannel/flannel:v0.22.0 # 在其他节点执行 isula load -i flannel.tar网络插件部署后还需要确认 CNI 配置文件存在。flannel 的 DaemonSet 会自动写入 /etc/cni/net.d/10-flannel.conflist目录由 iSulad 配置里的 cni-conf-dir 指定。如果目录下没有这个文件往往是 cni-bin-dir 或 cni-conf-dir 配置不一致导致的需要回过去检查 iSulad 配置。4.5 worker 节点加入集群worker 节点的前置准备和 master 基本一致openEuler 系统参数、iSulad 安装与配置、kubeadm/kubelet/kubectl 安装这些步骤在第二和第三节已经覆盖。如果 worker 节点的 iSulad 还没配置 CNI 或者 pod-sandbox-image 不对join 时也会出问题因此每个节点都要完整执行一遍前面的初始化。然后执行 kubeadm init 输出的 join 命令大致格式是kubeadm join 192.168.56.10:6443 --token token --discovery-token-ca-cert-hash sha256:hash --cri-socket unix:///run/isulad.sock注意最后手动指定了 cri-socket很多教程里忘了带这个参数会导致 kubeadm 去检查默认的 docker socket然后报错找不到 CRI。在 kubeadm v1.28 中不指定可能也能通过自动探测找到 isulad但既然我们已经明确用 iSula手动写清楚最稳妥。在 master 上确认 worker 节点加入kubectl get nodes看到 node01、node02 出现在列表里状态逐渐变成 Ready集群就搭起来了。如果节点一直 NotReady用 kubectl describe node node01 看 kubelet 的心跳和条件排查方向主要围绕 CNI 和 kubelet 日志下一节的故障记录会详细展开。5. 集群验证与网络插件部署要点5.1 从节点状态到真实工作负载集群搭建后不要急着上业务先把基础功能验证一遍。第一步是节点状态和组件状态kubectl get nodes -o wide kubectl get pods -n kube-system -o wide正常情况下 kube-system 里的 coredns、kube-flannel-ds 这些 Pod 都应该是 Running。如果某个 Pod 长时间 Pending大多是节点压力或污点匹配问题如果 Running 但 Ready 0/1那通常是网络或运行时问题。第二步是部署一个测试 Deployment 验证调度和网络链路。我习惯先跑一个简单的 nginxkubectl create deployment test --imagenginx:1.25 kubectl expose deployment test --port80 --target-port80 kubectl get pod -o wide确认 Pod 拿到了 10.244.x.x 网段的 IP再通过集群内部的 Service IP 访问一下kubectl run curl-test --imagebusybox:1.36 --rm -it -- wget -qO- http://service-ip能返回 nginx 的默认页面说明 Pod 间的扁平网络通了。这一步的意义不仅是验证 CNI同时也在验证 iSula 的 CNI 调用链路是否正常因为容器创建时网络都是由 isulad 调用 CNI 插件完成的。5.2 单节点集群的快速调整如果资源有限只有一个节点想让它既能当 master 又能调度普通 Pod需要去掉 master 上的控制面污点。执行kubectl taint nodes --all node-role.kubernetes.io/control-plane-这样普通 Pod 也可以调度到 master 节点上。日常开发和测试环境完全够用生产环境不建议这样干毕竟控制面组件和业务 Pod 混跑会影响稳定性。多节点环境里如果想验证 Pod 调度到指定节点可以给节点打 label然后用 nodeSelector 配合调度这些属于常规操作不展开。5.3 验证 iSula 作为 CRI 的真实运行状态走到这一步很多人有一个困惑Kubernetes 集群跑起来了但怎么确认容器真的是 iSula 在管而不是背后偷偷用了别的运行时方法很简单在任意节点上执行isula ps会看到一批容器每个容器的名称前缀都是 POD 和 container对应的是 pause 沙箱容器和业务容器。再结合isula inspect container-id可以看到这些容器的 labels 里有 io.kubernetes.pod.name、io.kubernetes.pod.namespace 等字段这些就是 kubelet 通过 CRI 调用 iSulad 创建容器时注入的元数据。同时查看 kubelet 启动参数也能看到 --container-runtime-endpointunix:///run/isulad.sock 这样的痕迹。日常维护时kubectl logs 和 isula logs 都能查看容器日志前者走 Kubernetes API后者直接看运行时日志。两者的时间戳和输出基本一致遇到日志采集工具问题时可以用 isula logs 做底层排查。5.4 日常维护命令速查整理几个我每天都要用的命令组合对刚接触这套组合的人来说可以直接抄# 查看 kubelet 运行时连接状态 journalctl -u kubelet -f | grep -i runtime # 查看 iSulad 运行时日志 journalctl -u isulad -f # 查看节点和 Pod 状态 kubectl get nodes kubectl get pod -A -o wide # 查看某个容器在节点上的运行时信息 isula inspect container-id # 全量导出集群资源清单做备份 kubectl get all -A -o yaml cluster-snapshot.yaml这套组合的维护逻辑跟常规 K8s 没太大差异唯一需要记住的就是把 Docker 命令替换成 isula把 Docker 目录替换成 isulad socket。用到滚瓜烂熟之后维护起来就跟 x86 containerd 的环境一样顺手。6. 常见问题优先级排错这些坑最值得提前注意6.1 kubelet 起不来runtime endpoint 连不上现象是节点 NotReadykubelet 日志里反复出现 “failed to connect to runtime service” 或者 “runtime connect timeout”。排查第一步先确认 isulad 在跑systemctl status isulad如果引擎正常再确认 kubelet 实际启动参数cat /var/lib/kubelet/kubeadm-flags.env里面应该有 --container-runtime-endpointunix:///run/isulad.sock 这样的内容。如果缺失或指向了错误路径修改配置文件后重启 kubeletsystemctl restart kubelet这个问题的根源基本都是在 kubeadm init 时没有把 criSocket 和 KubeletConfiguration.containerRuntimeEndpoint 同时配对。遇到这种情况不要手动乱改 kubelet 的环境变量文件回到 kubeadm 配置修正后重新 init或者至少在 worker 上重新 join避免两边 config 不一致。6.2 cgroup driver 不一致导致节点反复 NotReady现象是 kubelet 能启动master 上能看到节点但节点状态一直 NotReadykubelet 日志里有类似 “failed to validate cgroup v1” 或 “cgroup driver mismatch” 的信息。排查方法是把 kubelet 的 cgroupDriver 和 iSulad 的 cgroup-driver 拿到一起对比。kubelet 侧看 /var/lib/kubelet/config.yaml 里的 cgroupDriveriSulad 侧看 /etc/isulad/config.json 里的 cgroup-driver。两边不一致就改一致然后分别重启systemctl restart isulad systemctl restart kubelet如果系统启用了 cgroup v2要区分清楚在 v2 模式下推荐统一使用 systemdopenEuler 22.03 的默认内核 5.10 支持 cgroup v2但默认是混合模式还是 v2 模式取决于内核启动参数。可以用如下命令快速判断stat -fc %T /sys/fs/cgroup/如果输出是 cgroup2fs就是 v2。看到 cgroupfs 就直接走 cgroupfs 方案。搞清楚这一点能少走很多弯路。6.3 pause/sandbox 镜像拉取失败表现是创建 Pod 后一直处于 ContainerCreatingkubelet 事件里提示 “Failed to pull image registry.k8s.io/pause:3.9” 或类似信息。kubelet 自己不会直接拉镜像而是把镜像地址传给 iSuladiSulad 根据 pod-sandbox-image 配置去拉取。出现拉取失败时先手动用 isula pull 拉一次看看是网络问题还是地址问题isula pull registry.k8s.io/pause:3.9拉不动就换一个可达的镜像仓库比如你的内网仓库或者某个 public 仓库然后修改 iSulad 配置里的 pod-sandbox-image 字段重启 isulad。要注意这里改完配置后之前一直失败的 Pod 需要删除重建kubectl delete pod pod-name不重建的话 kubelet 会一直重试旧的配置行为虽然实际上它每次都会向 isulad 重新请求但保险起见重新创建最干脆。6.4 conntrack 和 socat 缺失导致的初始化失败kubeadm init 中途报错在预检阶段常见信息是[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: ... [ERROR SystemVerification]: missing required executables: conntrack第一个错误是没配置 sysctl第二个错误是没装 conntrack-tools这两个都能通过前面的系统初始化部分提前避免。如果走到这一步才遇到补装和配置之后重新 init 即可。需要注意的是kubeadm 的预检错误有时候会把多个问题合并抛出来不要只看最下面那一行要把所有 ERROR 都看完再一次性修复否则反复 init 会浪费时间。6.5 CNI 插件网络异常Pod 没有 IP或者 Pod 间通信不通这种情况通常是 flannel 部署后节点 Ready 了但 Pod 创建后没有拿到 10.244.x.x 的 IP或者节点上的路由表里没有对应的 flannel.1 接口。优先检查每个节点上是否生成了 CNI 配置ls -l /etc/cni/net.d/ cat /etc/cni/net.d/10-flannel.conflist如果文件存在再看 isulad 的日志里有没有调用 CNI 报错journalctl -u isulad --no-pager | grep -i cni常见原因是 cni-bin-dir 里的 flannel 二进制版本与容器镜像不匹配或者二进制没有执行权限。把 /opt/cni/bin 下的文件权限都设为 0755再重启 isulad 和 kubelet通常能解决。如果还没有可以重启 flannel DaemonSetkubectl -n kube-flannel rollout restart daemonset kube-flannel-ds这类问题在跨架构环境中尤其容易出现因为部分 CNI 的 arm64 二进制在下载或解压时如果格式不对会直接无法执行排查时多看一眼文件类型file /opt/cni/bin/flannel输出应该显示 ELF 64-bit LSB executable, ARM aarch64。看到 x86-64 就知道下载错架构了。6.6 资源不足和污点导致的 Pending最后补一个最常见但也最容易被忽略的问题Pod 一直 Pending怎么看都像网络问题实际上就是节点资源不够或者没去掉控制面污点。此时先看事件kubectl describe pod pod-name如果事件信息里出现 0/3 nodes are available、Insufficient cpu、Untolerated taint 等就不用去碰网络配置了。单节点环境记得去掉 master 污点两核四G的机器跑大镜像时也要留意内存压力。这套组合在实际跑起来之后稳定性其实比想象中好。iSulad 不是 Docker 生态的替代品它更像是 Kubernetes 原生体系里的一个适配良好的组件。只要版本对应、CRI 路径写对、cgroup 驱动统一整个集群的日常运维跟常规环境没有太大区别。我自己踩过几轮坑之后最大的体会是把“运行时选型”这个变量尽可能提前锁死不要在部署途中来回切换容器引擎。镜像这类东西尽量在节点加入集群前就准备好能离线分发就离线分发到联调阶段再处理镜像问题是最折磨人的。后来再复盘这套部署流程每个环节的复杂度其实都不高关键是把配置项之间的隐式依赖关系理顺顺着这条线走下来一次成功是大概率的事。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/22 13:52:05
Go服务容器化实战:多阶段构建与Docker Compose编排指南
2026/10/22 13:52:05
OJ题库刷题避坑指南:从输入输出到判题机制全解析
2026/10/22 13:52:05
Unity贝塞尔曲线虚线连线特效:LineRenderer与UV流动动画实现
2026/10/22 14:52:30
从RAG链路到领域知识图谱:企业内部搜索系统的架构演进
2026/10/22 14:52:30
文档转换困局怎么破?anydoc把Word/PPT/Excel/PDF一锅端成干净Markdown
2026/10/22 14:52:30
前端标准化技能栈:跨框架能力原子与路由解耦实践
2026/10/22 14:52:30
Unity DOTween移动动画动图解析:从硬赋值到工业级位移实践
2026/10/22 14:52:30
集中式贝叶斯传感器融合实战:从CentralizedSystem.rar入门
2026/10/22 14:47:28
前端转Agent开发实战:Mastra框架入门与踩坑全记录
2026/10/22 0:01:24
电商智能运营体系从0到1:架构设计、落地步骤与避坑指南
2026/10/22 0:01:24
压缩空气储能与热网热惯性联合优化调度:热电联产系统建模与求解
2026/10/22 0:01:24
若依框架AI代码生成不稳定?用Agent Skill三层结构+五步法搞定
2026/10/21 19:05:16
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/21 14:47:26
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/21 19:05:04
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/22 5:06:15
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/22 2:07:18
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/21 19:01:08
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)