高可用 Kubernetes 集群能够确保应用程序在运行时不会出现服务中断,这也是生产的需求之一。为此,有很多方法可供选择以实现高可用。本教程演示了如何配置 Keepalived 和 HAproxy 使负载均衡、实现高可用。步骤如下:
- 准备主机。
- 配置 Keepalived 和 HAproxy。
- 使用 KubeKey 创建 Kubernetes 集群。
集群架构
示例集群有三个主节点,三个工作节点,两个用于负载均衡的节点,以及一个虚拟 IP 地址。本示例中的虚拟 IP 地址也可称为“浮动 IP 地址”。这意味着在节点故障的情况下,该 IP 地址可在节点之间漂移,从而实现高可用。
集群架构
请注意,在本示例中,Keepalived 和 HAproxy 没有安装在任何主节点上。但您也可以这样做,并同时实现高可用。然而,配置两个用于负载均衡的特定节点(您可以按需增加更多此类节点)会更加安全。这两个节点上只安装 Keepalived 和 HAproxy,以避免与任何 Kubernetes 组件和服务的潜在冲突。
准备主机
IP 地址 | 主机名 | 角色 |
192.168.1.241 | lb1 | Keepalived & HAproxy |
192.168.1.242 | lb2 | Keepalived & HAproxy |
192.168.1.243 | master1 | master, etcd,worker |
192.168.1.244 | master2 | master, etcd,worker |
192.168.1.245 | master3 | master, etcd,worker |
192.168.250 | 虚拟 IP 地址 |
操作系统基础配置
(1) 配置主机名:
hostnamectl hostname master1
(2) 配置服务器时区
timedatectl set-timezone Asia/Shanghai
(3) 配置时间同步
安装 chrony 作为时间同步软件:
apt install chrony -y
编辑配置文件 /etc/chrony.conf,修改 ntp 服务器配置:
sed -i 's/pool.*/pool cn.pool.ntp.org iburst/g' /etc/chrony/chrony.conf
重启并设置 chrony 服务开机自启动:
systemctl enable chronyd
(4) 安装系统依赖
apt install curl socat conntrack ebtables ipset ipvsadm -y
配置负载均衡
Keepalived[1] 提供 VRRP 实现,并允许您配置 Linux 机器使负载均衡,预防单点故障。HAProxy[2] 提供可靠、高性能的负载均衡,能与 Keepalived 完美配合。由于 lb1 和 lb2 上安装了 Keepalived 和 HAproxy,如果其中一个节点故障,虚拟 IP 地址(即浮动 IP 地址)将自动与另一个节点关联,使集群仍然可以正常运行,从而实现高可用。若有需要,也可以此为目的,添加更多安装 Keepalived 和 HAproxy 的节点。先运行以下命令安装 Keepalived 和 HAproxy。
apt install keepalived haproxy psmisc -y
1.HAproxy
(1) 在两台用于负载均衡的机器上运行以下命令以配置 Proxy(两台机器的 Proxy 配置相同):
vi /etc/haproxy/haproxy.cfg
(2) 以下是示例配置,供您参考:
global
log /dev/log local0 warning
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
log global
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend kube-apiserver
bind *:6443
mode tcp
option tcplog
default_backend kube-apiserver
backend kube-apiserver
mode tcp
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server kube-apiserver-1 192.168.1.243:6443 check # Replace the IP address with your own.
server kube-apiserver-2 192.168.1.244:6443 check # Replace the IP address with your own.
server kube-apiserver-3 192.168.1.245:6443 check # Replace the IP address with your own.
(3) 保存文件并运行以下命令以重启 HAproxy。
systemctl restart haproxy
(4) 使 HAproxy 在开机后自动运行
systemctl enable haproxy
(5) 确保您在另一台机器 (master2) 上也配置了 HAproxy。
2.Keepalived
两台机器上必须都安装 Keepalived,但在配置上略有不同。
(1) 运行以下命令以配置 Keepalived
vi /etc/keepalived/keepalived.conf
(2) 以下是示例配置,供您参考(请注意 server 字段。请记住 6443 是 apiserver 端口):
global_defs{
notification_email{
}
script_userroot
enable_script_security
router_idLVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval1
vrrp_gna_interval1
}
vrrp_scriptchk_haproxy{
script"/usr/bin/killall -0 haproxy"
weight-50
fall3
rise5
timeout2
}
vrrp_instancehaproxy-vip{
stateMASTER
priority100
interfaceeth0# Network card
virtual_router_id60
advert_int1
authentication{
auth_typePASS
auth_pass1111
}
unicast_src_ip192.168.1.243# The IP address of this machine
unicast_peer{
192.168.1.244# The IP address of peer machines
}
virtual_ipaddress{
192.168.1.210/24# The VIP address
}
track_script{
chk_haproxy# 这个对应上面的vrrp_script
}
}
- 对于 interface 字段,您必须提供自己的网卡信息。您可以在机器上运行 ifconfig 以获取该值。
- 为 unicast_src_ip 提供的 IP 地址是您当前机器的 IP 地址。对于也安装了 HAproxy 和 Keepalived 进行负载均衡的其他机器,必须在字段 unicast_peer 中输入其 IP 地址。
(3) 保存文件并运行以下命令以重启 Keepalived。
systemctl restart keepalived
(4) 使 Keepalived 在开机后自动运行:
systemctl enable keepalived
确保您在另一台机器 (lb2) 上也配置了 Keepalived。
验证高可用
在开始创建 Kubernetes 集群之前,请确保已经测试了高可用。
(1) 在机器lb1上,运行以下命令:
(2) 如上图所示,虚拟 IP 地址已经成功添加。模拟此节点上的故障:
systemctl stop haproxy
(3) 再次检查浮动 IP 地址,您可以看到该地址在lb1上消失了。
(4) 理论上讲,若配置成功,该虚拟 IP 会漂移到另一台机器K8s-master2上。在K8s-master2 上运行以下命令,这是预期的输出:
(5) 如上所示,高可用已经配置成功。
使用 KubeKey 创建 Kubernetes 集群
KubeKey[3] 是一款用来创建 Kubernetes 集群的工具,高效而便捷。请按照以下步骤下载 KubeKey。
(1) 首先运行以下命令,以确保您从正确的区域下载 KubeKey。
export KKZONE=cn
(2) 运行以下命令来下载 KubeKey:
curl -sfL https://get-kk.kubesphere.io | VERSION=v3.1.1 sh -
下载 KubeKey 之后,如果您将其转移到访问 Googleapis 受限的新机器上,请务必再次运行 export KKZONE=cn,然后继续执行以下步骤:
(1) 执行完上述命令后,输出结果如下图:
(2) 不清楚KK的具体用法可以使用帮助,执行如下命令查看帮助:
(3) 使用默认配置创建一个示例配置文件。此处以 Kubernetes v1.29.3 作为示例。
kk create config --with-kubernetes v1.29.3
可以通过kk version --show-supported-k8s查看支持安装那些k8s版本,案例中kk采用的是最新的版本。所以,可以安装k8s最新的版本。
运行上述命令后,将在当前目录创建配置文件config-sample.yaml。根据自己的实际情况修改机器信息、配置负载均衡器等。
apiVersion:kubekey.kubesphere.io/v1alpha2
kind:Cluster
metadata:
name:sample
spec:
hosts:
-{name:master1,address:192.168.1.103,internalAddress:192.168.1.103,user:root,password:"123456"}
-{name:master2,address:192.168.1.104,internalAddress:192.168.1.104,user:root,password:"123456"}
-{name:master3,address:192.168.1.106,internalAddress:192.168.1.106,user:root,password:"123456"}
roleGroups:
etcd:
-master1
-master2
-master3
control-plane:
-master1
-master2
-master3
worker:
-master1
-master2
-master3
controlPlaneEndpoint:
## Internal loadbalancer for apiservers
# internalLoadbalancer: haproxy
domain:lb.kubesphere.local
address:"192.168.1.210"
port:9443
kubernetes:
version:v1.29.3
clusterName:cluster.local
autoRenewCerts:true
containerManager:containerd
etcd:
type:kubekey
network:
plugin:calico
kubePodsCIDR:10.233.64.0/18
kubeServiceCIDR:10.233.0.0/18
## multus support. https://github.com/k8snetworkplumbingwg/multus-cni
multusCNI:
enabled:false
registry:
privateRegistry:""
namespaceOverride:""
registryMirrors:[]
insecureRegistries:[]
addons:[]
- hosts:指定节点的 IP、ssh 用户、ssh 密码、ssh 端口
- roleGroups:指定 3 个 etcd、control-plane 节点,复用相同的机器作为 3 个 worker 节点
- internalLoadbalancer:启用内置的 HAProxy 负载均衡器
- domain:自定义域名,没特殊需求可使用默认值 lb.kubesphere.local
- clusterName:没特殊需求可使用默认值 cluster.local
- autoRenewCerts:该参数可以实现证书到期自动续期,默认为 true
- containerManager:使用 containerd
(4) 完成配置之后,可以执行以下命令开始安装:
kk create cluster -f config-sample.yaml
上面的命令执行后,首先 KubeKey 会检查部署 K8s 的依赖及其他详细要求。通过检查后,系统将提示您确认安装。输入 yes 并按 ENTER 继续部署。
- nfs client、ceph client、glusterfs client 3 个与存储有关的 client 显示没有安装,这个我们后期会在对接存储的实战中单独安装。
- docker、containerd 会根据配置文件选择的 containerManager 类型自动安装。
部署完成需要大约 10-20 分钟左右,具体看网速和机器配置,本次部署完成耗时 25 分钟。部署完成后,您应该会在终端上看到类似于下面的输出。
验证K8S集群
1.查看集群节点信息
在 master-1 节点运行 kubectl 命令获取 K8s 集群上的可用节点列表。
kubectl get nodes -o wide
在输出结果中可以看到,当前的 K8s 集群有三个可用节点、节点的内部 IP、节点角色、节点的 K8s 版本号、容器运行时及版本号、操作系统类型及内核版本等信息。
2.查看 Pod 列表
输入以下命令获取在 K8s 集群上运行的 Pod 列表。
kubectl get pods -o wide -A
在输出结果中可以看到, 所有 pod 都在运行。
部署测试资源
本示例使用命令行工具在 K8s 集群上部署一个 Nginx Web 服务器。
1.创建 Nginx Deployment
运行以下命令创建一个部署 Nginx Web 服务器的 Deployment。此示例中,我们将创建具有两个副本基于 nginx:alpine 镜像的 Pod。
root@master1:~# kubectl create deployment nginx --image nginx:alpine --replicas=2
deployment.apps/nginx created
2.创建 Nginx Service
创建一个新的 K8s 服务,服务名称 nginx,服务类型 Nodeport,对外的服务端口 80。
kubectl create service nodeport nginx --tcp=80:80
3.验证 Nginx Deployment 和 Pod
运行以下命令查看创建的 Deployment 和 Pod 资源。
kubectl get deployment -o wide
kubectl get pods -o wide
查看结果如下:
4.验证 Nginx Service
运行以下命令查看可用的服务列表,在列表中我们可以看到 nginx 服务类型 为 Nodeport,并在 Kubernetes 主机上开放了 32373 端口。
kubectl get svc -o wide
查看结果如下:
5.验证服务
运行以下命令访问部署的 Nginx 服务,验证服务是否成功部署。
验证直接访问 Pod:
问题与解决方案
查看三个节点分别出现如下报错信息:
通过执行如下名,加载下面两个模块
modprobe ip_vs
modprobe ip_vs_wrr
Reference:
- [1]Keepalived:https://www.keepalived.org/
- [2]HAProxy:http://www.haproxy.org/
- [3]KubeKey:https://github.com/kubesphere/kubekey