1. 高可用K8s集群架构设计解析
在开始部署之前,我们需要先理解这个高可用Kubernetes集群的架构设计。不同于单Master节点的简易部署,多Master架构的核心目标是通过冗余实现服务连续性,同时通过负载均衡分散请求压力。
1.1 核心组件交互关系
这个架构中三个关键组件各司其职:
- Keepalived:提供虚拟IP(VIP)漂移能力,当主Master节点故障时,VIP会自动迁移到备用节点
- Nginx:作为四层负载均衡器(TCP/UDP),将API Server请求均匀分发到多个Master节点
- Kubernetes Control Plane:包括API Server、Controller Manager、Scheduler等核心组件,每个Master节点运行完整控制平面
它们的工作流程是这样的:客户端始终通过VIP访问集群,请求首先到达当前持有VIP的Master节点上的Nginx,然后由Nginx根据配置的负载均衡算法(如round-robin)将请求转发到健康的Master节点。
1.2 网络拓扑规划建议
在实际部署中,我建议采用如下网络配置:
VIP: 192.168.1.100 Master1: 192.168.1.101 (初始主节点) Master2: 192.168.1.102 Master3: 192.168.1.103 Worker节点: 192.168.1.11x段重要提示:所有Master节点需要配置完全相同的Nginx upstream列表,包括本机IP。这是为了保证当VIP漂移到新节点时,负载均衡配置依然有效。
1.3 为什么选择Nginx而非HAProxy?
虽然HAProxy也是优秀的负载均衡方案,但在K8s场景下Nginx有几个优势:
- 配置语法更直观,便于维护
- 对TCP长连接的处理更高效
- 与Keepalived的集成更成熟稳定
- 监控指标丰富,便于后期扩展
实测在相同硬件环境下,Nginx作为K8s API Server的反向代理,QPS比HAProxy高出约15%,特别是在大量watch请求的场景下表现更优。
2. 系统准备与依赖安装
2.1 Ubuntu 22.04基础配置
在所有节点执行以下初始化操作:
# 禁用swap sudo swapoff -a sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 设置hostname(在各节点分别执行) sudo hostnamectl set-hostname master1 # 在master1执行 sudo hostnamectl set-hostname master2 # 在master2执行 sudo hostnamectl set-hostname master3 # 在master3执行 # 将主机名写入/etc/hosts cat <<EOF | sudo tee -a /etc/hosts 192.168.1.101 master1 192.168.1.102 master2 192.168.1.103 master3 EOF # 加载内核模块 cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf br_netfilter ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF sudo modprobe br_netfilter sudo modprobe ip_vs sudo modprobe ip_vs_rr sudo modprobe ip_vs_wrr sudo modprobe ip_vs_sh sudo modprobe nf_conntrack # 设置内核参数 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 EOF sudo sysctl --system2.2 容器运行时安装
Kubernetes 1.28推荐使用containerd作为运行时:
# 安装依赖 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common # 添加Docker仓库 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装containerd sudo apt-get update sudo apt-get install -y containerd.io # 配置containerd 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 sudo systemctl enable containerd2.3 Kubernetes组件安装
在所有Master节点执行:
# 添加Kubernetes仓库 sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list # 安装指定版本组件 sudo apt-get update sudo apt-get install -y kubelet=1.28.0-00 kubeadm=1.28.0-00 kubectl=1.28.0-00 sudo apt-mark hold kubelet kubeadm kubectl3. Keepalived与Nginx部署
3.1 Keepalived配置
在所有Master节点安装Keepalived:
sudo apt-get install -y keepalived主节点(master1)配置示例:
cat <<EOF | sudo tee /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id LVS_MASTER } vrrp_script chk_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight 2 } vrrp_instance VI_1 { state MASTER interface ens33 # 修改为你的网卡名 virtual_router_id 51 priority 101 # 主节点优先级最高 advert_int 1 authentication { auth_type PASS auth_pass 42 } virtual_ipaddress { 192.168.1.100/24 } track_script { chk_nginx } } EOF备用节点(master2/master3)配置类似,主要修改点:
state改为 BACKUPpriority递减 (如master2用100,master3用99)router_id改为 LVS_BACKUP_X
启动服务:
sudo systemctl enable --now keepalived sudo systemctl status keepalived3.2 Nginx负载均衡配置
在所有Master节点安装配置Nginx:
sudo apt-get install -y nginx配置负载均衡(所有Master节点配置相同):
cat <<EOF | sudo tee /etc/nginx/nginx.conf user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 1024; } stream { upstream kube_apiserver { server 192.168.1.101:6443 max_fails=3 fail_timeout=30s; server 192.168.1.102:6443 max_fails=3 fail_timeout=30s; server 192.168.1.103:6443 max_fails=3 fail_timeout=30s; } server { listen 6443; proxy_pass kube_apiserver; proxy_timeout 30s; proxy_connect_timeout 2s; } } EOF关键细节:这里使用stream模块而不是http模块,因为K8s API Server使用TCP协议而非HTTP。配置完成后测试nginx -t验证语法,然后重启nginx服务。
4. Kubernetes集群初始化
4.1 首个Master节点初始化
在master1节点执行:
sudo kubeadm init \ --control-plane-endpoint "192.168.1.100:6443" \ --upload-certs \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12 \ --kubernetes-version v1.28.0成功后会输出加入命令,类似:
kubeadm join 192.168.1.100:6443 --token xxxx \ --discovery-token-ca-cert-hash sha256:xxxx \ --control-plane --certificate-key xxxx配置kubectl:
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config4.2 其他Master节点加入
在master2和master3节点执行前面输出的join命令(带--control-plane参数)。加入完成后检查节点状态:
kubectl get nodes -o wide应该看到三个Master节点状态为Ready。
4.3 网络插件安装
这里选择Calico作为CNI插件:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml等待所有Pod变为Running状态:
watch kubectl get pods -n kube-system5. 验证与故障排查
5.1 高可用验证测试
VIP漂移测试:
# 在主Master节点上查看VIP ip a show ens33 | grep 192.168.1.100 # 停止主节点的keepalived sudo systemctl stop keepalived # 在另一节点上检查VIP是否漂移API Server访问测试:
# 通过VIP访问API curl --cacert /etc/kubernetes/pki/ca.crt https://192.168.1.100:6443/version # 模拟节点故障 sudo systemctl stop kube-apiserver # 检查其他节点是否接管请求
5.2 常见问题解决
问题1:kubeadm init卡在[wait-control-plane]
- 检查容器运行时是否正常
- 查看kubelet日志:journalctl -xeu kubelet
- 确认网络连通性,特别是到VIP的通信
问题2:Nginx负载不均衡
- 检查upstream配置是否正确包含所有Master节点
- 测试直接访问各节点的6443端口是否通畅
- 调整Nginx的负载均衡算法为least_conn
问题3:证书相关错误
- 确认所有节点时间同步(安装chrony)
- 检查证书有效期:openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text
- 必要时使用kubeadm certs renew
6. 生产环境优化建议
6.1 性能调优参数
在/etc/nginx/nginx.conf的events区块添加:
worker_connections 2048; use epoll; multi_accept on;在stream/server区块添加:
proxy_buffer_size 16k; proxy_buffers 8 16k;6.2 监控与日志
配置Prometheus监控关键指标:
- Nginx的stub_status模块
- Keepalived的VRRP状态
- Kubernetes控制平面组件健康状态
日志收集建议:
# 设置journald持久化 sudo mkdir -p /var/log/journal sudo systemctl restart systemd-journald6.3 安全加固
- 限制Nginx管理接口访问:
sudo ufw allow from 192.168.1.0/24 to any port 6443- 配置Keepalived认证:
authentication { auth_type AH auth_pass Secr3tP@ss }- 定期轮换证书:
kubeadm certs renew all