Kubernetes 集群部署:kubeadm 与高可用搭建
Kubernetes 集群部署:kubeadm 与高可用搭建
概述
本教程将手把手带你使用 kubeadm 工具从零开始部署 Kubernetes 集群,并进阶讲解如何构建高可用(HA)控制平面。无论你是初学者还是希望在生产环境中落地 K8s 的工程师,都能通过本文的实战步骤获得可复现的集群。
kubeadm 是 Kubernetes 官方提供的集群引导工具,它遵循最佳实践,能快速搭建出符合一致性认证的集群。我们首先完成一个单控制平面(1 个 master + N 个 worker)的部署,然后将其扩展为多控制平面节点的高可用架构。
目标读者与前置知识
- 熟悉 Linux 基本操作与命令行
- 了解容器(Docker/containerd)和 Kubernetes 核心概念(Pod、Node、Service 等)
- 拥有至少 2 台(单 master)或 4 台(高可用)可互通的 Linux 主机,推荐 Ubuntu 22.04 LTS 或 CentOS 7/8
环境准备
所有节点(控制平面与工作节点)均需完成以下配置。
系统要求
- 每节点至少 2 核 CPU、2 GB 内存(控制平面建议 4 GB)
- 节点间网络互通,且能正常访问外网(用于拉取镜像)
- 唯一的 hostname、MAC 地址和 product_uuid(可通过
ip link和sudo cat /sys/class/dmi/id/product_uuid检查)
配置基础环境(所有节点)
# 关闭 swap
sudo swapoff -a
# 永久关闭,编辑 /etc/fstab 注释 swap 行
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置 sysctl 参数
cat <<EOF | sudo 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
sudo sysctl --system
安装容器运行时(containerd)
Kubernetes 1.24+ 已移除对 Dockershim 的内置支持,推荐直接使用 containerd。
# 安装 containerd(Ubuntu 示例)
sudo apt-get update
sudo apt-get install -y containerd
# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 确保 SystemdCgroup 为 true(重要!)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 重启 containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
安装 kubeadm、kubelet 和 kubectl
在 每个节点 上安装指定版本(此处以 1.28 为例)的官方软件包。
# 添加 Kubernetes 仓库(Ubuntu)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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.28/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 # 防止自动更新
启动 kubelet(它会持续崩溃直到加入集群,属于正常现象):
sudo systemctl enable --now kubelet
第一部分:使用 kubeadm 部署单控制平面集群
初始化控制平面节点
在选作 master 的节点上执行:
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=1.28.0 \
--control-plane-endpoint="<CONTROL_PLANE_IP>:6443"
--pod-network-cidr需与你后续选择的网络插件匹配,这里使用 Flannel 的默认 CIDR。--control-plane-endpoint设为该节点的 IP 或域名,用于高可用扩展。
初始化成功后,输出中会包含类似以下内容:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
按提示执行命令以配置 kubectl:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
安装 Pod 网络插件
集群需要一个 CNI 插件来让 Pod 之间通信。这里使用 Flannel:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
等待所有系统 Pod 变为 Running:
kubectl get pods --all-namespaces
加入工作节点
在初始化结尾的输出中,kubeadm 会打印一条 kubeadm join 命令(包含 token 和 discovery-token-ca-cert-hash)。在 每一个 worker 节点 上,以 root 权限运行该命令:
sudo kubeadm join <CONTROL_PLANE_IP>:6443 --token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH>
如果 token 过期,可在控制平面节点重新生成:
kubeadm token create --print-join-command
验证集群节点状态:
kubectl get nodes
稍等片刻,所有节点应变为 Ready。
现在你已拥有一个可用的单 master 集群。接下来我们将它提升为高可用集群。
第二部分:高可用控制平面搭建
高可用拓扑选择
kubeadm 支持两种 HA 模式:
- 堆叠 etcd(Stacked etcd):每个控制平面节点运行自己的 etcd 成员,etcd 集群与控制平面节点耦合。
- 外部 etcd:etcd 集群独立于控制平面部署,控制平面节点仅连接外部 etcd。
本教程采用 堆叠 etcd 方式,因为它更简单且资源开销小,适用于大多数生产场景。
前置准备:负载均衡器
多个控制平面节点需要一个统一的访问入口,即 API Server 的负载均衡器(LB)。你可以使用硬件 LB、云服务商的 LB,或在某个节点上用 Keepalived + HAProxy 自建。
自建示例(在任意一台独立主机或 master 上):用 HAProxy 监听 6443 端口,并转发到所有控制平面节点的 6443 端口。配置文件 /etc/haproxy/haproxy.cfg 关键部分:
frontend kubernetes-apiserver
bind *:6443
mode tcp
option tcplog
default_backend kubernetes-apiserver
backend kubernetes-apiserver
mode tcp
balance roundrobin
option tcp-check
server master1 <IP1>:6443 check
server master2 <IP2>:6443 check
server master3 <IP3>:6443 check
假设负载均衡器的地址为 lb.example.com:6443 或 IP 192.168.1.100:6443。
初始化第一个控制平面节点(种子节点)
选择一个已完成单 master 部署的控制平面节点作为种子节点。如果是从零开始,未曾部署单 master,则直接在该节点执行 kubeadm init,但需额外指定 --control-plane-endpoint 指向负载均衡器地址,并上传证书。
若已有单 master 集群,并希望扩展为 HA:
- 将
kubeadm-configConfigMap 中的controlPlaneEndpoint更新为 LB 地址:
kubectl -n kube-system edit configmap kubeadm-config
找到 controlPlaneEndpoint,改为 lb.example.com:6443。
- 更新 kubelet 和所有控制平面组件的证书以包含新端点:
# 在所有控制平面节点执行
sudo kubeadm init phase certs all --control-plane-endpoint "lb.example.com:6443"
- 更新 admin.conf 等文件中的服务器地址,并重新分发配置文件(或者后续通过
kubeadm join同步)。
若全新部署(推荐用于练习),直接在第一个控制平面节点运行:
sudo kubeadm init \
--control-plane-endpoint "lb.example.com:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=1.28.0
参数 --upload-certs 会将控制平面证书加密后存储到集群中,供后续加入的控制平面节点自动下载,无需手动拷贝。
初始化成功后,按提示配置 kubectl,并安装 Pod 网络插件(例如 Flannel)。
加入其他控制平面节点
在种子节点输出中,包含一条用于添加控制平面节点的命令(带有 --control-plane 和 --certificate-key):
sudo kubeadm join lb.example.com:6443 --token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH> \
--control-plane \
--certificate-key <KEY>
若 token 或 certificate-key 过期,可重新生成:
# 生成新 token
kubeadm token create --print-join-command
# 生成新 certificate-key
kubeadm init phase upload-certs --upload-certs
在 第二台和第三台控制平面节点 上依次执行该 join 命令。当多个控制平面节点加入后,etcd 集群会自动扩展为 3 成员(堆叠模式)。
加入工作节点
工作节点的加入方式与单 master 一样,只是目标地址应指向 负载均衡器:
sudo kubeadm join lb.example.com:6443 --token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH>
验证高可用集群
在任意控制平面节点查看节点状态和 etcd 成员:
kubectl get nodes
kubectl -n kube-system get pods -l component=etcd
检查 etcd 集群健康(需要 etcdctl):
# 在控制平面节点安装 etcd-client
sudo apt install -y etcd-client # 或从容器内执行
# 使用 pod 中的 etcdctl
kubectl -n kube-system exec -it etcd-<master-node> -- 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
模拟控制平面节点故障:停止某个 master 节点的 kubelet 或关机,集群应仍然能够通过 LB 访问,并且 kubectl get nodes 仍正常。
常见问题与故障排除
1. kubelet 启动失败 / 节点 NotReady
- 检查 swap 是否关闭:
free -m,确认 Swap 行全为 0。 - 检查容器运行时状态:
sudo systemctl status containerd。 - 检查 kubelet 日志:
journalctl -xeu kubelet。
2. Pod 网络异常 / CoreDNS 一直 Pending
- 确认 CNI 插件已安装且 Pod 运行正常:
kubectl -n kube-system get pods。 - 检查网络插件 Pod 日志。
- 若使用 Flannel,确保
--pod-network-cidr与 Flannel 配置一致。
3. 加入节点时 token 过期
- 创建新 token:
kubeadm token create --ttl 0(0 表示永不过期)或--print-join-command直接输出完整命令。
4. 高可用加入控制平面时 certificate-key 错误
- 在第一个控制平面节点重新上传证书:
kubeadm init phase upload-certs --upload-certs,会输出新的 key。 - 确保所有控制平面节点时钟同步(NTP)。
5. etcd 集群配置问题
- 检查 etcd 成员列表:
kubectl -n kube-system exec -it etcd-<node> -- etcdctl member list。 - 若成员失效,可参考
kubeadm reset清理后重新加入。
结语
你已经掌握了使用 kubeadm 从单控制平面到高可用集群的完整部署流程。关键要点回顾:
- 基础环境准备(swap、内核模块、容器运行时)是成功的基石。
--control-plane-endpoint和负载均衡器是实现 HA 的核心。--upload-certs大幅简化了多控制平面节点的证书分发。
在生产环境中,还需结合持久化存储、监控、日志、备份等进一步加固。建议之后深入探索 Kubernetes 的调度策略、网络策略和 RBAC 权限管理。祝你在容器编排的世界中航行愉快!