ubuntu 24.04.4,使用kubeadm + (HaProxy + Keepalived) 在线部署三个master节点的高可用k8s v1.34.10集群
系统,ubuntu 24.04.4
集群规划(3 台服务器):
主机名:k8s-master-01,内网ip:172.29.128.1
主机名:k8s-worker-01,内网ip:172.29.132.68
主机名:k8s-worker-02,内网ip:172.29.132.69
由于服务器有限,把这三台服务器既当master节点,又当工作节点,部署三个master节点的高可用k8s集群。
节点清单:
| 节点 | 内网 IP | 角色 |
| k8s-master-01 | 172.29.128.1 | Master01+Worker + HaProxy + keepalived |
| k8s-worker-01 | 172.29.132.68 | Master02+Worker + HaProxy + keepalived |
| k8s-worker-02 | 172.29.132.69 | Master03+Worker + HaProxy + keepalived |
一、所有 3 台节点统一前置初始化(全部执行)
1.1 主机名 & hosts 解析
分别设置主机名
# 节点1执行 hostnamectl set-hostname k8s-master-01 # 节点2执行 hostnamectl set-hostname k8s-worker-01 # 节点3执行 hostnamectl set-hostname k8s-worker-02
所有节点写入 /etc/hosts
cat >> /etc/hosts <<EOF 172.29.128.1 k8s-master-01 172.29.132.68 k8s-worker-01 172.29.132.69 k8s-worker-02 172.29.128.100 k8s-apiserver-vip EOF
1.2 系统内核配置、关闭 swap、防火墙
1.3. 时间同步
apt install chrony -y systemctl enable --now chronyd timedatectl set-timezone Asia/Shanghai
二,三台节点部署 HAProxy+Keepalived(VIP 负载均衡层)
2.1 所有节点安装组件
apt install -y haproxy keepalived
2.2 Keepalived 配置(区分 MASTER/BACKUP)
节点 k8s-master-01(主 VIP 节点,优先级 100)
cat > /etc/keepalived/keepalived.conf <<'EOF'
# Keepalived 多master apiserver VIP漂移配置
global_defs {
router_id LVS-k8s-master-01 # 节点唯一标识,三台不能重复
}
vrrp_instance VI_1 {
state MASTER # 主节点;备机改为BACKUP
interface eth0 # 内网业务网卡
virtual_router_id 51 # 三台集群必须统一
priority 100 # 优先级,数字越大为主,备机90/80
advert_int 1 # VRRP报文发送间隔1秒
unicast_peer {
172.29.132.68
172.29.132.69
}
authentication {
auth_type PASS
auth_pass k8svip99 # 密码1-8字符,三台完全一致
}
virtual_ipaddress {
# 业务VIP1 apiserver访问地址
172.29.128.200
# 备用VIP2
172.29.128.201
}
}
EOF
节点 k8s-worker-01(备节点,优先级 90)
cat > /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
router_id LVS-k8s-worker-01
}
vrrp_instance VI_1 {
state BACKUP #备节点用BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt #主节点恢复后不抢占vip,避免断流
unicast_peer {
172.29.128.1
172.29.132.69
}
authentication {
auth_type PASS
auth_pass k8svip99
}
virtual_ipaddress {
172.29.128.200
172.29.128.201
}
}
EOF
节点 k8s-worker-02(备节点,优先级 80)
cat > /etc/keepalived/keepalived.conf <<'EOF' global_defs { router_id LVS-k8s-worker-02 } vrrp_instance VI_1 { state BACKUP #备节点用BACKUP interface eth0 #你真实的物理网卡(ip addr查看) virtual_router_id 51 priority 80 advert_int 1 nopreempt unicast_peer { 172.29.128.1 172.29.132.68 } authentication { auth_type PASS auth_pass k8svip99 #密码长度1到8位 } virtual_ipaddress { 172.29.128.200 172.29.128.201 } } EOF
参数说明:
router_id可以同名,但尽量不要同名,看日志不好排查问题。
auth_pass密码长度不能超过8位,超过会截断,会出现诡异的问题。
virtual_ipaddress里的ip地址规则:
- 必须落在 eth0 的大网段 172.29.128.0/20 内
允许区间:172.29.128.1 ~ 172.29.143.254 - IP 必须空闲未占用:不能是 master 节点 IP、网关、其他业务服务器 IP
- 禁止使用:网段首地址
.0、广播地址.255 - 禁止跨网段:不能写 172.29.127.x/ 172.29.144.x
unicast_peer :里面的ip不能添加本机的ip,否则会自环发包,产生冗余告警,无效心跳、轻微性能损耗,判定为异常冲突,持续打印警告日志刷屏。
分段拆解含义:
(1) dev eth0
含义:把这个 VIP 绑定在 eth0 这块物理网卡上。
(2) 一块网卡可以写多行,绑定多个 VIP。
virtual_ipaddress {
172.29.128.200
172.29.128.201
}
校验 + 重启keepalived
# 校验配置语法是否正确 keepalived -t -c /etc/keepalived/keepalived.conf # 重启服务生效 systemctl restart keepalived # 设置开机自启 systemctl enable keepalived #看keepalived实时日志 journalctl -u keepalived -f
#停止keepalived
systemctl stop keepalived
3, 查看vip在哪个节点
分别在三台keepalived节点执行命令:
ip a s
会出现的三种情况,在真实网卡(eth0 / ens33)下面的信息:
(1)如果三台全部没有输出带 172.29.128.200的ip地址,表示keepalived启动失败。
(2)如果只有一台输出带 172.29.128.200的ip地址,表示keepalived工作正常。
(3)如果有两台或多台输出带172.29.128.200的 ip地址,说明脑裂,表示节点相互不通,各自都启动一台vip。
输出示例:
root@k8s-master-01:~# ip a s 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:3c:a2:4a brd ff:ff:ff:ff:ff:ff altname enp0s5 altname ens5 inet 172.29.128.1/20 metric 100 brd 172.29.143.255 scope global dynamic eth0 valid_lft 1891909023sec preferred_lft 1891909023sec inet 172.29.128.200/32 scope global eth0:vip valid_lft forever preferred_lft forever inet 172.29.128.201/32 scope global eth0:vip2 valid_lft forever preferred_lft forever inet6 fe80::216:3eff:fe3c:a24a/64 scope link valid_lft forever preferred_lft forever
2.3 全部节点 HAProxy 配置 /etc/haproxy/haproxy.cfg
#================ K8s APISERVER TCP负载均衡 6444 ================= frontend k8s-api #不要用6443端口,因为k8s apiserver使用6443 bind 0.0.0.0:6444 mode tcp option tcplog timeout client 600000 default_backend k8s-master-api backend k8s-master-api mode tcp balance roundrobin timeout server 600000 #转发k8s apiserver的6443端口 server k8s-master-01 172.29.128.1:6443 check inter 3000 rise 2 fall 3 server k8s-worker-01 172.29.132.68:6443 check inter 3000 rise 2 fall 3 server k8s-worker-02 172.29.132.69:6443 check inter 3000 rise 2 fall 3 listen stats bind 0.0.0.0:8404 stats enable stats auth admin:admin2026 stats hide-version stats refresh 5s
校验语法 + 启动自启haproxy
# 校验配置合法性 haproxy -c -f /etc/haproxy/haproxy.cfg # 重启并开机自启 systemctl restart haproxy systemctl enable --now haproxy # 验证6444端口监听 ss -ltnp | grep 6444 ss -ltnp | grep haproxy # 查看haproxy实时日志 journalctl -u keepalived -f
#停止keepalived
systemctl stop haproxy
三,安装 containerd + kubeadm(所有节点执行)
1, 安装containerd
# 1. 全局删除所有 download.docker.com 配置 sed -i '/download.docker.com/d' /etc/apt/sources.list rm -rf /etc/apt/sources.list.d/docker* apt clean rm -rf /var/lib/apt/lists/*download.docker.com* # 2. 重新生成密钥+阿里源 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg chmod 644 /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null # 3. 校验无官方docker地址 grep -r "download.docker.com" /etc/apt/ # 4. 更新源(不会再出现download.docker.com报错) apt update #安装containerd apt install -y containerd.io # 生成默认配置 containerd config default | tee /etc/containerd/config.toml # 修改cgroup驱动为systemd + 配置国内pause镜像 sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml sed -i 's#sandbox_image = "registry.k8s.io/pause:3.10"#sandbox_image = "registry.ustc.edu.cn/k8s/pause:3.10"#' /etc/containerd/config.toml # 重启生效 systemctl daemon-reload systemctl restart containerd systemctl enable --now containerd
查看可用containerd版本(可以跳过)
apt-cache madison containerd.io
输出:
apt-cache madison containerd.io containerd.io | 2.2.6-1~ubuntu.24.04~noble | https://download.docker.com/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.6-1~ubuntu.24.04~noble | https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.5-1~ubuntu.24.04~noble | https://download.docker.com/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.5-1~ubuntu.24.04~noble | https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.4-1~ubuntu.24.04~noble | https://download.docker.com/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.4-1~ubuntu.24.04~noble | https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble/stable amd64 Packages containerd.io | 2.2.3-1~ubuntu.24.04~noble | https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
2,安装 kubeadm/kubelet/kubectl v1.34.10
# 导入k8s密钥 curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | gpg --dearmor -o /usr/share/keyrings/kubernetes-apt-keyring.gpg # 写入apt源 echo 'deb [signed-by=/usr/share/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list apt update # 锁定指定版本v1.34.10 K8S_VERSION="1.34.10-1.1" apt install -y kubelet=${K8S_VERSION} kubeadm=${K8S_VERSION} kubectl=${K8S_VERSION} # 锁定版本防止自动升级 apt-mark hold kubelet kubeadm kubectl # 校验版本 kubeadm version kubectl version --client
如果不知道源里有哪些版本,先查看可用版本
# 查询kubeadm所有可用版本 apt-cache madison kubeadm # kubectl apt-cache madison kubectl # kubelet apt-cache madison kubelet
输出:
apt-cache madison kubeadm kubeadm | 1.34.10-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.9-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.8-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.7-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.6-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.5-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.4-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.3-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.2-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.1-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages kubeadm | 1.34.0-1.1 | https://pkgs.k8s.io/core:/stable:/v1.34/deb Packages
四,初始化第一个master节点(仅 k8s-master-01 执行)
1, 执行镜像预拉取(所有节点执行):
# 源镜像仓库(可替换阿里云/华为/本地私有仓) SOURCE_REPO="registry.aliyuncs.com/google_containers" # K8s标准目标仓库固定值 K8S_REPO="registry.k8s.io" # 版本变量统一管理 K8S_VER="v1.34.10" COREDNS_VER="v1.12.1" ETCD_VER="3.6.5-0" PAUSE_VER="3.10.1" # 预先拉取镜像(单行命令) kubeadm config images pull --kubernetes-version ${K8S_VER} --image-repository ${SOURCE_REPO} # 逐条打tag 4个控制平面镜像 nerdctl tag ${SOURCE_REPO}/kube-apiserver:${K8S_VER} ${K8S_REPO}/kube-apiserver:${K8S_VER} nerdctl tag ${SOURCE_REPO}/kube-controller-manager:${K8S_VER} ${K8S_REPO}/kube-controller-manager:${K8S_VER} nerdctl tag ${SOURCE_REPO}/kube-scheduler:${K8S_VER} ${K8S_REPO}/kube-scheduler:${K8S_VER} nerdctl tag ${SOURCE_REPO}/kube-proxy:${K8S_VER} ${K8S_REPO}/kube-proxy:${K8S_VER} # 特殊路径镜像单独处理 nerdctl tag ${SOURCE_REPO}/coredns:${COREDNS_VER} ${K8S_REPO}/coredns/coredns:${COREDNS_VER} nerdctl tag ${SOURCE_REPO}/pause:${PAUSE_VER} ${K8S_REPO}/pause:${PAUSE_VER} nerdctl tag ${SOURCE_REPO}/etcd:${ETCD_VER} ${K8S_REPO}/etcd:${ETCD_VER}
--image-repository 备选仓库:
阿里云:registry.aliyuncs.com/google_containers
腾讯云:mirror.ccs.tencentyun.com/k8s
华为云:repo.huaweicloud.com/kubernetes
道客云:k8s.m.daocloud.io
2, 初始化第一个master节点
kubeadm init \ --kubernetes-version v1.34.10 \ --control-plane-endpoint "172.29.128.200:6444" \ --apiserver-advertise-address=172.29.128.1 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=192.168.0.0/16 \ --upload-certs
参数说明
--control-plane-endpoint:VIP 地址,所有节点统一接入点- --control-plane-endpoint:第一个master节点的地址
--pod-network-cidr=192.168.0.0/16:适配 Calico 网络插件,用10.244.0.0/16也行--image-repository:中科大镜像仓库,解决 registry.k8s.io 拉取慢--upload-certs:将控制平面证书上传集群 secret,其他 master 加入无需手动拷贝证书
初始化成功后输出:
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 Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of control-plane nodes running the following command on each as root: kubeadm join 172.29.128.200:6444 --token rjaf1k.vg2n5uygawc8g0rr \ --discovery-token-ca-cert-hash sha256:5c5242f461e93a87de6f8bf59fa8d9a9107baad6f0cd2a494aa143333d40bafc \ --control-plane --certificate-key 22b273e5cdf206af3800682e4a38141c7d68d10234134ac71b87de3993c18765 Please note that the certificate-key gives access to cluster sensitive data, keep it secret! As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use "kubeadm init phase upload-certs --upload-certs" to reload certs afterward. Then you can join any number of worker nodes by running the following on each as root: kubeadm join 172.29.128.200:6444 --token rjaf1k.vg2n5uygawc8g0rr \ --discovery-token-ca-cert-hash sha256:5c5242f461e93a87de6f8bf59fa8d9a9107baad6f0cd2a494aa143333d40bafc
把上面两条kubeadm join命令保存下来,后加入控制面板与工作面板需需要使用。
3, 配置 kubectl 普通用户权限
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
查看集节点状态
kubectl get nodes kubectl get pod -A
4, 把其它两个节点加入到 控制平面(带 cert-key,有效期 2 小时)
(1)其它master节点加入控制面板,要先停止节点本机的haproxy,加入成功后再启动haproxy
kubeadm join 172.29.128.200:6444 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxx \ --control-plane --certificate-key xxxxxxxxxxxxxxxxxxxxxxx \ -v 6
加 -v 6 输出完整请求、镜像拉取、证书通信日志
(2)其它master节点也要配置 kubectl 普通用户权限(各自执行)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5, 移除 Master 节点污点(关键!让 master 节点可调度 Pod)
#移除某一台节点的污点
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-
#一次性清除全部控制平面污点(无需写节点名,适配任意多 master)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
6, 加入 Worker 节点(在任意一台master节点执行)
kubeadm join 172.29.128.200:6444 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxx \ -v 6
7, 集群验证(在任意一台master节点执行)
kubectl get nodes kubectl get pod -A kubectl get cs
8, token过期重置
token 过期重置:
kubeadm token create --print-join-command
证书 key 过期重置:
kubeadm init phase upload-certs --upload-certs
9, 查看 etcd 集群成员(3 节点堆叠 etcd)
kubectl exec -n kube-system etcd-k8s-master-01 -- etcdctl \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ member list # 输出3个etcd节点ID,代表etcd三副本集群正常
五,安装 calico网络插件
#下载calico官方配置文件(适合k8s v1.34.10的版本) curl -O calico-v3.32.1.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml #替换为国内daocloud镜像源 sed -i 's|quay.io/calico|m.daocloud.io/quay.io/calico|g' calico-v3.32.1.yaml #安装 kubectl apply -f calico-v3.32.1.yaml # 等待calico全部pod就绪 kubectl get pods -n kube-system -w # 全部ready后节点状态变为Ready kubectl get nodes
查看calico健康状态
kubectl get pod -A -n kube-system -w
集群健康检查
kubectl get cs
kubectl get nodes
# 三台control-plane+worker全部Ready
六 测试 VIP 高可用故障转移
1, 查看当前 VIP 在哪台节点 ip a
2, 停止对应节点 keepalived:
systemctl stop keepalived
3, 验证VIP 是否有漂移至剩余优先级最高节点。
4,再验证执行 kubectl 命令是否正常。
# 任意节点通过VIP访问集群 kubectl --server=https://172.29.128.100:6443 get nodes

浙公网安备 33010602011771号