Kubernetes 集群部署:kubeadm 与高可用搭建

FreeGuideOnline 最新 2026-06-13

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 linksudo 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 模式:

  1. 堆叠 etcd(Stacked etcd):每个控制平面节点运行自己的 etcd 成员,etcd 集群与控制平面节点耦合。
  2. 外部 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

  1. kubeadm-config ConfigMap 中的 controlPlaneEndpoint 更新为 LB 地址:
kubectl -n kube-system edit configmap kubeadm-config

找到 controlPlaneEndpoint,改为 lb.example.com:6443

  1. 更新 kubelet 和所有控制平面组件的证书以包含新端点:
# 在所有控制平面节点执行
sudo kubeadm init phase certs all --control-plane-endpoint "lb.example.com:6443"
  1. 更新 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 权限管理。祝你在容器编排的世界中航行愉快!