前言
在云原生时代,Kubernetes 已经成为容器编排的事实标准。而
kubeadm 作为官方提供的集群部署工具,是新手入门和搭建生产集群最推荐的途径之一。
本文将基于
Kubernetes v1.28,带你从零开始,完成一个
3节点控制平面(HA) 集群的搭建。内容涵盖系统前置配置、容器运行时安装、集群初始化、证书延长、网络插件部署,以及节点加入的全流程。
环境概览
OS:Linux (CentOS / Ubuntu 均可)
K8s 版本:v1.28.x (建议搭建v1.34以上的,证书续期简单)
CRI:containerd (v1.6.33)
CNI:Flannel
节点规划:3 个控制平面节点 + N 个工作节点
一、所有节点通用配置
以下操作需要在
每一台即将加入集群的服务器上执行(包括控制平面和工作节点)。
1. 关闭 Swap
Kubernetes 要求必须禁用交换分区,否则
kubelet 将无法正常工作。
# 临时关闭
sudo swapoff -a
# 持久关闭:注释 /etc/fstab 中的 swap 行
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
2. 加载内核模块并配置参数
为了让容器网络正常工作,需要加载
br_netfilter 等模块并启用 IP 转发。
# 加载模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 配置内核参数
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
3. 安装容器运行时(containerd)
这里我们选择
containerd,它是目前与
kubeadm 兼容性最好、性能最稳定的运行时之一。
3.1 二进制安装 containerd(推荐)
cd /tmp
wget https://github.com/containerd/containerd/releases/download/v1.6.33/containerd-1.6.33-linux-amd64.tar.gz
sudo tar -C /usr/local -xzf containerd-1.6.33-linux-amd64.tar.gz
# 验证
/usr/local/bin/containerd --version
3.2 配置 systemd 服务
sudo tee /etc/systemd/system/containerd.service > /dev/null <<EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable containerd --now
3.3 生成配置文件并启用 SystemdCgroup
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
4. 安装 kubeadm、kubelet 和 kubectl
以下以
Ubuntu(APT) 为例,CentOS 用户可参考文末的 YUM 方式。
# 安装依赖工具
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# 添加 Kubernetes 官方 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
二、集群初始化(控制平面节点)
1. 修改 containerd 镜像源(所有节点)
为了加速镜像拉取,我们将
sandbox_image 指向阿里云镜像仓库。
sudo sed -i 's|sandbox_image = "registry.k8s.io/pause:.*"|sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"|g' /etc/containerd/config.toml
sudo systemctl restart containerd
2. 安装 runc
containerd 依赖
runc,若未安装会报错。
sudo wget -O /usr/local/bin/runc https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64
sudo chmod +x /usr/local/bin/runc
sudo ln -s /usr/local/bin/runc /usr/bin/runc
runc --version
3. 准备 kubeadm 初始化配置文件
将证书有效期延长至
10年 / 20年,并指定 API Server 的访问 IP。
3.1. 如下是
v1.31+版本的k8s可以通过如下配置直接延长证书的有效期
# init-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "10.2.1.57" # 替换为你的节点IP
bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
imageRepository: registry.aliyuncs.com/google_containers
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "10.2.1.57:6443"
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
certificateValidityPeriod: 87600h # 10年
caCertificateValidityPeriod: 175200h # 20年
apiServer:
certSANs:
- "10.2.1.57"
- "127.0.0.1"
- "localhost"
extraArgs:
service-node-port-range: "30000-32767"
controllerManager:
extraArgs:
node-cidr-mask-size: "24"
scheduler: {}
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: KubeletConfiguration
cgroupDriver: systemd
#可以使用如下命令验证下前面的配置文件是否正常(只检查,不执行)
sudo kubeadm init --config=init-config.yaml --dry-run
3.2. 如下是 v1.30版本以前的k8s可以通过如下配置直接延长证书的有效期
v1.28.15延长证书过期时间:
# 检查 Go 版本
go version
# 如果未安装,参考以下命令安装
wget https://dl.google.com/go/go1.20.5.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
获取源码:记得下载 v1.28.15 对应的源码。
git clone -b v1.28.15 --depth=1 https://github.com/kubernetes/kubernetes.git
cd kubernetes
修改常量:修改 cmd/kubeadm/app/constants/constants.go 文件,把 CertificateValidity 的值改成 100 年。
go
// 将
CertificateValidity = time.Hour * 24 * 365
// 改为
CertificateValidity = time.Hour * 24 * 365 * 100
编译与替换:参考之前的编译命令,生成新的 kubeadm 二进制文件,并替换系统里的旧文件。
make all WHAT=cmd/kubeadm GOFLAGS=-v
4. 执行初始化
sudo kubeadm init --config=init-config.yaml --upload-certs
kubeadm certs check-expiration #查看证书的过期时间
初始化成功后,
务必保存终端输出的
kubeadm join 命令(包括
--control-plane 和
--certificate-key 部分),后续用于添加其他控制平面节点和工作节点。
5. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
三、部署 CNI 网络插件(Flannel)
在
kubeadm 部署 Kubernetes 集群的实践中,网络插件(CNI)的选择是一个关键决策点。
Flannel 和
Calico 是目前最主流的两大选择,它们的设计哲学和适用场景有显著不同。
核心区别在于:
Flannel 追求的是简单与普适性,而 Calico 则侧重于高性能与丰富的网络策略控制。
一般建议不超过50个节点,可以使用Flannel
为了让你更清晰地理解,我把它们的区别整理成了下面的表格:

