实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。
选择正确的实验方式
个人练习优先使用 kind:节点是容器,创建和销毁成本低。生产或接近生产的验证使用独立 Linux 虚拟机与 kubeadm。两种路径不要混写;kind 的端口映射、存储和节点生命周期不能代表生产设计。
kind 单节点实验
kind create cluster --name lab --image kindest/node:v1.37.0 --wait 180s
kubectl cluster-info --context kind-lab
kubectl get nodes -o wide
kubectl wait --for=condition=Ready node --all --timeout=180s销毁命令是 kind delete cluster --name lab。本机若出现 cgroup 挂载错误,先运行 docker info | grep -i cgroup;Kubernetes 1.37 默认要求现代 cgroup v2 环境。不要通过反复重试掩盖宿主机能力不匹配。
kubeadm 三节点前置检查
- 每台节点时间同步、主机名唯一、端口与路由可达。
- 关闭 swap 或明确配置 kubelet 的 swap 行为。
- 安装并启用 containerd,确保 kubelet 与运行时使用同一 cgroup 驱动。
- 使用按小版本划分的仓库:v1.37 对应
pkgs.k8s.io/core:/stable:/v1.37。
sudo kubeadm init --pod-network-cidr=<与你的 CNI 一致的网段>
mkdir -p "$HOME/.kube"
sudo cp -i /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"
kubectl get nodes
kubectl get pods -Akubeadm init输出的 join 命令含短期令牌,应放入密码管理工具而不是文章或工单。安装与 Pod CIDR 匹配的 CNI 后,节点才会 Ready。逐台执行 join,每加入一台就检查节点、kube-system Pod 和事件。
验收与清理
kubectl create namespace lab
kubectl create deployment web --image=nginx:1.27-alpine -n lab
kubectl rollout status deployment/web -n lab --timeout=120s
kubectl delete namespace lab若 Pod Pending,先 kubectl describe pod 看调度事件;若 ContainerCreating,检查 CNI、镜像拉取与挂载;若节点 NotReady,检查 kubelet 和容器运行时日志。
生产式 kubeadm:逐台准备节点
以下以 Ubuntu/Debian 系为例。每台机器先记录 IP、主机名、CPU、内存、磁盘和网卡;Pod 网段、Service 网段、节点网段不得重叠。生产环境至少准备独立控制平面、独立工作节点和稳定的 API Server 入口。
sudo swapoff -a
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<'EOF' | sudo tee /etc/sysctl.d/99-kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
stat -fc %T /sys/fs/cgroup
timedatectl statusstat应显示 cgroup2fs。若仍为 cgroup v1,应先升级宿主机/虚拟化环境;不要以关闭保护参数作为长期生产方案。
安装 containerd 并统一 cgroup 驱动
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
sudo ctr version如果发行版已经提供自定义 containerd 配置,应先备份并核对 CRI 插件未被禁用,不能盲目覆盖。
安装 v1.37 工具
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.37/deb/Release.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.37/deb/ /' \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
初始化、加入与逐层验收
sudo kubeadm init \
--control-plane-endpoint=<LB_DNS_OR_IP>:6443 \
--upload-certs \
--pod-network-cidr=<CNI_POD_CIDR>
kubectl get --raw='/readyz?verbose'
kubectl get nodes -o wide
kubectl get pods -n kube-system -o wide先安装与你选定网段一致的 CNI,再执行输出中的 join 命令。加入后逐台检查:节点 Ready、CoreDNS Running、跨节点 Pod 通信、Service DNS、镜像拉取和时间同步。
常见失败矩阵
| 现象 | 验证 | 典型根因 |
|---|---|---|
| 节点 NotReady | journalctl -u kubelet | cgroup、CRI、CNI、证书 |
| CoreDNS Pending | describe Pod | CNI 未装或资源不足 |
| join 超时 | 检查 6443/TCP 与时间 | 防火墙、LB、令牌过期 |
| 镜像拉取失败 | 节点上 crictl pull | DNS、代理、仓库凭据 |
实验集群需要重置时,先排空业务,再执行 kubeadm reset并按 CNI 文档清理网络状态;该命令不能替代业务数据备份。
可复现记录模板
每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。
故障处理原则
- 先缩小影响面,不删除现场。
- 按对象状态—事件—日志—依赖顺序收集证据。
- 提出可证伪假设,一次只改变一个变量。
- 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。
完成检查
- 命令退出码为 0,目标对象状态与预期一致。
- 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
- 故障演练完成后执行清理或回滚,再进行下一章。