Skip to content

使用 kubeadm 搭建集群

kubeadm 用于引导符合 Kubernetes 最佳实践的集群,但不会安装容器运行时、CNI、存储、Ingress/Gateway 或监控系统。本例使用 containerd 和 Kubernetes 1.36,实际部署时应选择目标 minor 的最新补丁版本。

Kubernetes 1.23、Docker/dockershim、kubernetes-xenial 和旧 Yum 仓库均已停止维护,不再作为新集群搭建方案。旧集群的版本变化和迁移顺序参见“版本演进与升级”。

环境规划

项目要求
操作系统受 Kubernetes、containerd 和 CNI 支持的 Linux 发行版
容器运行时containerd 或 CRI-O,使用 CRI v1
cgroup推荐 cgroup v2,运行时和 kubelet 使用一致的 systemd driver
网络节点间端口可达,每个节点具有唯一 hostname、MAC 和 product_uuid
Swap默认禁用;启用 NodeSwap 时需显式配置 kubelet
时间使用 chrony 或 systemd-timesyncd 保持同步

生产环境至少部署三个 control plane 节点和奇数个 etcd 成员,并通过稳定的负载均衡地址访问 API Server。单 control plane 示例只适合学习和测试。

准备节点

所有节点执行:

bash
sudo swapoff -a

sudo modprobe overlay
sudo modprobe br_netfilter

cat <<'EOF' | sudo tee /etc/modules-load.d/kubernetes.conf
overlay
br_netfilter
EOF

cat <<'EOF' | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

不要把“关闭防火墙、关闭 SELinux、关闭所有安全控制”作为通用前置条件。应根据所选 CNI 和发行版放通所需端口;SELinux 可保持启用时,优先使用经过适配的策略。

配置 containerd

通过发行版的软件仓库安装 containerd。生成配置后启用 CRI,并设置 systemd cgroup:

bash
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

确认配置包含:

toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  SystemdCgroup = true

不同 containerd 大版本的配置结构可能变化,应使用当前版本生成的默认配置修改,不要直接复制其他版本的完整 config.toml

bash
sudo systemctl enable --now containerd
sudo systemctl restart containerd
sudo ctr plugins ls | grep cri

安装 crictl 后可配置 CRI endpoint:

yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false

安装 kubeadm、kubelet 和 kubectl

Kubernetes 的软件仓库按 minor version 分开。以下为 Debian/Ubuntu 示例:

bash
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.36/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.36/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 systemctl enable --now kubelet

RPM 系发行版应使用同一 minor 对应的 pkgs.k8s.io/core:/stable:/v1.36/rpm/ 仓库。安装命令以官方 kubeadm 安装文档为准。

初始化第一个 control plane

示例网络参数必须与所选 CNI 的配置一致:

yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.36.2
controlPlaneEndpoint: "k8s-api.example.com:6443"
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/12
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
systemReserved:
  cpu: 500m
  memory: 512Mi
kubeReserved:
  cpu: 500m
  memory: 512Mi
evictionHard:
  memory.available: 200Mi
  nodefs.available: 10%

版本号应替换为目标 minor 的最新补丁。执行前检查配置和镜像:

bash
sudo kubeadm config images list --config kubeadm-config.yaml
sudo kubeadm config images pull --config kubeadm-config.yaml
sudo kubeadm init --config kubeadm-config.yaml --upload-certs

初始化成功后配置当前用户的 kubeconfig:

bash
mkdir -p "$HOME/.kube"
sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"

admin.conf 具有高权限,不应复制到 worker 节点或分发给普通用户。

安装 CNI

在 CNI 安装完成前节点通常保持 NotReady。选择 Calico、Cilium 等实现时应确认:

  • 支持当前 Kubernetes 和 Linux 内核版本。
  • Pod CIDR 与 kubeadm 配置一致。
  • 使用 kube-proxy、替代 kube-proxy,还是混合模式。
  • NetworkPolicy、双栈、加密和可观测性能力是否满足需求。

使用固定版本的官方清单或 Helm Chart,不要直接应用会随时间变化的 mainmaster 或无版本 URL。

加入节点

初始化结束时 kubeadm 会输出 join 命令。命令丢失后可在 control plane 重新生成:

bash
kubeadm token create --print-join-command

在 worker 节点执行输出的命令。增加 control plane 节点时,还需要 --control-plane、稳定的 API Server endpoint 和证书分发方案。

Bootstrap Token 默认会过期,不应把真实 Token 或 discovery hash 写进公共文档。

验证集群

bash
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get --raw='/readyz?verbose'

kubectl create deployment web --image=nginx:stable
kubectl expose deployment web --port=80
kubectl run curl --rm -it --restart=Never --image=curlimages/curl -- \
  curl -fsS http://web

测试完成后删除示例资源:

bash
kubectl delete service web
kubectl delete deployment web

单节点测试集群

control plane 默认带有 NoSchedule 污点。只在单节点学习环境移除:

bash
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

生产环境应保留 control plane 隔离,不要使用旧的 node-role.kubernetes.io/master 作为新配置。

后续配置

基础集群完成后仍需规划:

  • control plane 和 etcd 高可用、备份与恢复演练。
  • CSI StorageClass、VolumeSnapshot 和数据备份。
  • Gateway API 或仍受维护的入口控制器。
  • Pod Security Admission、RBAC、Secret 静态加密和审计。
  • Metrics Server、监控、日志和告警。
  • 镜像仓库、供应链签名、漏洞扫描和准入策略。
  • 按 minor version 执行的升级和组件兼容性检查。