# 一、实验介绍
要想实现kubernetes集群的高可用,也就是实现控制面组件的高可用:
1. **etcd**:
- **高可用需求**:etcd 是 Kubernetes 集群的分布式键值存储系统,存储着集群的状态信息,因此需要保证其高可用性。
- **实现方式**:可以通过部署多个 etcd 实例,使用 `Raft` 协议进行数据复制和选举,确保即使部分节点故障,集群仍然能够正常运行。同时,建议将 etcd 部署在独立的节点上,避免与其他 Kubernetes 组件共享节点。
2. **API Server**:
- **高可用需求**:API Server 是 Kubernetes 集群的入口,负责接收和处理 API 请求,需要保证其高可用性。
- **实现方式**:可以通过部署多个 API Server 实例,并在负载均衡器后面进行负载均衡,以实现请求的分发和高可用性。同时,建议采用证书签名和认证等机制加强 API Server 的安全性。
3. **Controller Manager 和 Scheduler**:
- **高可用需求**:Controller Manager 负责维护集群中各种资源(如 Pod、Replication Controller 等)的状态,Scheduler 负责将 Pod 调度到合适的节点上,两者都需要保证高可用性。
- **实现方式**:可以通过部署多个 Controller Manager 和 Scheduler 实例,并使用 leader 选举机制确保只有一个实例处于活跃状态,其他实例处于备份状态。这样即使活跃实例出现故障,其他备份实例可以接管工作。
本文使用 Keepalived 和 HAproxy 实现 API Server 的高可用,架构如下图所示。
![高可用架构.png](/upload/高可用架构.png)
# 二、实验环境
| 主机编号 | 主机名 | IP地址 | 角色 | OS | 服务 |
| :------: | :-------: | :------------: | :---------:| :--------: | :------------------: |
| 1 | master-01 | 192.168.17.110 | 控制面-01 | CentOS 7.9 | master,etcd |
| 2 | master-02 | 192.168.17.120 | 控制面-02 | CentOS 7.9 | master,etcd |
| 3 | master-03 | 192.168.17.130 | 控制面-03 | CentOS 7.9 | master,etcd |
| 4 | worker-01 | 192.168.17.140 | 数据面-01 | CentOS 7.9 | worker |
| 5 | lb-01 | 192.168.17.150 | 高可用-主 | CentOS 7.9 | HAproxy & Keepalived |
| 6 | lb-02 | 192.168.17.160 | 高可用-备 | CentOS 7.9 | HAproxy & Keepalived |
| | | 192.168.17.200 | 虚拟 IP | | |
请注意,在本示例中,Keepalived 和 HAproxy 没有安装在任何主节点上。但您也可以这样做,并同时实现高可用。
然而,配置两个用于负载均衡的特定节点(您可以按需增加更多此类节点)会更加安全。这两个节点上只安装 Keepalived 和 HAproxy,以避免与任何 Kubernetes 组件和服务的潜在冲突。
如果将负载设备和控制面安装在同一台主机上,需要将haproxy的端口监听在非6443端口。
# 三、配置负载均衡
**lb-01 && lb-02**
##### 1. 安装HAproxy
```shell
yum -y install haproxy keepalived psmisc
```
##### 2. 编辑HAproxy的配置文件
```shell
以下是一个配置文件模板
cat /etc/haproxy/haproxy.cfg
```
```shell
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 tcplog
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.17.110:6443 check # Replace the IP address with your own.
server kube-apiserver-2 192.168.17.120:6443 check # Replace the IP address with your own.
server kube-apiserver-3 192.168.17.130:6443 check # Replace the IP address with your own.
```
两台主机 HAproxy 的配置文件是一样的
##### 3. 启动HAproxy
```shelll
systemctl restart haproxy
systemctl enable haproxy
```
##### 4. 配置Keepalived
```shell
#以下是lb-01的配置文件,lb-02的略有不同
cat /etc/keepalived/keepalived.conf
```
```
global_defs {
notification_email {
}
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance haproxy-vip {
state BACKUP
priority 100
interface ens33 # Network card
virtual_router_id 60
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
unicast_src_ip 192.168.17.150 # The IP address of this machine
unicast_peer {
192.168.17.160 # The IP address of peer machines
}
virtual_ipaddress {
192.168.17.200/24 # The VIP address
}
track_script {
chk_haproxy
}
}
```
注意事项:
- 对于 `interface` 字段,您必须提供自己的网卡信息。您可以在机器上运行 `ifconfig` 以获取该值。
- 为 `unicast_src_ip` 提供的 IP 地址是您当前机器的 IP 地址。对于也安装了 HAproxy 和 Keepalived 进行负载均衡的其他机器,必须在字段 `unicast_peer` 中输入其 IP 地址。
##### 5. 启动Keepalived
```fshell
systemctl restart keepalived
systemctl enable keepalived
```
##### 6. 测试高可用
###### 6.1 在主机lb-01上运行以下命令
```shell
[root@lb-01 ~]# ip a
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
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:46:98:b0 brd ff:ff:ff:ff:ff:ff
inet 192.168.17.110/24 brd 192.168.17.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.17.200/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::4d96:e5f1:682:f79b/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::71b8:266c:7bcf:5022/64 scope link noprefixroute
valid_lft forever preferred_lft forever
```
###### 6.2 如上所示,lb-01虚拟IP(192.168.17.200)已经成功添加。模拟此节点上的故障
```shell
systemctl stop haproxy
```
###### 6.3 再次检查浮动地址,可以看到虚拟IP从lb-01上消失
```shell
[root@lb-01 ~]# ip a
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
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:46:98:b0 brd ff:ff:ff:ff:ff:ff
inet 192.168.17.150/24 brd 192.168.17.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::4d96:e5f1:682:f79b/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::71b8:266c:7bcf:5022/64 scope link noprefixroute
valid_lft forever preferred_lft forever
```
###### 6.4 理论上讲,如果配置成功,虚拟IP地址将漂移到主机lb-1上。lb-1上输入以下命令
```shell
[root@lb-02 ~]# ip a
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
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:78:78:fb brd ff:ff:ff:ff:ff:ff
inet 192.168.17.160/24 brd 192.168.17.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.17.200/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::4d96:e5f1:682:f79b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
```
###### 6.5 如上图所示,高可用配置成功
# 四、使用KubeKey创建Kubernetes集群
**KubeKey** 是一款用来创建 Kubernetes 集群的工具。
##### 1. 下载KubeKey
```shell
export KKZONE=cn
curl -sfL https://get-kk.kubesphere.io | VERSION=v3.0.7 sh -
```
注意事项:
- `curl -sfL https://get-kk.kubesphere.io`:这部分使用 curl 命令从指定的 URL([https://get-kk.kubesphere.io](https://get-kk.kubesphere.io/))下载内容。其中:
- `-s` 参数表示静默模式,不输出下载过程信息。
- `-f` 参数表示在发生错误时不显示错误信息。
- `-L` 参数表示跟随重定向,即如果下载内容有重定向,会继续下载重定向后的内容。
- `|`:管道符号,将 curl 命令的输出传递给下一个命令。
- `VERSION=v3.0.7 sh -`:这部分将下载的内容作为 shell 脚本执行。其中:
- `VERSION=v3.0.7` 是设置一个环境变量 `VERSION` 的数值为 `v3.0.7`,用于指定安装的 KubeSphere 版本。
- `sh -` 表示使用 shell 解释器执行通过管道传递过来的内容,即下载的脚本文件。
综合起来,这行命令的作用是从指定的 URL 下载 KubeSphere 安装脚本,并以指定的版本号进行安装。
通过以上命令,可以下载 KubeKey 的3.0.7版本。您可以更改命令中的版本号来下载特定的版本。
##### 2. 创建配置文件
```shell
./kk create config --with-kubesphere v3.3.2 --with-kubernetes v1.23.15
```
注意事项:
- 若没有在本步骤的命令中添加标志 `--with-kubesphere`,那么除非您使用配置文件中的 `addons` 字段进行安装,或者稍后使用 `./kk create cluster` 时再添加该标志,否则 KubeSphere 将不会被部署。
- 具体的版本号可以手动指定,本文以1.23.15版本为例。
运行上述命令后,将创建配置文件 `config-sample.yaml`。编辑文件以添加机器信息、配置负载均衡器等。
##### 3. 修改配置文件
```shell
...
spec:
hosts:
- {name: master-01, address: 192.168.17.110, internalAddress: 192.168.17.110, user: root, password: "123123"}
- {name: master-02, address: 192.168.17.120, internalAddress: 192.168.17.120, user: root, password: "123123"}
- {name: master-03, address: 192.168.17.130, internalAddress: 192.168.17.130, user: root, password: "123123"}
- {name: worker-01, address: 192.168.17.140, internalAddress: 192.168.17.140, user: root, password: "123123"}
roleGroups:
etcd:
- master-01
- master-02
- master-03
control-plane:
- master-01
- master-02
- master-03
worker:
- worker-01
controlPlaneEndpoint:
## Internal loadbalancer for apiservers
# internalLoadbalancer: haproxy
domain: lb.kubesphere.local
address: "192.168.17.200"
port: 6443
...
```
注意事项:请使用您自己的 VIP 地址来替换 `controlPlaneEndpoint.address` 的值。
如果想使用其他版本的docker,可以先安装docker后再使用kk安装集群。
Ref: [配置含义](https://www.kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/multioverview/#2-edit-the-configuration-file)
##### 4. 开始安装
```shell
./kk create cluster -f config-sample.yaml
```
##### 5. 验证安装
###### 5.1 看到以下信息时,表明高可用集群已成功创建
```shell
#####################################################
### Welcome to KubeSphere! ###
#####################################################
Console: http://192.168.17.110:30880
Account: admin
Password: P@88w0rd
NOTES:
1. After you log into the console, please check the
monitoring status of service components in
"Cluster Management". If any service is not
ready, please wait patiently until all components
are up and running.
2. Please change the default password after login.
#####################################################
https://kubesphere.io 2024-03-25 20:27:44
#####################################################
```
###### 5.2 运行以下命令以检查安装日志
```shell
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
```
**Ref**: [使用 Keepalived 和 HAproxy 创建高可用 Kubernetes 集群](https://www.kubesphere.io/zh/docs/v3.4/installing-on-linux/high-availability-configurations/set-up-ha-cluster-using-keepalived-haproxy/)
**Ref**: [使用 KubeKey 内置 HAproxy 创建高可用集群](https://www.kubesphere.io/zh/docs/v3.4/installing-on-linux/high-availability-configurations/internal-ha-configuration/)