開發與維運

二進制安裝k8s超詳細版本-V1.20

一、環境說明

此環境下需要6臺主機,主機地址和角色如下表所示:

主機名

IP地址

集群角色

master1

172.16.213.225

k8s master1

master2

172.16.213.229

k8s master2

master3

172.16.213.230

k8s master3

node1

172.16.213.231

k8s slave1

node2

172.16.213.235

k8s slave2

lbserver

172.16.213.236

k8s master vip

 

在這個環境中,k8s集群我們採用三個master節點,兩個node節點,其中,三個master節點通過haproxy實現k8s-api的負載均衡。

二、系統基礎配置

1、內核升級

k8s在較低內核中存在某些bug,因此需要先升級下系統內核。建議使用4.10或以上版本內核,在master1/2/3和node1/2主機上依次執行如下操作,升級過程如下:

 

#升級內核:

[root@master1 kernel]#  wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-5.10.3-1.el7.elrepo.x86_64.rpm

[root@master1 kernel]#  wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-devel-5.10.3-1.el7.elrepo.x86_64.rpm

[root@master1 kernel]#  yum -y install kernel-ml-5.10.3-1.el7.elrepo.x86_64.rpm  kernel-ml-devel-5.10.3-1.el7.elrepo.x86_64.rpm

 

# 調整默認內核啟動

[root@master1 kernel]# cat /boot/grub2/grub.cfg |grep menuentry

[root@master1 kernel]# grub2-set-default "CentOS Linux (5.10.3-1.el7.elrepo.x86_64) 7 (Core)"

 

# 檢查是否修改正確

[root@master1 kernel]# grub2-editenv list

[root@master1 kernel]# reboot

2、開啟IPVS支持

內核升級完成後,首先確認內核版本是否正確,執行如下命令;

[root@master1 kernel]# uname  -a

接著,創建/etc/sysconfig/modules/ipvs.modules文件,內容如下:

#!/bin/bash

ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"

for kernel_module in ${ipvs_modules}; do

  /sbin/modinfo -F filename ${kernel_module} > /dev/null 2>&1

  if [ $? -eq 0 ]; then

    /sbin/modprobe ${kernel_module}

  fi

done

 

最後,執行如下命令使配置生效:

[root@master1 kernel]# chmod 755 /etc/sysconfig/modules/ipvs.modules

[root@master1 kernel]# sh /etc/sysconfig/modules/ipvs.modules

[root@master1 kernel]# lsmod | grep ip_vs

如果執行lsmod命令能看到ip_vs相關模塊信息,表明ipvs開啟成功。

3、關閉防火牆、swap設置

K8s集群每個節點都需要關閉防火牆,執行如下操作:

[root@master1 kernel]# systemctl stop firewalld && systemctl disable firewalld

[root@master1 kernel]# setenforce 0

[root@master1 kernel]# sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

 

接著,還需要關閉系統的交換分區,執行如下命令:

[root@master1 kernel]# swapoff -a

[root@master1 kernel]# cp /etc/fstab  /etc/fstab.bak

[root@master1 kernel]# cat /etc/fstab.bak | grep -v swap > /etc/fstab

 

然後,還需要修改iptables設置,在/etc/sysctl.conf中添加如下內容:

vm.swappiness = 0

net.bridge.bridge-nf-call-iptables = 1

net.ipv4.ip_forward = 1

net.bridge.bridge-nf-call-ip6tables = 1

最後,執行如下命令,以使設置生效:

[root@master1 kernel]# sysctl -p

 

 

4、主機免密鑰登錄

免密鑰登錄不是必須的,配置免密鑰是為了後面在節點之間拷貝數據方便,在任意一個master主機上設置到其它所有集群節點的無密碼登錄,這裡選擇master1節點,操作過程如下:

[root@master1 ~]# ssh-keygen

[root@master1 ~]# ssh-copy-id [email protected]

[root@master1 ~]# ssh-copy-id [email protected]

[root@master1 ~]# ssh-copy-id [email protected]

[root@master1 ~]# ssh-copy-id [email protected]

[root@master1 ~]# ssh-copy-id [email protected]

[root@master1 ~]# ssh-copy-id [email protected]

 

配置完成,在master1節點進行無密碼登錄其它節點的測試,看是否有問題。

 

5、主機名解析配置

每個主機的主機名以及IP地址都在上面環境介紹中給出來了,根據這些信息,在每個k8s集群節點添加如下主機名解析信息,將這些信息添加到每個集群節點的/etc/hosts文件中,主機名解析內容如下:

172.16.213.225  master1

172.16.213.229  master2

172.16.213.230  master3

172.16.213.231  node1

172.16.213.235  node2

172.16.213.236  lbserver

 

三、給k8s組件簽發證書

1、獲取證書籤發工具

這裡我們需要用到用到cfssl工具和cfssljson工具,下面簡單介紹下CFSSL,CFSSL是一款開源的PKI/TLS工具。 CFSSL包含一個命令行工具和一個用於簽名、驗證並且捆綁TLS證書的HTTP API服務。 使用Go語言編寫。

CFSSL包括:

一組用於生成自定義TLS PKI的工具

cfssl程序,是CFSSL的命令行工具

multirootca程序是可以使用多個簽名密鑰的證書頒發機構服務器

mkbundle程序用於構建證書池

cfssljson程序,從cfssl和multirootca程序獲取JSON輸出,並將證書,密鑰,CSR和bundle寫入磁盤

這裡我們只用到cfssl和cfssljson工具,大家可從https://github.com/cloudflare/cfssl/releases/下載相應的版本,這裡我下載的是1.5.0版本。

 

[root@master1 setup]# https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64

[root@master1 setup]# https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64

[root@master1 setup]# mv cfssl_1.5.0_linux_amd64  /usr/local/bin/cfssl

[root@master1 setup]# mv cfssljson_1.5.0_linux_amd64 /usr/local/bin/cfssljson

接下來,就可以簽發證書了,需要簽發證書的組件有admin用戶、kube-controller-manager、kubelet、kube-proxy、kube-scheduler和kube-api。

2、創建CA證書

(1)、創建證書生成策略文件

配置證書生成策略,讓CA軟件知道頒發有什麼功能的證書。先創建一個json格式文件ca-config.json,內容如下:

[root@master1 k8s]# cat ca-config.json

{

  "signing": {

    "default": {

      "expiry": "87600h"

    },

    "profiles": {

      "kubernetes": {

        "usages": ["signing", "key encipherment", "server auth", "client auth"],

        "expiry": "87600h"

      }

    }

  }

} 

這個策略,有一個default默認的配置,和一個profiles,profiles可以設置多個profile,這裡的profile是etcd。

default默認策略,指定了證書的默認有效期是一年(8760h)。

