首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Kubernetes高可用集群部署实战:基于kubeadm + 腾讯云CLB的生产级方案

Kubernetes高可用集群部署实战:基于kubeadm + 腾讯云CLB的生产级方案

原创
作者头像
用户12566962
发布2026-08-13 11:26:20
发布2026-08-13 11:26:20
1330
举报

Kubernetes高可用集群部署实战:基于kubeadm + 腾讯云CLB的生产级方案

引言

在云原生时代,Kubernetes已成为容器编排的事实标准。对于生产环境,集群的高可用性(HA)是刚性需求——控制平面必须容忍节点故障,确保API服务连续性。本文不空谈理论,而是基于腾讯云CVMCLB(云负载均衡器),使用kubeadm工具从零部署一套符合生产级标准的Kubernetes高可用集群。全文包含完整命令、配置文件、验证步骤及故障注入测试,技术深度直面一线运维场景。


1. 架构设计

1.1 拓扑选择:堆叠etcd vs 外部etcd

  • 堆叠etcd:etcd与控制平面组件(apiserver、controller-manager、scheduler)共宿主机,部署简单,但控制平面节点故障时etcd成员同时丢失,需至少3台控制平面节点。
  • 外部etcd:etcd独立集群,控制平面节点可水平扩展,资源隔离更佳,但运维复杂度高。

本文选用堆叠etcd + 3个控制平面节点,兼顾可靠性与部署效率。控制平面通过腾讯云CLB实现四层(TCP)负载均衡,对外暴露一个VIP:6443,所有kubelet和kubectl均通过该VIP访问API Server。

1.2 节点规划

角色

主机名

内网IP(示例)

配置要求

控制平面节点1(etcd)

k8s-master-1

10.0.1.10

4C 8G SSD

控制平面节点2(etcd)

k8s-master-2

10.0.1.11

4C 8G SSD

控制平面节点3(etcd)

k8s-master-3

10.0.1.12

4C 8G SSD

工作节点1

k8s-worker-1

10.0.1.20

2C 4G

工作节点2

k8s-worker-2

10.0.1.21

2C 4G

负载均衡器(CLB)

-

10.0.1.100(VIP)

腾讯云四层CLB

操作系统:TencentOS Server 3.1(基于RHEL 8),内核 5.4.119。所有节点需配置SSH免密、主机名解析(/etc/hosts或内网DNS)。


2. 环境准备(所有节点统一执行)

2.1 系统基础配置

代码语言:javascript
复制
# 关闭swap(kubelet强制要求)
swapoff -a && sed -i '/swap/d' /etc/fstab

# 关闭防火墙(或放行必要端口:6443,2379-2380,10250,10259,10257等)
systemctl stop firewalld && systemctl disable firewalld

# 设置内核参数
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
vm.swappiness = 0
EOF
sysctl --system

# 加载br_netfilter模块
modprobe br_netfilter && lsmod | grep br_netfilter

# 安装基础工具
yum install -y wget curl vim git conntrack-tools

2.2 安装容器运行时(Containerd)

Kubernetes 1.26+ 官方推荐使用CRI兼容运行时,这里选用containerd,性能与稳定性优于Docker。

代码语言:javascript
复制
# 安装containerd
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y containerd.io

# 生成默认配置并修改cgroup驱动为systemd(与kubelet一致)
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 配置pause镜像加速(腾讯云内网镜像)
sed -i 's/sandbox_image = .*/sandbox_image = "ccr.ccs.tencentyun.com/k8s/pause:3.9"/' /etc/containerd/config.toml

# 启动containerd
systemctl daemon-reload && systemctl enable containerd --now

2.3 安装kubeadm、kubelet、kubectl

使用腾讯云提供的Kubernetes YUM源(或阿里源),版本锁定为 v1.28.8(当前稳定版)。

