Kubernetes master集群高可用

实现方案

Kubernetes master高可用一般有三种实现方案:

1. kubeadm 高可用安装使用kubeadm工具安装Kubernetes集群。通过增加master节点数量和指定vip实现master高可用。

具体步骤如下:

- 安装一主两备master节点(由kubeadm完成)

- 配置vip(使用keepalived或haproxy等工具)

- kubeadm join时指定apiserver-vip参数(kubeadm join ... --apiserver-advertise-address apiserver-vip)

- 各节点apiserver配置service-cluster-ip-range参数,指向vip这种方案简单易行,kubeadm帮助完成大部分复杂配置,但是控制面扩展性较差,可靠性依赖前端vip产品。

2. etcd集群 + apiserver高可用以etcd集群为后端存储,部署多个apiserver实例,并进行LB实现高可用。

具体步骤如下:

- 部署etcd集群(3个或5个节点)

- 多个master节点分别部署apiserver,指向etcd集群

扫描二维码关注公众号,回复: 16969259 查看本文章

- 使用LB(如nginx)反向代理apiserver,实现负载均衡这种方案扩展性好,控制面高可用性高,但是部署和配置比较复杂,依赖额外的LB设备。

3. 使用CSKU(企业版本Kubernetes)使用企业版本Kubernetes(如GKE),它自带 master高可用实现。通过在GKE控制台选择master节点数,与高可用特性,GKE将自动完成以下配置:

- 部署etcd集群

- 部署多个master副本

- 通过内置LB实现apiserver负载均衡这种方案最简单,完全由企业版本Kubernetes平台实现和运维,但是成本较高。

这里我将介绍前两种实现

方式一

1. 准备3台机器,配置主机名和hosts

master1

master2

master3

编辑所有节点的/etc/hosts,添加三节点映射: 

192.168.0.1 master1
192.168.0.2 master2
192.168.0.3 master3

2. 在所有的master节点安装kubeadm,kubelet和kubectl

apt install -y kubeadm kubelet kubectl

3. 指定vip(如10.0.0.10),在master1上使用keepalived配置,其他master节点配置keepalived backup

master1:

vrrp_instance VI_1 {
    state MASTER
    interface ens4
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.10
    }        
}

  其它master节点:

vrrp_instance VI_1 {
    state BACKUP 
    interface ens4 
    virtual_router_id 50
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111 
    }
    virtual_ipaddress {
        10.0.0.10
    }

4. 在所有节点初始化kubeadm配置文件

kubeadm config print init-defaults > kubeadm.yaml

修改kubeadm.yaml,指定apiserver地址为vip:

​apiVersion: kubeadm.k8s.io/v1beta2 
kind: InitConfiguration
localAPIEndpoint:
 advertiseAddress: "10.0.0.10"

5. 在master1节点执行kubeadm init,使用--config指定kubeadm.yaml文件

kubeadm init --config=kubeadm.yaml

6. 在其他master节点执行kubeadm join,同样指定apiserver-vip

kubeadm join 10.0.0.10:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:1234..cdef --apiserver-advertise-address=10.0.0.10

7. 将master节点的kubeconfig文件拷贝到其它节点至此,使用kubeadm工具部署的Kubernetes master高可用集群已完成!客户端只需要访问vip(10.0.0.10)即可,keepalived会自动将请求转发到可用的master节点。

        至此,使用kubeadm工具部署的Kubernetes master高可用集群已完成!客户端只需要访问vip(10.0.0.10)即可,keepalived会自动将请求转发到可用的master节点。这种方案简单易行,但是扩展性和可靠性略差,依赖第三方软件(如keepalived)实现LB和vip。但对测试和体验Kubernetes HA足以。

方式二

1. 准备3台机器作为etcd集群:

- etcd1:10.0.0.11
- etcd2:10.0.0.12
- etcd3:10.0.0.13

2. 在etcd1上部署etcd

etcd --name etcd1 \
 --listen-client-urls https://10.0.0.11:2379 \
 --advertise-client-urls https://10.0.0.11:2379 \
 --listen-peer-urls https://10.0.0.11:2380 \
 --initial-advertise-peer-urls https://10.0.0.11:2380 \
 --initial-cluster etcd1=https://10.0.0.11:2380,etcd2=https://10.0.0.12:2380,etcd3=https://10.0.0.13:2380 \
 --initial-cluster-token etcd-token

3. 在etcd2和etcd3节点也启动etcd,命令与etcd1相同,只是名称和地址不同

4. 准备3台master节点:master1,master2,master3

5.所有master节点安装kube-apiserver、kube-controller-manager和kube-scheduler

6. 配置kube-apiserver

- --etcd-servers: 指定etcd集群地址

- --service-cluster-ip-range: 指定Cluster IP地址段

- --secure-port: apiserver端口(如6443)

- 其它参数参考 [kube-apiserver配置文档]( kube-apiserver | Kubernetes)

master1例如:

kube-apiserver --etcd-servers=https://10.0.0.11:2379,https://10.0.0.12:2379,https://10.0.0.13:2379  --service-cluster-ip-range=10.0.0.0/24 --secure-port=6443 ​-bind-address=10.0.0.11  ...

master2,master3...也类似,修改bind-address为对应节点IP

7. 配置反向代理(如nginx)实现kube-apiserver高可用负载均衡

