银河麒麟OS上Kubernetes/Docker异常需按基础设施、运行时、编排组件、网络策略四层逐级排查:先查磁盘内存、内核模块及cgroup挂载,再验Docker/containerd健康,接着定位kubelet、etcd、CoreDNS故障,最后排查CNI插件配置与网络命名空间。

当银河麒麟OS上运行的Kubernetes或Docker Swarm容器集群出现节点失联、Pod持续Pending、Service无法访问、网络不通等异常时,需按层次逐级验证基础设施、容器运行时、编排组件与网络策略。跳过任一环节都可能导致误判,例如将CNI插件配置错误当成kubelet崩溃处理。
确认底层主机与内核状态
容器集群依赖宿主机稳定运行,若系统资源耗尽、内核模块缺失或cgroup挂载异常,上层服务必然失效。
执行 df -h / 和 free -h,检查根分区使用率是否≥95%、内存是否被OOM Killer频繁触发;若/var/lib/docker所在分区满,【docker daemon将拒绝拉取镜像并静默退出】。
运行 lsmod | grep -E 'overlay|br_netfilter',确保 overlay(用于overlay2存储驱动)和 br_netfilter(启用网桥转发)已加载;未输出则立即执行 sudo modprobe overlay && sudo modprobe br_netfilter。
检查 cgroup 挂载点:运行 mount | grep cgroup,确认 cgroup2 与 cgroup(v1)均存在且挂载路径完整;若仅见 cgroup2 而无 cgroup v1,且使用的是 Docker 18.09.7 等旧版二进制,则需在 GRUB 配置中添加 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory 并更新内核参数。
验证容器运行时健康度
先排除 Docker 或 containerd 是否真正就绪,而非仅 systemctl 显示 active。
方法一:直接调用 Docker API
执行 curl -s --unix-socket /var/run/docker.sock http://localhost/info | jq -r '.ServerVersion + " | " + .Driver + " | " + .CgroupDriver',正常应返回类似 18.09.7 | overlay2 | systemd;若报错 Failed to connect,说明 docker.socket 未监听或 socket 文件权限错误。
方法二:测试基础容器生命周期
运行 sudo docker run --rm hello-world;若卡住超30秒,检查 sudo journalctl -u docker -n 50 --no-pager 中是否含 failed to start daemon: failed to mount overlay —— 此为 overlay2 初始化失败,需回查 /etc/docker/daemon.json 中 storage-driver 是否拼写错误或 /var/lib/docker 所在文件系统不支持。
方法三:containerd 兼容性兜底验证(适用于 Kylin V10 SP1+)
执行 sudo ctr -n k8s.io containers list;若提示 connection refused,说明 containerd 服务未启动或配置路径错误,此时应检查 /etc/containerd/config.toml 中 root = "/var/lib/containerd" 是否与实际目录一致,且该目录属主为 containerd:containerd。
定位 Kubernetes 控制平面组件异常
第一步:确认 kubelet 是否注册到 API Server
执行 kubectl get nodes -o wide,若节点状态为 NotReady 或完全不显示,运行 sudo journalctl -u kubelet -n 100 --no-pager | grep -E "(status|error|failed|Unable to update node)";常见错误如 Unable to update node status: error getting node 表明 kubelet 无法连接 apiserver,需检查 /var/lib/kubelet/kubeconfig 中 server 地址是否指向正确 IP 及端口(6443),并确认防火墙放行:sudo firewall-cmd --permanent --add-port=6443/tcp && sudo firewall-cmd --reload。
第二步:验证 etcd 健康状态
若集群调度停滞或 ConfigMap/Secret 无法同步,进入 etcd 容器或本机执行:export ETCDCTL_API=3 && sudo etcdctl --endpoints=https://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;输出中任意 endpoint 显示 unhealthy,说明 etcd 成员通信中断,需检查 /etc/kubernetes/manifests/etcd.yaml 中 --initial-cluster 列表是否包含当前节点且 peer URL 可达。
第三步:检查 CoreDNS 是否响应 DNS 查询
执行 kubectl -n kube-system get pods -l k8s-app=kube-dns,若 Pod 处于 CrashLoopBackOff,进入其日志:kubectl -n kube-system logs -l k8s-app=kube-dns --tail=50;高频报错 plugin/errors: 2 10.96.0.10:53: read udp 10.244.0.3:57402->10.244.0.1:53: i/o timeout 表明 CoreDNS 无法访问上游 DNS,需检查 /etc/resolv.conf 在容器内是否被覆盖为 nameserver 127.0.0.53(systemd-resolved 冲突),此时应在 CoreDNS ConfigMap 中显式设置 forward . 114.114.114.114。
排查 CNI 网络插件故障
Pod 启动卡在 ContainerCreating、跨节点通信失败、Service ClusterIP 不通,大概率源于 CNI 插件未就绪或配置错误。
执行 ls /opt/cni/bin/,确认 containernetworking-plugins 核心二进制(如 bridge、host-local、loopback)存在;若为空,说明 CNI 插件包未安装或解压路径错误,需从官方 release 下载对应 aarch64 版本并解压至该目录。
检查 kubelet 启动参数是否指定 CNI:ps aux | grep kubelet | grep -o 'cni-bin-dir.*' | cut -d' ' -f2,标准值应为 /opt/cni/bin;若为 /usr/lib/cni 但该路径下无文件,需修改 /var/lib/kubelet/kubeadm-flags.env 中的 --cni-bin-dir 参数并重启 kubelet。
查看节点 CNI 配置文件:cat /etc/cni/net.d/10-flannel.conflist(以 Flannel 为例),确认其中 plugins[0].type 为 flannel,且 plugins[1].type 为 portmap;若缺失 portmap 插件,NodePort 类型 Service 将无法映射端口,导致外部无法访问。
手动触发一次 CNI 配置校验:sudo crictl info | jq -r '.cniConfig',输出应为有效 JSON;若报错 cni config load failed,说明 /etc/cni/net.d/*.conf 文件语法错误,常见于多行 JSON 缺少逗号或引号不闭合,可用 jq . /etc/cni/net.d/10-flannel.conflist 快速验证。
提取关键日志进行交叉比对
单一日志源易遗漏上下文,必须将容器运行时、编排组件、内核消息三者时间线对齐。
第一步:导出最近1小时全量结构化日志
执行 sudo journalctl --since "1 hour ago" --all --no-pager > /tmp/cluster_logs_$(date +%s).log,该命令捕获包括 systemd、kubelet、docker、containerd 的原始事件流。
第二步:抓取内核环缓冲区快照
运行 sudo dmesg -T -H | grep -i -E "(oom|kill|segfault|overlay|netlink|cni)" > /tmp/dmesg_cni_oom.log,重点筛选 OOM Killer 杀死进程、overlay 挂载失败、CNI netlink 调用超时等底层错误。
第三步:获取当前 Pod 网络命名空间诊断信息
若某 Pod 卡在 ContainerCreating,先找到其 sandbox ID:sudo crictl ps -a | grep -B5 "ContainerCreating",再执行 sudo crictl inspect <sandbox_id> | jq -r '.info.runtimeSpec.linux.namespaces[] | select(.type=="network").path'</sandbox_id>,得到类似 /proc/12345/ns/net 的路径后,用 sudo nsenter -t 12345 -n ip link show 查看该 Pod 是否成功分配了 veth 接口;若无输出,证明 CNI 插件未执行成功。

















