集群安装:kind 与 kubeadm
本篇目标是创建一个可随时删除的练习集群,掌握 kind 与 kubeadm 两种部署方式。单机学习资源对象时选择 kind;需要理解节点、容器运行时和集群初始化时,选择 kubeadm。生产集群的准入、网络、备份和权限策略复杂得多,第一次学习不应直接在生产环境试命令。
完成后,你应能确认当前 kubectl 操作的是哪一个集群,并能创建和删除一个本地集群。

1. 安装 kubectl
kubectl 是 Kubernetes API 的命令行客户端。安装方式随系统不同而变化,请以 Kubernetes 官方安装说明 为准。安装后先验证客户端:
kubectl version --client
kubectl config get-contexts
kubectl config get-contexts 会列出所有已知集群。星号所在行是当前上下文,任何有修改效果的命令都应先确认它。
2. 用 kind 创建本地集群
kind 使用 Docker 容器模拟 Kubernetes 节点,适合练习资源对象和发布流程。先确保 Docker Engine 正在运行,再安装 kind:
# macOS
brew install kind kubectl
# 创建名为 k8s-lab 的单节点集群
kind create cluster --name k8s-lab
# 确认 kubectl 已切换到对应 context
kubectl config current-context
kubectl get nodes
预期看到一个状态为 Ready 的 control-plane 节点。首次创建会拉取节点镜像,需要一些时间。
3. 用 kubeadm 搭建多节点集群(可选进阶)
kind 已足够完成本系列的大多数练习。若你有可重装的 Linux 虚拟机或云主机,可通过 kubeadm 搭建一套更接近真实架构的集群。推荐准备两台:一台控制面节点和一台工作节点;只有一台时也能完成单节点实验。
3.1 规划节点与网络
示例使用下列地址。控制面和工作节点必须能通过内网互通,且各节点主机名唯一。Pod CIDR 192.168.0.0/16 会交由 Calico 使用,不能与主机网络、VPN 或现有 Pod 网络重叠。
| 节点 | 主机名 | 示例内网地址 | 角色 |
|---|---|---|---|
| 控制面 | k8s-control-01 | 192.168.56.10 | API Server、etcd、调度和控制器 |
| 工作节点 | k8s-worker-01 | 192.168.56.11 | 运行业务 Pod |
每台虚拟机建议至少 2 vCPU、2 GiB 内存和 20 GiB 磁盘;控制面建议 2 vCPU、4 GiB 内存。云安全组或主机防火墙至少应允许节点间的 Kubernetes 控制面和 CNI 通信。练习时最简单的做法是仅在可信的私有网段内放通节点之间的流量。
3.2 在所有节点安装 containerd 与 kubeadm
先在控制面和每个工作节点添加 Kubernetes 软件源并安装指定小版本的 kubelet kubeadm kubectl(安装后用 apt-mark hold 固定版本;版本号应在控制面和工作节点保持一致,升级时遵循后文的集群升级,不要直接升级生产节点),然后执行下面的系统准备命令——Kubernetes 使用 containerd 作为 CRI 容器运行时,禁用 swap 并让 containerd 使用 systemd cgroup,是 kubelet 正常运行的前提:
# 所有节点执行:加载容器网络所需的内核模块
sudo tee /etc/modules-load.d/k8s.conf >/dev/null <<'EOF'
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 所有节点执行:让 iptables 能看到经过网桥的流量,并启用转发
sudo tee /etc/sysctl.d/k8s.conf >/dev/null <<'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# 所有节点执行:kubelet 默认要求关闭 swap
sudo swapoff -a
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
# 所有节点执行:安装并配置 containerd
sudo apt-get update
sudo apt-get install -y ca-certificates curl gpg containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl enable --now containerd
3.3 初始化控制面
仅在控制面节点执行。将 CONTROL_PLANE_IP 改为该节点可被其他节点访问的内网 IP;不要填写 Pod CIDR 中的地址。
# 仅控制面节点执行
CONTROL_PLANE_IP=192.168.56.10
sudo kubeadm init \
--apiserver-advertise-address="${CONTROL_PLANE_IP}" \
--pod-network-cidr=192.168.0.0/16
# 让当前普通用户可以访问新集群
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
kubeadm init 最后的输出包含 kubeadm join 命令。它带有短期令牌,应妥善保存,仅在可信节点上使用。令牌默认 24 小时过期;过期后可在控制面重新生成:
sudo kubeadm token create --print-join-command
3.4 安装 Pod 网络插件
控制面就绪不代表 Pod 网络已经可用。下面以 Calico 为例,安装完成前 CoreDNS 处于 Pending 是预期现象。Calico 的发布版本需要与 Kubernetes 版本兼容;创建固定版本的实验环境时,应把版本同时记录在变更或实验笔记中。
# 仅控制面节点执行
CALICO_VERSION=v3.31.0
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/calico.yaml"
# 等待网络组件和 CoreDNS 就绪
kubectl get pods -n kube-system -w
若使用其他 CNI,必须按其官方安装文档设置对应的 Pod CIDR 和网络策略能力;不要同时安装多个 CNI。
3.5 加入工作节点
在控制面执行前一节保存的 kubeadm join 命令,或重新生成一条命令。然后在每一台工作节点粘贴并以 sudo 执行,例如:
# 仅工作节点执行;此命令以控制面实际输出为准
sudo kubeadm join 192.168.56.10:6443 \
--token TOKEN_VALUE \
--discovery-token-ca-cert-hash sha256:HASH_VALUE
回到控制面验证节点和系统组件。所有节点显示 Ready 后,再继续后续工作负载练习。
kubectl get nodes -o wide
kubectl get pods -n kube-system
kubectl cluster-info
如果只准备了一台实验机,可以移除控制面的调度污点,让业务 Pod 也能调度到该节点。这个设置仅适合单节点实验环境,生产控制面通常不应承载普通业务工作负载。
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
3.6 重置 kubeadm 实验环境
先在控制面驱逐工作节点的业务,再在各节点执行重置。kubeadm reset 不会删除 CNI 创建的网络规则或当前用户的 kubeconfig;以下清理命令会删除本机的集群配置,只能用于明确不再需要的实验集群。
# 控制面执行:先移除每个工作节点,替换为实际节点名
kubectl drain k8s-worker-01 --ignore-daemonsets --delete-emptydir-data
kubectl delete node k8s-worker-01
# 所有节点执行:重置 kubeadm 状态
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
# 控制面执行:若确认不再使用该 kubeconfig,再删除它
rm -rf "$HOME/.kube"
4. 建立自己的 Namespace
不要把练习资源堆在 default 或 kube-system。创建独立 Namespace,后续命令始终显式指定它:
kubectl create namespace learning
kubectl get namespace learning
# 创建一个只在当前终端生效的快捷 Namespace
kubectl config set-context --current --namespace=learning
kubectl config view --minify --output 'jsonpath={..namespace}{"\n"}'
最后一条命令应输出 learning。本系列示例默认使用此 Namespace;如果不设置默认值,请在每条命令中加入 -n learning。
5. 连接检查
# 控制面 API 是否可用
kubectl cluster-info
# 当前身份可以做什么;生产环境不应拥有 * 权限
kubectl auth can-i create deployments -n learning
kubectl auth can-i delete namespaces
# 查看核心系统组件所在 Namespace,不要在这里练习删除操作
kubectl get pods -n kube-system
kubectl auth can-i 是排查权限问题的第一步。若创建 Deployment 的结果为 no,应申请测试 Namespace 的最小权限,不要借用管理员 kubeconfig。
6. 清理 kind 练习环境
练习结束后可删除整个 kind 集群:
kind delete cluster --name k8s-lab
这会删除本地节点容器及其内部资源。真实集群绝不能使用类似“删除整个 Namespace / 集群”的方式清理,必须按变更流程逐项确认数据和依赖。
下一篇:Namespace 与资源隔离。