upstream kube-apiserver { 
    server 10.0.0.11:6443; 
    server 10.0.0.12:6443; 
    server 10.0.0.13:6443; 

server {
    listen 6443; 
    proxy_pass http://kube-apiserver; 
}

8. 其他master组件连接nginx的6443端口在

所有master节点:

kube-controller-manager --master=http://10.0.0.11:6443 ...
kube-scheduler --master=http://10.0.0.11:6443 ...

9. Node节点kubelet连接nginx的6443端口

10. kubectl客户端也连接nginx的6443端口至此,实现了高可用的多master控制面,具有高扩展性和高可用性。etcd本身作为Kubernetes的关键存储也具备高可用,nginx实现简单可靠的LB。

        这种方案设计得较为复杂,但是更加灵活可靠。适用于大型产品级Kubernetes集群,可以根据需要扩展apiserver和etcd节点。也是实际Kubernetes控制面部署的经典模式。

访问集群方式

访问Kubernetes高可用集群,有以下几种方式:

1. kubectl客户端 connects 到nginx的6443端口,nginx会自动将请求转发到可用的kube-apiserver实例上。
所以,您只需要将kubectl指向任一master节点的6443端口即可:

kubectl --server=https://10.0.0.11:6443 get nodes

2. API Server Endpoint对外暴露的API Server Endpoint也是nginx的6443端口,所以调用Kubernetes API可以像这样:

curl https://10.0.0.11:6443/api/v1/nodes 

3. DNS在Kubernetes集群内部,kube-dns会解析kubernetes.default.svc.cluster.local到nginx的6443端口。
所以在集群内的Pod也可以通过该DNS名称访问API Server。

4. Service可以在集群内创建kubernetes服务,将类型设置为NodePort或LoadBalancer,开放6443端口,对外提供访问入口。
例如:

yaml
apiVersion: v1
kind: Service
metadata:
  name: kubernetes
spec:
  type: NodePort
  ports:
  - port: 6443
    targetPort: 6443
    protocol: TCP
  selector:
    component: apiserver 

        创建该服务后,外部可以通过Node的ANY IP:31643端口访问(31643是随机分配的端口)。

        以上就是几种访问Kubernetes高可用集群的方法。总体来说,对内可以直接使用kubernetes服务域名(推荐);对外可以通过NodePort服务或直接通过nginx的6443端口调用API(适用于测试)。

        在日常使用中,kubectl命令行工具是最常用的方式。只需要在每个节点安装kubectl,并指定正确的apiserver地址即可使用。 

相关延申

keepalived

        这里最重要的是VRRP虚拟IP,VRRP虚拟IP(Virtual Router Redundancy Protocol Virtual IP)是keepalived实现高可用的关键概念。

它是一个浮动的IP地址,可以在keepalived集群中的主节点和备节点之间漂移。客户端并不直接连接主节点或备节点,而是连接这个虚拟IP。

当主节点出现故障时,VRRP虚拟IP会从主节点漂移到备节点,客户端连接的IP地址不变,实现了业务的故障切换。VRRP虚拟IP具有以下特征:

1. 它是一个逻辑IP,并不对应于主节点或备节点的物理IP地址。

2. 它会在keepalived主节点和备节点之间漂移,实现高可用。

3. 客户端只关注VRRP虚拟IP,不需要关心主节点或备节点的物理IP地址。

4. VRRP虚拟IP的MAC地址会随着IP漂移而改变,交换机会更新MAC表,无需人工干预。

5. 一个VRRP实例可以有多个VRRP虚拟IP,所有的虚拟IP会同时漂移。

6. VRRP虚拟IP所在的子网需要在主节点和备节点的网卡上都有配置。

VRRP虚拟IP是keepalived实现高可用的基石,当主节点出现故障,它实现了与备节点的无缝切换,为客户端提供了一个逻辑的浮动入口IP,自动实现了故障转移,这也是VRRP协议的初衷。

综上,VRRP虚拟IP的主要作用是:

- 为客户端提供一个逻辑入口IP

- 实现与备节点的故障切换

- 隐藏集群主节点与备节点的物理IP地址

- 简化客户端的配置

ngnix方式

nginx大家都很熟悉,反向代理服务器,暴露一个端口根据上下文负载均衡所有master节点地址

kubectl

kubectl是k8s的请求客户端命令,kubectl命令内部根据命令带的参数信息封装了个 restful http请求,向kube-apiserver发送请求。接下来列举几个命令的实际http请求的对应请求:

获取Pod列表:

GET /api/v1/namespaces/{namespace}/pods 

创建Pod:

POST /api/v1/namespaces/{namespace}/pods

获取Service列表:

GET /api/v1/namespaces/{namespace}/services

创建Service:

POST /api/v1/namespaces/{namespace}/services

获取Deployment列表:

GET /apis/apps/v1/namespaces/{namespace}/deployments 

创建Deployment:

POST /apis/apps/v1/namespaces/{namespace}/deployments

获取Node列表:

GET /api/v1/nodes

获取Namespace列表: 

GET /api/v1/namespaces

创建Namespace:

POST /api/v1/namespaces  

获取Secret列表: 

GET /api/v1/namespaces/{namespace}/secrets 

创建Secret:

POST /api/v1/namespaces/{namespace}/secrets    

获取ConfigMap列表:

GET /api/v1/namespaces/{namespace}/configmaps  

创建ConfigMap:

POST /api/v1/namespaces/{namespace}/configmaps  

执行kubectl exec:

POST /api/v1/namespaces/{namespace}/pods/{pod}/exec

执行yaml文件的apply or create命令

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"apiVersion":"v1", "kind":"Pod"...}'  https://10.0.0.1:6443/api/v1/namespaces/default/pods

这些只是常见API的一部分,kubectl封装的API还有非常多,它通过构建不同的HTTP请求,以RESTful API风格与Kubernetes API Server进行交互,从而实现所有kubectl的功能。

猜你喜欢

转载自blog.csdn.net/qq_40322236/article/details/130990563