天天看點

Kubernetes 之 master高可用叢集搭建

1

介紹

k8s的node預設已經有高可用了,因為在pod會随機配置設定到各個node上,如果有pod挂了,就會配置設定到其他node上,是以這裡主要是做一下master的高可用

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不需要做高可用,因為它們預設會通過選舉産生。

2

apiserver的高可用也有三種基本思路:

一是使用外部負載均衡器。不管是使用公有雲提供的負載均衡器服務或是在私有雲中使用LVS或者HaProxy自建負載均衡器都可以歸到這一類。 負載均衡器是非常成熟的方案,在這裡略過不做過多介紹。如何保證負載均衡器的高可用,則是選擇這一方案需要考慮的新問題。

二是在網絡層做負載均衡。比如在Master節點上用BGP做ECMP,或者在Node節點上用iptables做NAT都可以實作。采用這一方案不需要額外的外部服務,但是對網絡配置有一定的要求。

三是在Node節點上使用反向代理對多個Master做負載均衡。這一方案同樣不需要依賴外部的元件,但是當Master節點有增減時,如何動态配置Node節點上的負載均衡器成為了另外一個需要解決的問題。

3

官方的master節點高可用架構

Kubernetes 之 master高可用叢集搭建

可以看出,使用者通過kubectl發送指令經過LB進行負載均衡到後端的master上的apiserver,再由具體的某一個master進行向叢集内部的節點的轉發。

同理,節點也是通過LB進行負載均衡連接配接到master上的apiserver,去擷取到apiserver中配置的資訊。

4

其他高可用叢集架構

Kubernetes 之 master高可用叢集搭建

可以看到,每一台node上都部署了 nginx做負載均衡到master的apiserver。

高可用部署(node節點部署nginx代理方式)

将master節點擴充至2個,新增加的master的ip為:10.0.0.111

在原先的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"

       }

    ]

}

重新生成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

将原先master上的/opt/kubernetes發送到

新的master節點上:

scp -r /opt/kubernetes/ [email protected]:/opt

從原先的master上拷貝服務的配置檔案到

新的master上:

scp /usr/lib/systemd/system/{kube-apiserver,kube-scheduler,kube-controller-manager}.service [email protected]:/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-reloadsystemctl 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節點上

安裝nginx做4層負載均衡:

添加nginx源

vim /etc/yum.repos.d/nginx.repo

[root@k8s-node1-102 ~]# cat /etc/yum.repos.d/nginx.repo

[nginx]

name=nginx 

repobaseurl=http://nginx.org/packages/centos/7/\$basearch/

gpgcheck=0

yum install -y nginx

配置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;

    }

在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/' {}

在node節點上重新開機服務

systemctl restart kubelet.service

systemctl restart kube-proxy.service

在node節點上啟動nginx:

systemctl start nginx

systemctl enable nginx

檢查nginx日志有沒有代理記錄:

Kubernetes 之 master高可用叢集搭建