代码语言:javascript
复制
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.tencent.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.tencent.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.tencent.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum install -y kubeadm-1.28.8 kubelet-1.28.8 kubectl-1.28.8 --disableexcludes=kubernetes
systemctl enable kubelet --now

注意:此时kubelet启动会报错(未加入集群),属正常现象,后续初始化后自动恢复。


3. 配置腾讯云CLB作为API Server负载均衡

3.1 创建四层CLB

登录腾讯云控制台,购买内网四层CLB(带宽按需,推荐500Mbps以上),监听器配置如下:

  • 监听协议端口:TCP 6443
  • 后端协议端口:TCP 6443
  • 健康检查:TCP,间隔5秒,超时2秒,健康阈值3,不健康阈值3
  • 后端服务器:绑定3台控制平面节点的内网IP(10.0.1.10, .11, .12),权重均等。

记录CLB的VIP(例如 10.0.1.100)和监听器ID(后续用于API Server的--advertise-address?实际我们使用--control-plane-endpoint)。

3.2 所有节点配置CLB域名解析(可选)

/etc/hosts中添加:

代码语言:javascript
复制
10.0.1.100 apiserver.cluster.local

后续kubeadm初始化使用apiserver.cluster.local:6443作为控制平面端点。


4. 部署第一个控制平面节点(初始化集群)

4.1 生成初始化配置文件

使用kubeadm config print init-defaults生成基础模板,按需修改。关键参数:

代码语言:javascript
复制
# init-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.0.1.10   # 本机内网IP
  bindPort: 6443
nodeRegistration:
  name: k8s-master-1
  criSocket: unix:///var/run/containerd/containerd.sock
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.8
controlPlaneEndpoint: "apiserver.cluster.local:6443"  # CLB VIP域名
apiServer:
  extraArgs:
    bind-address: 0.0.0.0
    # 启用etcd健康检查等
  certSANs:
  - apiserver.cluster.local
  - 10.0.1.100   # CLB VIP
  - 127.0.0.1
  - 10.0.1.10
  - 10.0.1.11
  - 10.0.1.12
controllerManager:
  extraArgs:
    bind-address: 0.0.0.0
scheduler:
  extraArgs:
    bind-address: 0.0.0.0
etcd:
  local:
    dataDir: /var/lib/etcd
    extraArgs:
      listen-client-urls: https://0.0.0.0:2379
      advertise-client-urls: https://10.0.1.10:2379
      listen-peer-urls: https://0.0.0.0:2380
      initial-advertise-peer-urls: https://10.0.1.10:2380
      initial-cluster: k8s-master-1=https://10.0.1.10:2380,k8s-master-2=https://10.0.1.11:2380,k8s-master-3=https://10.0.1.12:2380
      initial-cluster-state: new
      initial-cluster-token: etcd-cluster-1
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

关键说明

  • controlPlaneEndpoint指向CLB域名,所有kubelet和组件通过该地址访问API Server,实现负载均衡。
  • certSANs必须包含CLB VIP和域名,否则API Server证书不认可该地址,导致连接拒绝。
  • etcd的initial-cluster需列出全部3个控制平面节点,后续加入时自动发现。

4.2 拉取镜像(内网加速)

代码语言:javascript
复制
# 查看所需镜像
kubeadm config images list --config=init-config.yaml
# 使用腾讯云镜像仓库拉取(替换registry)
kubeadm config images pull --config=init-config.yaml --image-repository=ccr.ccs.tencentyun.com/k8s

4.3 执行初始化

代码语言:javascript
复制
kubeadm init --config=init-config.yaml --upload-certs

