一、介绍

1、k8s的node默认已经有高可用了,因为在pod会随机分配到各个node上,如果有pod挂了,就会分配到其他node上,所以这里主要是做一下master的高可用。

2、kube-controller-manager与kube-scheduler高可用
这两项服务是Master节点的一部分,他们的高可用相对容易,仅需要运行多份实例即可。这两项服务是有状态的服务,这些实例会通过向apiserver中的Endpoint加锁的方式来进行leader election, 当目前拿到leader的实例无法正常工作时,别的实例会拿到锁,变为新的leader。
这种选举操作是通过在kube-system名称空间中创建一个与程序同名的Endpoints资源对象来实现。各实例通过apiserver去获取endpoint的状态,通过竞争的方式去抢占指定的Endpoint资源锁,胜利者将成为leader。

[root@k8s-master-101 ~]# kubectl get endpoints -n kube-system  
NAME                      ENDPOINTS                           AGE
kube-controller-manager   <none>                              23d
kube-scheduler            <none>                              23d

#在搭建完后实验,一开始111这台master为leader,然后把111上的kube-controller关闭后可以看到101这台master变为了leader,实现了高可用。
[root@k8s-master-101 ~]# kubectl describe endpoints kube-controller-manager -n kube-system                                  Name:         kube-controller-manager
Namespace:    kube-system
Labels:       <none>
Annotations:  control-plane.alpha.kubernetes.io/leader:
                {"holderIdentity":"k8s-master-101_c6cd4e97-53ba-11e9-9694-000c293313a6","leaseDurationSeconds":15,"acquireTime":"2019-03-31T14:14:51Z","re...
Subsets:
Events:
  Type    Reason          Age   From                     Message
  ----    ------          ----  ----                     -------
  Normal  LeaderElection  34m   kube-controller-manager  k8s-master-111_3fa9e034-53ba-11e9-9ba6-000c29785034 became leader
  Normal  LeaderElection  29s   kube-controller-manager  k8s-master-101_c6cd4e97-53ba-11e9-9694-000c293313a6 became leader

kube-scheduler和controller-manager不需要做高可用,因为它们默认会通过选举产生,可以通过下面的命令查看:
在这里插入图片描述

3、apiserver的高可用也有三种基本思路:
一是使用外部负载均衡器,不管是使用公有云提供的负载均衡器服务或是在私有云中使用LVS或者HaProxy自建负载均衡器都可以归到这一类。 负载均衡器是非常成熟的方案,在这里略过不做过多介绍。如何保证负载均衡器的高可用,则是选择这一方案需要考虑的新问题。
二是在网络层做负载均衡。比如在Master节点上用BGP做ECMP,或者在Node节点上用iptables做NAT都可以实现。采用这一方案不需要额外的外部服务,但是对网络配置有一定的要求。
三是在Node节点上使用反向代理对多个Master做负载均衡。这一方案同样不需要依赖外部的组件,但是当Master节点有增减时,如何动态配置Node节点上的负载均衡器成为了另外一个需要解决的问题。

4、官方的master节点高可用架构
在这里插入图片描述
可以看出,用户通过kubectl发送命令经过LB进行负载均衡到后端的master上的apiserver,再由具体的某一个master进行向集群内部的节点的转发。
同理,节点也是通过LB进行负载均衡连接到master上的apiserver,去获取到apiserver中配置的信息。

5、其他高可用集群架构
在这里插入图片描述
可以看到,每一台node上都部署了 nginx做负载均衡到master的apiserver

二、高可用部署(node节点部署nginx代理方式)

将master节点扩展至2个,新增加的master的ip为:10.0.0.111
1、在原先的master上的server-csr.json中增加新增master的ip:
vim server-csr.json

[root@k8s-master-101 ssl]# cat server-csr.json 
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "10.10.10.1",
      "10.0.0.101",
      "10.0.0.102",
      "10.0.0.103",
      "10.0.0.111",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Shenzhen",
            "ST": "Guangzhou",
            "O": "k8s",
            "OU": "System"
        }
    ]
}

2、重新生成server证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

cp -p server-key.pem server.pem /opt/kubernetes/ssl/
systemctl restart kube-apiserver

3、将原先master上的/opt/kubernetes发送到新的master节点上:

scp -r /opt/kubernetes/ root@10.0.0.111:/opt

4、从原先的master上拷贝服务的配置文件到新的master上:

scp /usr/lib/systemd/system/{kube-apiserver,kube-scheduler,kube-controller-manager}.service root@10.0.0.111:/usr/lib/systemd/system/

5、修改新master节点上的kube-apiserver配置文件:
将advertise-address和bind-address改为新master本机的ip
vim /opt/kubernetes/cfg/kube-apiserver

[root@k8s-master-111 ~]# cat /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://10.0.0.101:2379,https://10.0.0.102:2379,https://10.0.0.103:2379 \
--insecure-bind-address=127.0.0.1 \
--bind-address=10.0.0.111 \
--insecure-port=8080 \
--secure-port=6443 \
--advertise-address=10.0.0.111 \
--allow-privileged=true \
--service-cluster-ip-range=10.10.10.0/24 \
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction --authorization-mode=RBAC,Node \
--kubelet-https=true \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/opt/kubernetes/ssl/server.pem  \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/server.pem \
--etcd-keyfile=/opt/kubernetes/ssl/server-key.pem"

6、启动服务

systemctl daemon-reload
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service

7、在新的master上使用kubectl查看集群中的节点:

echo PATH=$PATH:/opt/kubernetes/bin >> /etc/profile
source /etc/profile
kubectl get node

[root@k8s-master-111 ~]# kubectl get node
NAME         STATUS   ROLES    AGE   VERSION
10.0.0.102   Ready    <none>   23d   v1.12.2
10.0.0.103   Ready    <none>   23d   v1.12.2

三、node节点上

node节点配置
1、首先在两台node节点上安装nginx做4层负载均衡:
添加nginx源
vim /etc/yum.repos.d/nginx.repo

[root@k8s-node1-102 ~]# cat /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/\$basearch/
gpgcheck=0

yum install -y nginx

2、配置nginx:把对本机127.0.0.1:6443的请求代理到两个master几点的6443节点上
vim /etc/nginx/nginx.conf

[root@k8s-node1-102 ~]# cat /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
    access_log /var/log/nginx/k8s-access.log main;
    upstream k8s-apiserver {
        server 10.0.0.101:6443;
        server 10.0.0.111:6443;
    }
    server {
        listen 127.0.0.1:6443;
        proxy_pass k8s-apiserver;
    }
}

3、在node节点上修改bootstrap.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig中的apiserver地址为本地:server: https://127.0.0.1:6443,这样node节点向apiserver的请求会先发向本机127.0.0.1:6443,然后经过代理转发到两个master节点上的apiserver端口

cd /opt/kubernetes/cfg
ls *config | xargs -i sed -i 's/10.0.0.101/127.0.0.1/' {}

4、在node节点上重启服务

systemctl restart kubelet.service
systemctl restart kube-proxy.service

5、在node节点上启动nginx:

systemctl start nginx
systemctl enable nginx

6、查看一下nginx日志有没有代理记录:
tail /var/log/nginx/k8s-access.log
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