安装Flannel网络插件:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
如果无法访问 GitHub,可使用国内镜像源:
kubectl apply -f https://gitee.com/mirrors/flannel/raw/master/Documentation/kube-flannel.yml
等待 Flannel Pod 启动完成:
kubectl get pods -n kube-system | grep flannel
四、加入更多控制平面节点(HA)
登录到第二、第三台控制平面节点,执行之前保存的
kubeadm join 命令:
sudo kubeadm join 10.2.1.57:6443 \
--token <your-token> \
--discovery-token-ca-cert-hash sha256:<your-hash> \
--control-plane \
--certificate-key <your-cert-key>
验证 etcd 集群状态:
kubectl get pods -n kube-system -l component=etcd -o wide
预期会看到 3 个 etcd Pod 分布在 3 个节点上。
五、加入工作节点
在工作节点上执行(若 token 过期可重新生成):
重新生成 worker 加入命令(在控制平面执行)
kubeadm token create --print-join-command
在工作节点执行
sudo kubeadm join 10.2.1.57:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
六、验证集群
回到任意控制平面节点,检查节点状态:
kubectl get nodes
当所有节点的
STATUS 变为
Ready 时,集群部署成功!
[@elk-kafka-prod-hzac.novalocal ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
elk-kafka-prod-6kqd.novalocal Ready control-plane 5d6h v1.28.15
elk-kafka-prod-hzac.novalocal Ready control-plane 6d7h v1.28.15
elk-kafka-prod-ktxw.novalocal Ready control-plane 5d6h v1.28.15
milvus-worker-01 Ready worker 3d7h v1.28.15
milvus-worker-02 Ready worker 3d8h v1.28.15
milvus-worker-03 Ready worker 6h59m v1.28.1
NAME STATUS ROLES AGE VERSION
elk-kafka-prod-6kqd.novalocal Ready control-plane 5d6h v1.28.15
elk-kafka-prod-hzac.novalocal Ready control-plane 6d7h v1.28.15
elk-kafka-prod-ktxw.novalocal Ready control-plane 5d6h v1.28.15
milvus-worker-01 Ready worker 3d7h v1.28.15
milvus-worker-02 Ready worker 3d8h v1.28.15
milvus-worker-03 Ready worker 6h59m v1.28.1
七、常见问题与避坑指南
❌ Token 过期
默认 token 有效期为 24 小时,重新生成:
# 生成新的 worker 加入命令
kubeadm token create --print-join-command
# 生成新的 control-plane 加入命令(含 certificate-key)
kubeadm token create --print-join-command --certificate-key $(kubeadm init phase upload-certs --upload-certs | tail -1)
❌ kubectl 报错 connection refused
原因:未配置
KUBECONFIG 环境变量或未复制
admin.conf。执行:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
❌ 初始化失败需要重置
sudo kubeadm reset -f
附:CentOS / RHEL 使用 YUM 安装 kubeadm
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
EOF
sudo rpm --import https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
sudo yum install -y kubelet kubeadm kubectl
sudo systemctl enable kubelet --now
结语
至此,你已经成功搭建了一个
3 节点高可用 Kubernetes 集群,并完成了网络插件部署和节点加入。这套方案已经过生产环境验证,稳定可靠。
如果你在部署过程中遇到任何问题,欢迎在评论区留言交流!后续我还会分享关于
集群监控(Prometheus)、
日志收集(ELK) 和
Ingress 配置 的实战文章,敬请关注。