初始化成功后,输出包含:

  • 控制平面节点加入命令(含证书密钥)
  • 工作节点加入命令
  • kubeconfig文件位置(/etc/kubernetes/admin.conf

保存输出内容,尤其是--certificate-key,用于后续控制平面节点加入。

4.4 配置kubectl访问

代码语言:javascript
复制
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

验证集群状态:

代码语言:javascript
复制
kubectl get nodes  # 仅master-1,状态NotReady(未安装CNI)
kubectl get pods -n kube-system  # etcd、apiserver等均Running

5. 加入其余控制平面节点(实现etcd集群与API Server多副本)

5.1 将master-2和master-3加入

在master-2上执行(使用初始化输出的join命令):

代码语言:javascript
复制
kubeadm join apiserver.cluster.local:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --control-plane --certificate-key <cert-key> \
    --node-name k8s-master-2

master-3同理,替换--node-name k8s-master-3

注意:join时需保证etcd的initial-cluster已包含新节点?实际上kubeadm会自动将新etcd成员加入现有集群,无需提前修改配置,但需确保节点间网络互通且/etc/hosts解析所有主机名。

5.2 验证etcd集群健康

代码语言:javascript
复制
# 在任一控制平面节点执行
kubectl exec -n kube-system etcd-k8s-master-1 -- etcdctl --endpoints=https://10.0.1.10:2379,https://10.0.1.11:2379,https://10.0.1.12:2379 \
    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --key=/etc/kubernetes/pki/etcd/server.key \
    endpoint health

预期所有端点返回 healthy

5.3 验证控制平面组件高可用

查看kube-system pod分布:

代码语言:javascript
复制
kubectl get pods -n kube-system -o wide | grep -E 'apiserver|controller-manager|scheduler'

每个组件应有3个副本,分别调度在不同控制平面节点上。


6. 安装CNI网络插件(Calico)

集群内部通信必须依赖CNI。选用Calico,支持网络策略,性能优秀。

代码语言:javascript
复制
# 安装Calico operator和资源
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml

# 等待所有pod Running
kubectl wait --for=condition=Ready pods --all -n calico-system --timeout=300s

检查节点状态:

代码语言:javascript
复制
kubectl get nodes  # 全部Ready

7. 加入工作节点

在worker-1、worker-2上执行工作节点join命令(初始化输出中的worker join命令,不含--control-plane):

代码语言:javascript
复制
kubeadm join apiserver.cluster.local:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --node-name k8s-worker-1

验证:

代码语言:javascript
复制
kubectl get nodes -o wide
NAME            STATUS   ROLES           AGE   VERSION   INTERNAL-IP
k8s-master-1    Ready    control-plane   ...   v1.28.8   10.0.1.10
k8s-master-2    Ready    control-plane   ...   v1.28.8   10.0.1.11
k8s-master-3    Ready    control-plane   ...   v1.28.8   10.0.1.12
k8s-worker-1    Ready    <none>          ...   v1.28.8   10.0.1.20
k8s-worker-2    Ready    <none>          ...   v1.28.8   10.0.1.21

8. 高可用实战测试(故障注入)

8.1 模拟控制平面节点宕机

在master-1执行shutdown -h now(或直接kill apiserver进程)。然后从任意机器通过kubectl访问集群(使用CLB VIP):

代码语言:javascript
复制
kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf  # 依然正常返回

8.2 模拟etcd成员故障

停止master-1上的etcd容器(或直接关机),然后检查etcd集群成员:

代码语言:javascript
复制
kubectl exec -n kube-system etcd-k8s-master-2 -- etcdctl member list

可以看到故障节点状态为unstarted,但集群仍保持多数(2/3存活),读写正常。

8.3 测试Leader选举

删除当前leader的controller-manager pod,观察是否快速切换到其他节点:

代码语言:javascript
复制
kubectl delete pod -n kube-system kube-controller-manager-k8s-master-1
kubectl get lease -n kube-system kube-controller-manager -o yaml  # 查看holderIdentity变化

所有测试应显示业务无感知,API服务持续可用。


9. 生产级加固与监控建议

9.1 RBAC与审计日志

启用API Server审计日志,配置审计策略,将日志输出到腾讯云CLS(日志服务):

代码语言:javascript
复制
apiServer:
  extraArgs:
    audit-policy-file: /etc/kubernetes/audit-policy.yaml
    audit-log-path: /var/log/audit/kube-apiserver-audit.log
    audit-log-maxage: "30"
    audit-log-maxbackup: "10"
    audit-log-maxsize: "100"

9.2 资源配额与LimitRange

为命名空间设置ResourceQuota,防止资源争抢。

9.3 集群自动扩缩容

结合腾讯云CVM伸缩组,部署Cluster Autoscaler,根据Pod pending状态自动增减节点。

9.4 监控体系(Prometheus + Grafana)

通过Helm部署kube-prometheus-stack,采集控制平面组件指标,设置告警规则(如etcd leader变更频繁、apiserver请求延迟超过阈值)。


10. 常见问题排障

Q1:kubeadm join控制平面失败,提示etcd cluster unhealthy

解决:检查etcd的initial-cluster配置是否包含所有节点,且节点间2380端口互通;查看etcd日志 kubectl logs -n kube-system etcd-xxx

Q2:kubectl通过CLB访问报错 "x509: certificate is valid for ... not CLB VIP"

解决:在初始化时certSANs漏掉了CLB IP或域名,需要重新生成证书(使用kubeadm certs renew并修改--cert-san)或重新初始化。

Q3:节点NotReady,CNI Pod CrashLoopBackOff

解决:检查calico是否依赖/etc/cni/net.d配置,或Pod CIDR是否与VPC路由冲突。可调整Calico的IP池为10.244.0.0/16或其他不重叠段。


结语

本文详细演示了基于kubeadm + 腾讯云CLB构建Kubernetes高可用集群的完整流程,涵盖了从系统初始化、组件配置、负载均衡集成、集群扩容到故障验证的全链路实践。该方案已在多家企业的腾讯云生产环境中稳定运行,经受住了节点宕机、网络分区等故障考验。希望这篇文章能为你的云原生基础设施落地提供可靠参考。后续可继续探索服务网格(Istio)、GitOps(ArgoCD)等高级主题,构建完整的应用交付体系。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • Kubernetes高可用集群部署实战:基于kubeadm + 腾讯云CLB的生产级方案
    • 引言
    • 1. 架构设计
      • 1.1 拓扑选择:堆叠etcd vs 外部etcd
      • 1.2 节点规划
    • 2. 环境准备(所有节点统一执行)
      • 2.1 系统基础配置
      • 2.2 安装容器运行时(Containerd)
      • 2.3 安装kubeadm、kubelet、kubectl
    • 3. 配置腾讯云CLB作为API Server负载均衡
      • 3.1 创建四层CLB
      • 3.2 所有节点配置CLB域名解析(可选)
    • 4. 部署第一个控制平面节点(初始化集群)
      • 4.1 生成初始化配置文件
      • 4.2 拉取镜像(内网加速)
      • 4.3 执行初始化
      • 4.4 配置kubectl访问
    • 5. 加入其余控制平面节点(实现etcd集群与API Server多副本)
      • 5.1 将master-2和master-3加入
      • 5.2 验证etcd集群健康
      • 5.3 验证控制平面组件高可用
    • 6. 安装CNI网络插件(Calico)
    • 7. 加入工作节点
    • 8. 高可用实战测试(故障注入)
      • 8.1 模拟控制平面节点宕机
      • 8.2 模拟etcd成员故障
      • 8.3 测试Leader选举
    • 9. 生产级加固与监控建议
      • 9.1 RBAC与审计日志
      • 9.2 资源配额与LimitRange
      • 9.3 集群自动扩缩容
      • 9.4 监控体系(Prometheus + Grafana)
    • 10. 常见问题排障
      • Q1:kubeadm join控制平面失败,提示etcd cluster unhealthy
      • Q2:kubectl通过CLB访问报错 "x509: certificate is valid for ... not CLB VIP"
      • Q3:节点NotReady,CNI Pod CrashLoopBackOff
    • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档