kubernetes:表示該配置(profile)的用途是為kubernetes生成證書及相關的校驗工作。

signing:表示該證書可用於簽名其它證書;生成的 ca.pem 證書中 CA=TRUE。

server auth:表示可以用該CA 對 server 提供的證書進行驗證。

client auth:表示可以用該 CA 對 client 提供的證書進行驗證。

expiry:也表示過期時間,如果不寫以default中的為準。

這裡將證書有效期設置為10年。

(2)、創建CA證書籤名請求文件

創建一個json格式文件ca-csr.json,內容如下:

[root@master1 k8s]# cat ca-csr.json

{

  "CN": "Kubernetes",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "iivey",

      "OU": "CA",

      "ST": "shaanxi"

    }

  ]

}

參數含義如下:

Ø CN: Common Name,瀏覽器使用該字段驗證網站是否合法,一般寫的是域名。非常重要。

Ø key:生成證書的算法

Ø hosts:表示哪些主機名(域名)或者IP可以使用此csr申請的證書,為空或者""表示所有的都可以使用(本例中沒有hosts字段)

Ø names:一些其它的屬性

² C: Country, 國家

² ST: State,州或者是省份

² L: Locality Name,地區,城市

² O: Organization Name,組織名稱,公司名稱(在k8s中常用於指定Group,進行RBAC綁定)

² OU: Organization Unit Name,組織單位名稱,公司部門

在這個文件中,可根據情況進行地域、國家的修改。

(3)、產生CA證書文件

執行如下命令:

[root@master1 k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca

其中,幾個參數功能如下:

Ø gencert: 生成新的key(密鑰)和簽名證書

² -initca:初始化一個新ca

該命令會生成運行CA所必需的文件ca-key.pem(私鑰)和ca.pem(證書),還會生成ca.csr(證書籤名請求),用於交叉簽名或重新簽名接著,查看產生的證書文件:

[root@master1 k8s]#  ls -al ca*.pem

-rw-------  1 root root 1675 Mar 23 11:04 ca-key.pem

-rw-r--r--  1 root root 1314 Mar 23 11:04 ca.pem

這兩個文件就是我們需要的證書文件。如果要查看cert(證書信息),可執行如下命令:

[root@master1 k8s]# cfssl certinfo -cert ca.pem

要查看CSR(證書籤名請求)信息,可執行如下文件:

[root@master1 k8s]# cfssl certinfo -csr ca.csr

3、創建admin用戶證書

(1)、創建證書籤名請求配置文件

創建一個json格式文件admin-csr.json,內容如下:

[root@master1 k8s]# cat  admin-csr.json

{

  "CN": "admin",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "system:masters",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

 

(2)、創建admin用戶證書並校驗結果

首先創建admin證書,執行如下命令:

[root@master1 k8s]# cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  admin-csr.json | cfssljson -bare admin

其中,每個參數含義如下:

Ø gencert: 生成新的key(密鑰)和簽名證書

² -initca:初始化一個新ca

² -ca:指明ca的證書

² -ca-key:指明ca的私鑰文件

² -config:指明請求證書的json文件

² -profile:與-config中的profile對應,是指根據config中的profile段來生成證書的相關信息

接著,查看產生的證書文件:

[root@master1 k8s]# ls -al admin*.pem

-rw------- 1 root root 1675 Dec  2 10:12 admin-key.pem

-rw-r--r-- 1 root root 1411 Dec  2 10:12 admin.pem

這兩個就是需要的證書文件。

4、創建kubelet證書

Kubelet證書主要是在node節點使用的,這裡我們有node1、node2兩個節點,因此需要創建兩個節點的Kubelet證書,為了方便起見,這裡通過一個腳本一次性實現兩個節點證書的創建,腳本generate-kubelet-certificate.sh內容如下:

[root@master1 k8s]# more generate-kubelet-certificate.sh

IFS=$'\n'

for line in `cat node.txt`; do

 

instance=`echo $line | awk '{print $1}'`

INTERNAL_IP=`echo $line | awk '{print $2}'`

 

cat > ${instance}-csr.json <<EOF

{

  "CN": "system:node:${instance}",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "system:nodes",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

EOF

 

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -hostname=${instance},${INTERNAL_IP} \

  -profile=kubernetes \

  ${instance}-csr.json | cfssljson -bare ${instance}

done

其中,node.txt文件內容如下:

[root@master1 k8s]# cat node.txt

node1   172.16.213.231

node2   172.16.213.235

執行generate-kubelet-certificate.sh這個腳本,會生成node1、node2兩個節點的證書文件。

[root@master1 k8s]# ll node*.pem

-rw------- 1 root root 1679 Dec  2 10:41 node1-key.pem

-rw-r--r-- 1 root root 1464 Dec  2 10:41 node1.pem

-rw------- 1 root root 1675 Dec  2 10:41 node2-key.pem

-rw-r--r-- 1 root root 1464 Dec  2 10:41 node2.pem

5、創建Controller Manager客戶端證書

Controller Manager證書是在master節點,為了方便起見,我們通過一個腳本來自動完成證書的創建,腳本kube-controller-manager.sh內容如下:

[root@master1 k8s]# more kube-controller-manager.sh

cat > kube-controller-manager-csr.json <<EOF

{

  "CN": "system:kube-controller-manager",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "system:kube-controller-manager",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

EOF

 

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

執行kube-controller-manager.sh這個腳本,會生成兩個證書文件。

[root@master1 k8s]# ll kube-controller-manager*.pem

-rw------- 1 root root 1679 Dec  2 10:43 kube-controller-manager-key.pem

-rw-r--r-- 1 root root 1468 Dec  2 10:43 kube-controller-manager.pem

6、創建Kube Proxy客戶端證書

Kube Proxy證書是在master節點,為了方便起見,我們通過一個腳本來自動完成證書的創建,腳本kubeproxy.sh內容如下: 

cat > kube-proxy-csr.json <<EOF

{

  "CN": "system:kube-proxy",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "system:node-proxier",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

EOF

 

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-proxy-csr.json | cfssljson -bare kube-proxy

執行kubeproxy.sh這個腳本,會生成兩個證書文件。

[root@master1 k8s]# ll kube-proxy*.pem

-rw------- 1 root root 1675 Dec  2 10:45 kube-proxy-key.pem

-rw-r--r-- 1 root root 1436 Dec  2 10:45 kube-proxy.pem

7、創建Scheduler 客戶端證書

Kube Scheduler證書是在master節點,為了方便起見,我們通過一個腳本來自動完成證書的創建,腳本kubescheduler.sh內容如下:

 

[root@master1 k8s]# more kubescheduler.sh

cat > kube-scheduler-csr.json <<EOF

{

  "CN": "system:kube-scheduler",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "system:kube-scheduler",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

EOF

 

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-scheduler-csr.json | cfssljson -bare kube-scheduler

執行kubescheduler.sh這個腳本,會生成兩個證書文件。

[root@master1 k8s]#  ll kube-scheduler*.pem

-rw------- 1 root root 1679 Dec  2 10:47 kube-scheduler-key.pem

-rw-r--r-- 1 root root 1444 Dec  2 10:47 kube-scheduler.pem

8、創建Kuberenetes API證書

kube-api服務器證書主機名應該包含所有控制器的主機名和IP、負載均衡器的主機名和IP、kubernetes服務以及localhost。

為了方便起見,我們通過一個腳本來自動完成證書的創建,腳本kubeapi.sh內容如下:

CERT_HOSTNAME=10.100.0.1,master1,172.16.213.225,master2,172.16.213.229,master3,172.16.213.230,lbserver,172.16.213.236,127.0.0.1,localhost,kubernetes.default

cat > kubernetes-csr.json <<EOF

{

  "CN": "kubernetes",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "Kubernetes",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

 

EOF

 

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -hostname=${CERT_HOSTNAME} \

  -profile=kubernetes \

  kubernetes-csr.json | cfssljson -bare kubernetes

 

注意,此腳本中,CERT_HOSTNAME的內容,需要修改為你環境下的主機名和IP地址。

執行kubeapi.sh這個腳本,會生成兩個證書文件。

[root@master1 k8s]# ll kubernetes*.pem

-rw------- 1 root root 1679 Dec  3 17:45 kubernetes-key.pem

-rw-r--r-- 1 root root 1574 Dec  3 17:45 kubernetes.pem

9、創建服務帳戶密鑰對

服務帳戶密鑰對用來簽署服務帳戶的token,為了方便起見,我們通過一個腳本來自動完成證書的創建,腳本servicesaccount.sh內容如下:

[root@master1 k8s]# cat servicesaccount.sh

cat > service-account-csr.json  <<EOF

{

  "CN": "service-accounts",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "L": "xian",

      "O": "Kubernetes",

      "OU": "Kubernetes The Hard Way",

      "ST": "shaanxi"

    }

  ]

}

EOF

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  service-account-csr.json | cfssljson -bare service-account

執行servicesaccount.sh這個腳本,會生成兩個證書文件。

[root@master1 k8s]# ll service-account*.pem

-rw------- 1 root root 1679 Dec  3 17:46 service-account-key.pem

-rw-r--r-- 1 root root 1424 Dec  3 17:46 service-account.pem

10、複製證書到對應節點

基礎證書到此已經基本創建完成了,接下來要將證書傳到集群的相應節點上,為了方便起見,通過一個腳本來完成證書的傳輸,腳本scp1.sh的內容如下:

[root@master1 k8s]# cat scp1.sh

IFS=$'\n'

for line in `cat node.txt`; do

   instance=`echo $line | awk '{print $1}'`

   rsync -azvp ca.pem ${instance}-key.pem ${instance}.pem root@${instance}:/root/

done

 

for instance in master1 master2 master3; do

   rsync -avpz ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem service-account-key.pem service-account.pem root@${instance}:/root/

done

 

注意,此腳本是將k8s集群兩個node節點的證書傳到對應node主機上,然後將ca證書、kube-api證書以及service-account證書傳到三個master節點上。

其中,腳本中的node.txt文件內容如下:

[root@master1 k8s]# more node.txt

node1   172.16.213.231

node2   172.16.213.235

 

四、給k8s組件創建kubeconfig

kubeconfig是kubernetes集群中各個組件連入api-server的時候, 使用的客戶端配置文件。用於配置集群訪問的文件稱為kubeconfig文件。這是引用配置文件的通用方法。這並不意味著有一個名為 kubeconfig 的文件。

使用 kubeconfig 文件來組織有關集群、用戶、命名空間和身份認證機制的信息。kubectl 命令行工具使用 kubeconfig 文件來查找選擇集群所需的信息,並與集群的 API 服務器進行通信。

默認情況下,kubectl 在 $HOME/.kube 目錄下查找名為 config 的文件。 我們也可以通過設置 KUBECONFIG 環境變量或者設置--kubeconfig參數來指定其他 kubeconfig 文件。

 

本文中我們將生成多個組件的kubeconfig,分別是kubelet kubeconfig、kube Proxy kubeconfig、Controller Manager kubeconfig、Kube Scheduler kubeconfig、`admin`用戶的kubeconfig。

1、 生成kubelet的kubeconfig

首先需要安裝kubectl,這是管理k8s的一個客戶端工具,下載地址如下:

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#downloads-for-v1204

這裡下載的kubernetes版本為kubernetes-server-linux-amd64.tar.gz,建議下載二進制的server版本,這樣下載後,解壓即可使用。將上面這個壓縮包解壓,得到kubernetes/server/bin這個路徑,就可以找到一個二進制文件kubectl,將這個文件拷貝到master節點的/usr/local/bin目錄下即可。此步驟需要在三個master節點進行,基本操作過程如下:

[root@master1 bin]# chmod 755 kubectl

[root@master1 bin]# cp kubectl /usr/local/bin

[root@master1 bin]# scp kubectl  master2:/usr/local/bin

[root@master1 bin]# scp kubectl  master3:/usr/local/bin

kubectl文件拷貝完成,接下來就可以生成kubeconfig文件了,為了方便起見,仍然使用一個腳本kubelet.sh完成,腳本內容如下:

[root@master1 k8s]# more kubelet.sh  

IFS=$'\n'

for instance in node1 node2; do

# 設置集群參數

  kubectl config set-cluster kubernetes-the-hard-way \

    --certificate-authority=ca.pem \

    --embed-certs=true \

    --server=https://172.16.213.236:6443 \

    --kubeconfig=${instance}.kubeconfig

# 設置客戶端認證參數

  kubectl config set-credentials system:node:${instance} \

    --client-certificate=${instance}.pem \

    --client-key=${instance}-key.pem \

    --embed-certs=true \

    --kubeconfig=${instance}.kubeconfig

# 設置上下文參數

  kubectl config set-context default \

    --cluster=kubernetes-the-hard-way \

    --user=system:node:${instance} \

    --kubeconfig=${instance}.kubeconfig

# 設置默認上下文

  kubectl config use-context default --kubeconfig=${instance}.kubeconfig

done

此段配置中,主要有三個方面的配置,分別是:

(1)、集群參數

本段設置了所需要訪問的集群的信息。使用set-cluster設置了需要訪問的集群,如上為kubernetes-the-hard-way,這只是個名稱,實際為--server指向的apiserver,--certificate-authority設置了該集群的公鑰,--embed-certs為true表示將--certificate-authority證書寫入到kubeconfig中;--server則表示該集群的kube-apiserver地址。

注意,這裡--server指定的apiserver地址是個負載均衡的地址,因為此環境是三個master節點的集群環境,所以要指向負載均衡器的IP地址。關於負載均衡器的配置,將在下面做具體介紹。

生成的kubeconfig 如果不指定路徑,默認被保存到 ~/.kube/config 文件,而上面的配置中,我們指定的路徑是當前目錄,所以會在當前目錄下生成kubeconfig文件。

(2)、客戶端參數

本段主要設置客戶端的相關信息,注意客戶端的證書首先要經過集群CA的簽署,否則不會被集群認可。此處使用的是ca認證方式,也可以使用token認證. 

(3)、上下文參數

集群參數和用戶參數可以同時設置多對,在上下文參數中將集群參數和用戶參數關聯起來。上面的上下文名稱為default,--cluster為kubernetes-the-hard-way,用戶為system:node:${instance},表示使用system:node的用戶憑證來訪問kubernetes-the-hard-way集群的default命名空間,也可以增加--namspace來指定訪問的命名空間。

 

最後使用kubectl config use-context default 來使用名為default的環境項來作為配置。如果配置了多個環境項,可以通過切換不同的環境項名字來訪問到不同的集群環境。

執行kubelet.sh腳本,就會生成兩個node節點的kubeconfig文件,操作如下:

[root@master1 k8s]# sh kubelet.sh

[root@master1 k8s]# ll node*.kubeconfig

-rw------- 1 root root 6314 Dec  2 16:22 node1.kubeconfig

-rw------- 1 root root 6310 Dec  2 16:22 node2.kubeconfig

2、生成kube-proxy 的kubeconfig

為了方便起見,仍然使用一個腳本kube-proxy.sh完成,腳本內容如下:

kubectl config set-cluster kubernetes-the-hard-way \

    --certificate-authority=ca.pem \

    --embed-certs=true \

    --server=https://172.16.213.236:6443 \

    --kubeconfig=kube-proxy.kubeconfig

 

kubectl config set-credentials system:kube-proxy \

    --client-certificate=kube-proxy.pem \

    --client-key=kube-proxy-key.pem \

    --embed-certs=true \

    --kubeconfig=kube-proxy.kubeconfig

 

kubectl config set-context default \

    --cluster=kubernetes-the-hard-way \

    --user=system:kube-proxy \

    --kubeconfig=kube-proxy.kubeconfig

 

kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

 

腳本的內容不再解釋,跟kubelet.sh腳本中的參數含義基本相同,執行此腳本,會生成kube-proxy的kubeconfig文件,操作如下:

[root@master1 k8s]# sh kube-proxy.sh   

[root@master1 k8s]# ll kube-proxy*.kubeconfig

-rw------- 1 root root 6274 Dec  2 16:27 kube-proxy.kubeconfig

3、創建kue-controller-manager kubeconfig

為了方便起見,仍然使用一個腳本kube-controllermanager.sh完成,腳本內容如下:

[root@master1 k8s]# vi kube-controllermanager.sh

kubectl config set-cluster kubernetes-the-hard-way \

    --certificate-authority=ca.pem \

    --embed-certs=true \

    --server=https://127.0.0.1:6443 \

    --kubeconfig=kube-controller-manager.kubeconfig

 

kubectl config set-credentials system:kube-controller-manager \

    --client-certificate=kube-controller-manager.pem \

    --client-key=kube-controller-manager-key.pem \

    --embed-certs=true \

    --kubeconfig=kube-controller-manager.kubeconfig

 

kubectl config set-context default \

    --cluster=kubernetes-the-hard-way \

    --user=system:kube-controller-manager \

    --kubeconfig=kube-controller-manager.kubeconfig

 

kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig

執行此腳本,會生成kube-proxy的kubeconfig文件,操作如下:

[root@master1 k8s]#  sh kube-controllermanager.sh

[root@master1 k8s]# ll kube-controller-manager*.kubeconfig

-rw------- 1 root root 6343 Dec  2 17:51 kube-controller-manager.kubeconfig

4、生成kube-scheduler kubeconfig

為了方便起見,仍然使用一個腳本kube-scheduler.sh完成,腳本內容如下:

[root@master1 k8s]# cat kube-scheduler.sh

kubectl config set-cluster kubernetes-the-hard-way \

    --certificate-authority=ca.pem \

    --embed-certs=true \

    --server=https://127.0.0.1:6443 \

    --kubeconfig=kube-scheduler.kubeconfig

 

kubectl config set-credentials system:kube-scheduler \

    --client-certificate=kube-scheduler.pem \

    --client-key=kube-scheduler-key.pem \

    --embed-certs=true \

    --kubeconfig=kube-scheduler.kubeconfig

kubectl config set-context default \

    --cluster=kubernetes-the-hard-way \

    --user=system:kube-scheduler \

    --kubeconfig=kube-scheduler.kubeconfig

 

kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig

 

執行此腳本,會生成kube-scheduler的kubeconfig文件,操作如下:

[root@master1 k8s]# sh kube-scheduler.sh

[root@master1 k8s]# ll kube-scheduler*.kubeconfig

-rw------- 1 root root 6293 Dec  2 16:54 kube-scheduler.kubeconfig

5、生成admin的kubeconfig

為了方便起見,仍然使用一個腳本admin.sh完成,腳本內容如下:

[root@master1 k8s]# cat admin.sh

kubectl config set-cluster kubernetes-the-hard-way \

    --certificate-authority=ca.pem \

    --embed-certs=true \

    --server=https://127.0.0.1:6443 \

    --kubeconfig=admin.kubeconfig

 

kubectl config set-credentials admin \

    --client-certificate=admin.pem \

    --client-key=admin-key.pem \

    --embed-certs=true \

    --kubeconfig=admin.kubeconfig

 

kubectl config set-context default \

    --cluster=kubernetes-the-hard-way \

    --user=admin \

    --kubeconfig=admin.kubeconfig

 

kubectl config use-context default --kubeconfig=admin.kubeconfig

執行此腳本,會生成admin的kubeconfig文件,操作如下:

[root@master1 k8s]# sh admin.sh

[root@master1 k8s]# ll admin.kubeconfig

-rw------- 1 root root 6213 Dec  2 16:55 admin.kubeconfig

6、創建通信加密文件

Kubernetes支持集群數據加密。在下面操作中,我們將生成一個加密密鑰和加密配置來加密Kubernetes靜態Secret數據。

這裡仍然通過一個腳本encryption-config.sh來完成,腳本內容如下:

[root@master1 ~]# more encryption-config.sh

cat > encryption-config.yaml <<EOF

kind: EncryptionConfig

apiVersion: v1

resources:

  - resources:

      - secrets

    providers:

      - aescbc:

          keys:

            - name: key1

              secret: $(head -c 32 /dev/urandom | base64)

      - identity: {}

EOF

執行這個腳本,然後會生成一個文件encryption-config.yaml,此文件需要複製到三個master節點。

7、拷貝kubeconfig到集群節點

到這裡為止,所需要的證書、kubeconfig文件已經全部生成完畢,接下來需要將這些文件拷貝到集群對應的主機上。

首先需要將kube-proxy.kubeconfig以及${node}.kubeconfig拷貝到集群的兩個work節點,接著將admin.kubeconfig、kube-controller-manager.kubeconfig、kube-scheduler.kubeconfig、encryption-config.yaml拷貝到k8s集群的三個master節點,這通過一個腳本即可完成,腳本kubeconfig-scp.sh內容如下:

[root@master1 k8s]# more kubeconfig-scp.sh 

IFS=$'\n' 

for line in node1 node2; do

  rsync -avpz ${line}.kubeconfig kube-proxy.kubeconfig root@${line}:/root/

done

 

for instance in master1 master2 master3; do

  rsync -avpz admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig root@${instan

ce}:/root/

rsync -avpz encryption-config.yaml root@${instance}:/root/

done

 

注意,腳本中node1/node2以及master1/2/3都是k8s集群的主機名。另外,腳本中的文件都在當前目錄下,寫的相當路徑,當前目錄為/root/k8s。另外,將文件拷貝到其他節點時,也是暫存到/root目錄下的,後面在其它節點安裝軟件後,還需要把這些文件拷貝到對應的配置目錄下。

五、Etcd集群配置

Etcd可以單獨部署,也可以部署為集群模式,在生產環境下,建議部署為集群模式,集群模式下至少需要3臺機器,這三臺機器可以單獨部署,也可以和三個master節點公用,這取決於機器資源十分充足。

下面我們將etcd和master部署到一起,因此,下面每個步驟的操作都需要在maser1、maser2、maser3執行一遍。

1、部署etcd文件

Etcd程序可以從https://github.com/etcd-io/etcd/releases/下載,這裡我下載的是最新版本etcd-v3.4.14-linux-amd64.tar.gz,下載完成後進行解壓,然後創建相應目錄並複製配置文件過來完成配置,操作過程如下:

[root@master1 k8s]# tar -xvf etcd-v3.4.14-linux-amd64.tar.gz

[root@master1 k8s]# cp etcd-v3.4.14-linux-amd64/etcd* /usr/local/bin/

[root@master1 k8s]# scp etcd-v3.4.14-linux-amd64/etcd* master2:/usr/local/bin/

[root@master1 k8s]# scp etcd-v3.4.14-linux-amd64/etcd* master3:/usr/local/bin/

 

[root@master1 k8s]# mkdir -p /etc/etcd /var/lib/etcd

[root@master1 k8s]# cp  ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/

[root@master1 k8s]#scp  ca.pem kubernetes-key.pem kubernetes.pem master2:/etc/etcd/

[root@master1 k8s]#scp  ca.pem kubernetes-key.pem kubernetes.pem master3:/etc/etcd/

 

注意,最後兩個步驟是先創建etcd幾個配置文件目錄,然後將之前生成的證書文件拷貝到這些目錄中。

2、 創建etcd服務配置文件

服務配置文件主要用來管理etcd服務,例如啟動、關閉等,為方便起見,通過一個腳本完成,腳本etcd.sh內容如下:

[root@master1 k8s]# cat  etcd.sh

ETCD_NAME=`hostname`

INTERNAL_IP=`hostname -i`

INITIAL_CLUSTER=master1=https://172.16.213.225:2380,master2=https://172.16.213.229:2380,master3=https://172.16.213.230:2380

cat << EOF | sudo tee /etc/systemd/system/etcd.service

[Unit]

Description=etcd

Documentation=https://github.com/coreos

 

[Service]

ExecStart=/usr/local/bin/etcd \\

  --name ${ETCD_NAME} \\

  --cert-file=/etc/etcd/kubernetes.pem \\

  --key-file=/etc/etcd/kubernetes-key.pem \\

  --peer-cert-file=/etc/etcd/kubernetes.pem \\

  --peer-key-file=/etc/etcd/kubernetes-key.pem \\

  --trusted-ca-file=/etc/etcd/ca.pem \\

  --peer-trusted-ca-file=/etc/etcd/ca.pem \\

  --peer-client-cert-auth \\

  --client-cert-auth \\

  --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\

  --listen-peer-urls https://${INTERNAL_IP}:2380 \\

  --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\

  --advertise-client-urls https://${INTERNAL_IP}:2379 \\

  --initial-cluster-token etcd-cluster-0 \\

  --initial-cluster ${INITIAL_CLUSTER} \\

  --initial-cluster-state new \\

  --data-dir=/var/lib/etcd

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

在三個master節點上執行此腳本,會自動生成服務配置文件etcd.service,後面會調用此文件來啟動或重啟etcd服務。

3、 啟動並測試etcd集群服務

要啟動etcd集群服務,可通過執行如下命令實現:

[root@master1 k8s]#  systemctl daemon-reload

[root@master1 k8s]#  systemctl enable etcd

[root@master1 k8s]#  systemctl start etcd

要測試etcd集群是否正常運行,可執行如下命令:

[root@master1 k8s]# ETCDCTL_API=3 etcdctl member list   --endpoints=https://127.0.0.1:2379   --cacert=/etc/etcd/ca.pem   --cert=/etc/etcd/kubernetes.pem   --key=/etc/etcd/kubernetes-key.pem

 

至此,etcd集群安裝完成。

六、k8s集群master節點各組件部署

下面正式進入k8s集群部署階段,首先部署的是master節點各組件,主要有kube-apiserver、kube-controller-manager、kube-scheduler三個組件的安裝部署。

1、部署master節點組件

要安裝k8s集群組件,首先需要從github上下載Kubernetes的安裝程序,可選擇源碼和二進制版本下載,建議選擇二進制版本下載。

下載地址為:

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#downloads-for-v1204,我這裡下載的是kubernetes1.20.4版本,對應的程序包為kubernetes-server-linux-amd64.tar.gz。

將下載好的程序包進行解壓,然後在kubernetes/server/bin目錄下即可找到需要的組件程序,先進行授權,然後傳到/usr/local/bin目錄下。操作如下:

[root@master1 setup]# cd kubernetes/server/bin

[root@master1 bin]# chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl

[root@master1 bin]# cp kube-apiserver kube-controller-manager kube-scheduler /usr/local/bin/

[root@master1 bin]# scp kube-apiserver kube-controller-manager kube-scheduler master2:/usr/local/bin/

[root@master1 bin]# scp kube-apiserver kube-controller-manager kube-scheduler master2:/usr/local/bin/

[root@master1 bin]# scp  kubectl kubelet kube-proxy  node1:/usr/local/bin/

[root@master1 bin]# scp  kubectl kubelet kube-proxy  node2:/usr/local/bin/

此操作在三個master節點都執行一遍,即可完成master節點組件的安裝。同時也將客戶端node1、node2所需的軟件也一併拷貝過去。

2、Kubernetes API服務配置

首先,需要移動證書到Kubernetes對應目錄,操作如下:

[root@master1 k8s]# mkdir -p /var/lib/kubernetes/

[root@master1 k8s]# cp  ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \

    service-account-key.pem service-account.pem \

    encryption-config.yaml /var/lib/kubernetes/

 

下面是拷貝證書到master2、3節點:

[root@master1 k8s]# scp  ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \

    service-account-key.pem service-account.pem \

    encryption-config.yaml  master2:/var/lib/kubernetes/

[root@master1 k8s]# scp  ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \

    service-account-key.pem service-account.pem \

    encryption-config.yaml  master3:/var/lib/kubernetes/

接著,創建kube-api服務的配置文件,為了方便起見,通過一個腳本來實現,腳本kube-api.sh內容如下:

[root@master1 k8s]# cat  kube-api.sh

CONTROLLER0_IP=172.16.213.225

CONTROLLER1_IP=172.16.213.229

CONTROLLER2_IP=172.16.213.230

INTERNAL_IP=`hostname -i`

 

cat << EOF | sudo tee /etc/systemd/system/kube-apiserver.service

[Unit]

Description=Kubernetes API Server

Documentation=https://github.com/kubernetes/kubernetes

 

[Service]

ExecStart=/usr/local/bin/kube-apiserver \\

  --advertise-address=${INTERNAL_IP} \\

  --allow-privileged=true \\

  --apiserver-count=3 \\

  --audit-log-maxage=30 \\

  --audit-log-maxbackup=3 \\

  --audit-log-maxsize=100 \\

  --audit-log-path=/var/log/audit.log \\

  --authorization-mode=Node,RBAC \\

  --bind-address=0.0.0.0 \\

  --client-ca-file=/var/lib/kubernetes/ca.pem \\

  --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\

  --etcd-cafile=/var/lib/kubernetes/ca.pem \\

  --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\

  --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\

  --etcd-servers=https://$CONTROLLER0_IP:2379,https://$CONTROLLER1_IP:2379,https://$CONTROLLER2_IP:2379 \\

  --event-ttl=1h \\

  --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\

  --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\

  --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\

  --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\

  --kubelet-https=true \\

  --runtime-config=api/all=true \\

  --service-account-key-file=/var/lib/kubernetes/service-account.pem \\

  --service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem \\

--service-account-issuer=https://${INTERNAL_IP}:6443/auth/realms/master/.well-known/openid-configuration \\

  --service-cluster-ip-range=10.100.0.0/24 \\

  --service-node-port-range=30000-32767 \\

  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\

  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\

  --v=2 \\

  --kubelet-preferred-address-types=InternalIP,InternalDNS,Hostname,ExternalIP,ExternalDNS

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

在三個master節點依次執行此腳本,會生成/etc/systemd/system/kube-apiserver.service文件。

3、Kubernetes Controller Manager配置

首先需要移動kubeconfig文件到kubernetes目錄,執行如下命令:

[root@master1 k8s]# cp  kube-controller-manager.kubeconfig /var/lib/kubernetes/

[root@master1 k8s]# scp  kube-controller-manager.kubeconfig master2:/var/lib/kubernetes/

[root@master1 k8s]# scp  kube-controller-manager.kubeconfig master3:/var/lib/kubernetes/

 

然後,創建kube-controller-manager服務配置文件,為方便起見,仍通過一個腳本controller-manager.sh來實現,腳本內容如下:

[root@master1 k8s]# cat controller-manager.sh

cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service

[Unit]

Description=Kubernetes Controller Manager

Documentation=https://github.com/kubernetes/kubernetes

 

[Service]

ExecStart=/usr/local/bin/kube-controller-manager \\

  --address=0.0.0.0 \\

  --cluster-cidr=10.200.0.0/16 \\

  --cluster-name=kubernetes \\

  --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\

  --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\

  --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\

  --leader-elect=true \\

  --root-ca-file=/var/lib/kubernetes/ca.pem \\

  --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\

  --service-cluster-ip-range=10.100.0.0/24 \\

  --use-service-account-credentials=true \\

  --allocate-node-cidrs=true \

  --cluster-cidr=10.100.0.0/16 \

  --v=2

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

執行此腳本,會生成/etc/systemd/system/kube-controller-manager.service文件。

4、Kubernetes Scheduler配置

配置之前,先需要將kube-scheduler的kubeconfig文件移動到kubernetes目錄,然後創建kube-scheduler配置文件,最後,創建kube-scheduler服務配置文件。

[root@master1 k8s]# cp kube-scheduler.kubeconfig /var/lib/kubernetes/

[root@master1 k8s]#scp kube-scheduler.kubeconfig master2:/var/lib/kubernetes/

[root@master1 k8s]#scp kube-scheduler.kubeconfig master3:/var/lib/kubernetes/

 

[root@master1 k8s]# mkdir -p /etc/kubernetes/config

[root@master1 k8s]#scp admin.kubeconfig master2:/etc/kubernetes/

[root@master1 k8s]#scp admin.kubeconfig master3:/etc/kubernetes/

 

目錄創建完成後,最後通過腳本完成kube-scheduler配置文件和服務文件的創建,腳本scheduler.sh內容如下:

[root@master1 k8s]# cat  scheduler.sh

cat <<EOF | tee /etc/kubernetes/config/kube-scheduler.yaml

apiVersion: kubescheduler.config.k8s.io/v1beta1

kind: KubeSchedulerConfiguration

clientConnection:

  kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"

leaderElection:

  leaderElect: true

EOF

 

cat <<EOF | tee /etc/systemd/system/kube-scheduler.service

[Unit]

Description=Kubernetes Scheduler

Documentation=https://github.com/kubernetes/kubernetes

 

[Service]

ExecStart=/usr/local/bin/kube-scheduler \\

  --config=/etc/kubernetes/config/kube-scheduler.yaml \\

  --v=2

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

此腳本執行後,會創建kube-scheduler.yaml和kube-scheduler.service兩個文件。

5、啟動各組件服務

到這裡為止,master節點上相關組件的配置和服務文件都配置完成了,下面就可以啟動服務了,執行如下命令啟動三個服務:

[root@master1 k8s]# systemctl daemon-reload

[root@master1 k8s]# systemctl enable kube-apiserver kube-controller-manager kube-scheduler

[root@master1 k8s]# systemctl start kube-apiserver kube-controller-manager kube-scheduler

服務啟動完畢後,使用以下命令檢查各個組件的狀態:

[root@master1 k8s]# kubectl get cs --kubeconfig admin.kubeconfig

Warning: v1 ComponentStatus is deprecated in v1.19+

NAME                 STATUS    MESSAGE             ERROR

scheduler            Healthy   ok                  

controller-manager   Healthy   ok                  

etcd-2               Healthy   {"health":"true"}   

etcd-0               Healthy   {"health":"true"}   

etcd-1               Healthy   {"health":"true"}  

從輸出可在,服務正常,etcd集群也運行正常。

 

此時,如果直接在master節點運行kubectl  get cs會得到如下錯誤:

[root@master1 ~]# kubectl  get node

The connection to the server localhost:8080 was refused - did you specify the right host or port?

這是因為kubectl命令需要使用kubernetes-admin來運行,解決方法有兩種,第一種是執行如下操作:

mkdir -p $HOME/.kube

cp -i admin.kubeconfig $HOME/.kube/config

chown $(id -u):$(id -g) $HOME/.kube/config

 

第二種方法是執行如下操作:

echo "export KUBECONFIG=/etc/kubernetes/admin.kubeconfig" >> ~/.bash_profile

source ~/.bash_profile

然後就可以正常執行kubectl命令了。

 

以上操作在三個master節點都執行一遍。

6、配置RBAC的授權

將下來配置RBAC的授權,來允許kube-api server去訪問在每個worker節點上kubelet API. 訪問kubelet API主要是用來檢索度量,日誌和執行Pods中的命令等。

此過程主要分為兩個步驟,分別是創建`system:kube-apiserver-to-kubelet`集群角色,並附與權限去訪問kubelet,然後綁定`system:kube-apiserver-to-kubelet`集群角色到kubernetes用戶。這個過程通過一個腳本來完成,腳本kube-apiserver-to-kubelet.sh內容如下:

[root@master1 k8s]# cat  kube-apiserver-to-kubelet.sh   

cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  annotations:

    rbac.authorization.kubernetes.io/autoupdate: "true"

  labels:

    kubernetes.io/bootstrapping: rbac-defaults

  name: system:kube-apiserver-to-kubelet

rules:

  - apiGroups:

      - ""

    resources:

      - nodes/proxy

      - nodes/stats

      - nodes/log

      - nodes/spec

      - nodes/metrics

    verbs:

      - "*"

EOF

 

cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: system:kube-apiserver

  namespace: ""

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: system:kube-apiserver-to-kubelet

subjects:

  - apiGroup: rbac.authorization.k8s.io

    kind: User

    name: kubernetes

EOF

 

此腳本執行完畢,相關授權操作就執行成功了。

7、Kubernetes前端負載均衡器配置

負載均衡主要是針對master節點上面的kube-apiserver服務的。此服務非常關鍵,如果服務較多,此服務負載就會很高,所以做負載均衡很有必要。

由於我們使用了三個master,因此,負載均衡是針對三個master節點上的kube-apiserver服務,這裡我採用haproxy來實現三個master節點kube-apiserver服務的負載均衡,這裡我單獨找一臺主機來部署haproxy,haproxy機器就是之前環境說明中的lbserver主機,haproxy的安裝可以採用容器方式,也可以直接在物理機上安裝,這裡直接在物理機上安裝,安裝通過yum來實現即可。 

安裝方式如下:

[root@lbserver ~]# yum install -y  haproxy

安裝完成後,需要配置haproxy,默認的配置文件為/etc/haproxy/haproxy.cfg,修改後的配置文件內容如下:

[root@lbserver ~]# more /etc/haproxy/haproxy.cfg

frontend frontend-k8s-api

  bind 172.16.213.236:6443

  bind 172.16.213.236:443

  mode tcp

  option tcplog

  default_backend k8s-api

 

backend k8s-api

  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 k8s-api-1 172.16.213.225:6443 check

  server k8s-api-2 172.16.213.229:6443 check

  server k8s-api-3 172.16.213.230:6443 check

listen admin_stats

        bind 0.0.0.0:9188

        mode http

        log 127.0.0.1 local0 err

        stats refresh 30s

        stats uri /haproxy-status

        stats realm welcome login\ Haproxy

        stats auth admin:admin123

        stats hide-version

        stats admin if TRUE

配置完成後,就可以啟動服務了,執行如下命令:

[root@lbserver ~]# systemctl start haproxy

[root@lbserver ~]#systemctl enable haproxy

Haproxy啟動成功後,就可以通過haproxy的ip加上端口訪問三個master節點的api-server服務了,測試如下:

[root@lbserver ~]#  curl --cacert ca.pem https://172.16.213.236:6443/version

{

  "major": "1",

  "minor": "19",

  "gitVersion": "v1.19.4",

  "gitCommit": "d360454c9bcd1634cf4cc52d1867af5491dc9c5f",

  "gitTreeState": "clean",

  "buildDate": "2020-11-11T13:09:17Z",

  "goVersion": "go1.15.2",

  "compiler": "gc",

  "platform": "linux/amd64"

如果有類似如下輸出,表示負載均衡配置正常。

七、k8s集群work節點組件配置

以下操作均在k8s集群的兩個work節點進行。

1、安裝docker引擎

K8s底層默認使用docker引擎,當然也可以使用其它非docekr引擎,例如containerd 和 cri-o等。更專業的應該叫容器運行時。這裡使用docker運行時,所以,需要在每個work節點安裝docker引擎,基本安裝過程如下:

[root@node1 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

[root@node1 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@node1 ~]# yum makecache fast

[root@node1 ~]# yum -y install docker-ce

接著,創建daemon.json文件,內容如下:

[root@node1 ~]#  more /etc/docker/daemon.json        

{

  "exec-opts": ["native.cgroupdriver=systemd"]

}

最後,重啟docker服務即可。

 [root@node1 ~]# systemctl  start docker

注意,官方軟件源默認啟用了最新的軟件,如果我們不想安裝最新版本,可以通過編輯軟件源的方式獲取各個版本的軟件包。例如官方並沒有將測試版本的軟件源置為可用,我們可以修改docker-ce.repo文件,開啟各種測試版本等。

3、 kubelet配置

在前面我們創建了kubelet的各種證書,這裡需要移動證書和kubelet config到相對應的目錄,基本操作過程如下:

[root@node1 ~]# mkdir -p /var/lib/kubelet

[root@node1 ~]# mkdir -p /var/lib/kubernetes

 

[root@node2 ~]# mkdir -p /var/lib/kubelet

[root@node2 ~]# mkdir -p /var/lib/kubernetes

 

[root@master1 ~]# scp node1-key.pem node1.pem  node1:/var/lib/kubelet/

[root@master1 ~]# scp node1.kubeconfig node1:/var/lib/kubelet/kubeconfig

[root@master1 ~]# scp ca.pem node1:/var/lib/kubernetes/

 

[root@master1 ~]# scp node2-key.pem node2.pem  node2:/var/lib/kubelet/

[root@master1 ~]# scp node2.kubeconfig  node2:/var/lib/kubelet/kubeconfig

[root@master1 ~]# scp ca.pem node2:/var/lib/kubernetes/

 

注意,上面操作中使用scp命令從master1節點拷貝證書到node1、node2主機對應目錄下。

接著,還需要創建kubelet配置文件以及服務文件,通過一個腳本kubelet-setup.sh來自動完成,腳本內容如下:

[root@node1 ~]# more  kubelet-setup.sh

cat <<EOF | tee /var/lib/kubelet/kubelet-config.yaml

kind: KubeletConfiguration

apiVersion: kubelet.config.k8s.io/v1beta1

authentication:

  anonymous:

    enabled: false

  webhook:

    enabled: true

  x509:

    clientCAFile: "/var/lib/kubernetes/ca.pem"

authorization:

  mode: Webhook

clusterDomain: "cluster.local"

clusterDNS:

  - "10.100.0.10"

podCIDR: "10.100.0.0/16"

#resolvConf: "/run/systemd/resolve/resolv.conf"

runtimeRequestTimeout: "15m"

tlsCertFile: "/var/lib/kubelet/node1.pem"   #這裡是node1節點,如果要部署到node2,需要修改這兩個證書的名字為node2的證書。

tlsPrivateKeyFile: "/var/lib/kubelet/node1-key.pem"

EOF

 

 

cat <<EOF | sudo tee /etc/systemd/system/kubelet.service

[Unit]

Description=Kubernetes Kubelet

Documentation=https://github.com/kubernetes/kubernetes

After=containerd.service

Requires=containerd.service

 

[Service]

ExecStart=/usr/local/bin/kubelet \

  --config=/var/lib/kubelet/kubelet-config.yaml \

  --docker=unix:///var/run/docker.sock \

  --docker-endpoint=unix:///var/run/docker.sock \

  --image-pull-progress-deadline=2m \

  --network-plugin=cni \

  --kubeconfig=/var/lib/kubelet/kubeconfig \

  --register-node=true \

  --cgroup-driver=systemd \

  --v=2

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

將這個腳本拷貝的node1、node2主機下,並做簡單修改,然後執行此腳本,即可完成kubelet配置以及服務配置。會生成/var/lib/kubelet/kubelet-config.yaml和/etc/systemd/system/kubelet.service兩個文件。

 

4、 kube-proxy配置

針對kube-proxy的配置,首先需要移動kubeconfig文件到kubernetes目錄,操作如下:

[root@node1 ~]# mkdir  -p /var/lib/kube-proxy

[root@node2 ~]# mkdir  -p /var/lib/kube-proxy

然後從master1節點拷貝kube-proxy.kubeconfig到node1、node2節點。

[root@master1 ~]# scp  kube-proxy.kubeconfig  node1:/var/lib/kube-proxy/kubeconfig

[root@master1 ~]# scp  kube-proxy.kubeconfig  node2:/var/lib/kube-proxy/kubeconfig

 

接著,還需要創建kube-proxy配置文件以及服務文件,通過一個腳本kube-proxy-setup.sh來自動完成,腳本內容如下:

[root@node1 ~]# cat   kube-proxy-setup.sh

cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml

kind: KubeProxyConfiguration

apiVersion: kubeproxy.config.k8s.io/v1alpha1

clientConnection:

  kubeconfig: "/var/lib/kube-proxy/kubeconfig"

mode: ""

clusterCIDR: "10.100.0.0/16"

EOF

 

cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service

[Unit]

Description=Kubernetes Kube Proxy

Documentation=https://github.com/kubernetes/kubernetes

 

[Service]

ExecStart=/usr/local/bin/kube-proxy \\

  --config=/var/lib/kube-proxy/kube-proxy-config.yaml

Restart=on-failure

RestartSec=5

 

[Install]

WantedBy=multi-user.target

EOF

 

將此腳本拷貝到node1、node2主機上,然後執行此腳本,會生成/var/lib/kube-proxy/kube-proxy-config.yaml和/etc/systemd/system/kube-proxy.service兩個文件。

5、 啟動kubelet和kube-proxy服務

到此為止,kubelet和kube-proxy的配置都已經完成,下面在集群work節點上分別啟動這兩個服務,操作如下:

[root@node1 ~]# systemctl daemon-reload

[root@node1 ~]# systemctl enable kubelet kube-proxy

[root@node1 ~]# systemctl start kubelet kube-proxy

服務啟動完畢後,可以通過systemctl status查看服務啟動狀態,如果不正常,會提示相關錯誤。

6、 部署CNI網絡插件

CNI網絡用來實現k8s集群不同主機上不同pod的通信,需要在每個work節點安裝CNI網絡,要部署CNI網絡,可從https://github.com/containernetworking/plugins/releases下載CNI查看,操作過程如下:

[root@node1 ~]# mkdir /opt/cni/bin /etc/cni/net.d -p

[root@node1 ~]# cd /opt/cni/bin

[root@node1 ~]# wget https://github.com/containernetworking/plugins/releases/download/v0.8.7/cni-plugins-linux-amd64-v0.8.7.tgz

[root@node1 ~]# tar zxvf cni-plugins-linux-amd64-v0.8.7.tgz -C /opt/cni/bin

 

CNI插件安裝完畢後,還需要在任意一個master節點上執行如下操作,將CNI網絡與master節點關聯起來,操作如下:

[root@master1 ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

將kube-flannel.yml文件下載到本地,然後找到"Network": "10.244.0.0/16", 修改為"Network": "10.100.0.0/16"

最後,在master節點執行如下操作:

[root@node1 ~]# kubectl apply -f kube-flannel.yaml

至此,k8s集群全部部署完成。

要驗證k8s集群是否工作正常,可在master節點執行如下命令:

[root@master1 k8s]# kubectl  get node

NAME    STATUS   ROLES    AGE   VERSION

node1   Ready    <none>   49d   v1.19.4

node2   Ready    <none>   49d   v1.19.4

其中node1/2是兩個work節點,如果狀態均為Ready,表示集群運行正常。

八、測試集群是否正常

1、啟用 kubectl 命令的自動補全功能

echo "source <(kubectl completion bash)" >> ~/.bashrc

source ~/.bashrc

1、創建deployment  

kubectl  create   deployment nginx-deployment --image=nginx --dry-run=client -o yaml

 

2、創建service

kubectl create service nodeport nginx-services --tcp=8080:80 --dry-run=client  -o yaml

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *