系列说明本文是「K8s 避坑指南」系列第 1 篇覆盖环境搭建阶段最高频的 4 个坑。后续三篇分别对应开发、生产运维、权限网络建议收藏整个系列。适用版本Kubernetes 1.24 1.30 | 系统Ubuntu 20.04/22.04、CentOS 7/8很多人第一次搭 K8s光kubeadm init这一步就能卡半天。不是文档没看是有些前置条件根本没人告诉你。这篇把环境初始化阶段最容易踩的 4 个坑整理出来每个坑都给出根本原因和可直接执行的解决方案。坑 1kubeadm init 卡住或直接报错退出报错现象[ERROR Swap]: running with swap on is not supported. Please disable swap [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: contents are not set to 1或者命令卡在[wait-control-plane] Waiting for the kubelet to boot up...超时退出什么有用信息都没有。根本原因k8s 对底层环境有 3 项强制要求漏一个就跑不起来Swap 必须关闭k8s 调度器假设 Swap 不存在启用后内存计算不准官方直接拒绝启动。内核网桥模块未加载br_netfilter缺失Pod 间流量无法被 iptables 拦截处理。cgroup driver 不一致containerd 用systemdkubelet 还配着cgroupfs两边对不上导致容器创建失败。解决方案按顺序执行一次搞定# 第一步永久关闭 Swap两行都要执行 swapoff -a sed -i s/.*swap.*/#/ /etc/fstab # 第二步加载内核模块并持久化 cat EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # 第三步配置内核参数 cat EOF | tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 EOF sysctl --system # 第四步确认 containerd 使用 systemd cgroup driver containerd config default | tee /etc/containerd/config.toml sed -i s/SystemdCgroup false/SystemdCgroup true/ /etc/containerd/config.toml systemctl restart containerd验证环境是否准备好# 预检有 ERROR 就按提示修复WARNING 可以忽略 kubeadm init phase preflight坑 2国内环境 kubeadm init 镜像拉取超时报错现象Failed to pull image registry.k8s.io/pause:3.9: rpc error: context deadline exceeded或者kubectl get pods -n kube-system里看到核心组件ImagePullBackOff。根本原因registry.k8s.io旧版是k8s.gcr.io在国内访问超时或被屏蔽。kubeadm 默认从这里拉 pause、apiserver、etcd 等核心镜像一个拉不下来整个初始化就卡死。解决方案方法一推荐init 时直接指定国内镜像源kubeadm init \ --image-repository registry.aliyuncs.com/google_containers \ --pod-network-cidr10.244.0.0/16 \ --apiserver-advertise-address你的主节点 IP方法二提前手动拉镜像并改 tag# 查看当前版本需要的完整镜像列表 kubeadm config images list # 从阿里云拉取后打 tag以 v1.28 为例 REPOregistry.aliyuncs.com/google_containers TARGETregistry.k8s.io IMAGES( kube-apiserver:v1.28.0 kube-controller-manager:v1.28.0 kube-scheduler:v1.28.0 kube-proxy:v1.28.0 pause:3.9 etcd:3.5.9-0 coredns/coredns:v1.10.1 ) for img in ${IMAGES[]}; do ctr images pull ${REPO}/${img} ctr images tag ${REPO}/${img} ${TARGET}/${img} echo ✓ ${img} 完成 done业务镜像加速containerd 镜像源配置# /etc/containerd/config.toml [plugins.io.containerd.grpc.v1.cri.registry.mirrors] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://xxxx.mirror.aliyuncs.com] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.registry.k8s.io] endpoint [https://registry.aliyuncs.com/google_containers]systemctl restart containerd坑 3kubectl 无法连接集群报错现象情况一本机The connection to the server localhost:8080 was refused情况二其他机器Unable to connect to the server: x509: certificate signed by unknown authority根本原因情况一kubeconfig未配置kubectl 默认去找localhost:8080但 API Server 实际监听的是 6443且需要认证。情况二kubeconfig 里的证书和当前集群不匹配常见于重建集群后还在用旧的~/.kube/config。解决方案# Master 节点上执行kubeadm 初始化后的标准操作这步很多人忘了 mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # 验证 kubectl cluster-info kubectl get nodes在其他机器上访问集群# 把 admin.conf 复制到目标机器 scp rootmaster-ip:/etc/kubernetes/admin.conf ~/.kube/config # 如果集群重建了旧 config 要删掉重复制 rm ~/.kube/config scp rootmaster-ip:/etc/kubernetes/admin.conf ~/.kube/config多集群切换日常运维必备# 合并多个 kubeconfig export KUBECONFIG~/.kube/config-prod:~/.kube/config-dev kubectl config get-contexts # 列出所有集群 kubectl config use-context name # 切换 kubectl config current-context # 查当前坑 4Pod 一直 Pending永远调度不上去报错现象kubectl get pods看到 Pod 长时间Pendingkubectl describe pod name的 Events 里报0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 2 node(s) had insufficient memory.根本原因Pending 只有 3 类根因原因典型场景节点资源不足节点 CPU/内存满了Pod 的requests无法被满足污点未容忍单节点学习环境Master 有control-plane污点拒绝普通 Pod选择器不匹配nodeSelector或nodeAffinity里的标签写错了解决方案# 查看节点实际可分配资源 kubectl describe nodes | grep -A 8 Allocated resources # 查看节点上的污点 kubectl describe node node-name | grep -i taint # ——— 单节点开发环境去掉 control-plane 污点 ——— # 这样 Master 节点也可以跑普通 Pod kubectl taint nodes --all node-role.kubernetes.io/control-plane- # ——— 排查标签匹配问题 ——— kubectl get nodes --show-labels # 对比 Pod 的 nodeSelector 是否和节点标签一致 kubectl get pod name -o yaml | grep -A 5 nodeSelector如果是资源不足3 个方向解决扩容节点加机器或升配降低 Pod 的requests设置清理占资源的僵尸 Pod快速检查清单环境篇□ swap 已关闭free -h 看 Swap 一行是否全 0 □ 内核模块已加载lsmod | grep br_netfilter □ sysctl 参数已生效sysctl net.bridge.bridge-nf-call-iptables □ containerd cgroup driver 是 systemdgrep SystemdCgroup /etc/containerd/config.toml □ kubeconfig 已配置kubectl get nodes 不报错 □ 节点状态 Readykubectl get nodes -o wide □ 系统组件正常kubectl get pods -n kube-system小结环境阶段的坑几乎都是「默认配置和 k8s 要求不一致」导致的把上面的检查清单过一遍基本能排完。下一篇预告环境搭好之后应用跑起来又是另一回事。Pod 反复 CrashLoopBackOff、OOMKilled、Service 访问不通、ConfigMap 热更新不生效……这些开发阶段的坑下一篇逐一拆解。