1. 程式人生 > 其它 >第19章: kubeadm方式部署K8S1.20單Master叢集

第19章: kubeadm方式部署K8S1.20單Master叢集

kubeadm方式部署K8S1.20Master叢集

作者

劉暢

時間

2021-08-24

目錄

1 架構說明 1

1.1 生產環境可部署Kubernetes叢集的兩種方式 1

1.2 準備環境 1

1.3 作業系統初始化配置 2

2 安裝kubeadm/kubelet/kubectl 4

2.1 新增阿里雲YUM軟體源 4

2.2 安裝 4

3 部署Kubernetes Master 5

3.1 命令列方式引導 5

3.2 使用配置檔案方式引導 5

3.3 拷貝kubectl使用的連線k8s認證檔案到預設路徑 6

4 加入

Kubernetes Node 6

5 部署容器網路(CNI) 6

5.1下載YAML 6

5.2 修改CALICO_IPV4POOL_CIDR 7

6 測試kubernetes叢集 7

7 部署 Dashboard 7

7.1 說明 7

7.2 部署 8

7.3 token登入Dashboard 10

8 切換容器引擎為Containerd 11

8.1 安裝和配置的先決條件 12

8.2 安裝containerd(linux) 12

8.3 修改配置檔案 13

8.4 配置kubelet使用containerd 13

8.5 驗證 13

8.6 管理容器工具 14

9 補充 15

9.1 k8s刪除一直處於terminating狀態的pod 15

9.2 無法訪問k8s.gcr.io的解決辦法 15


1 架構說明

1.1 生產環境可部署Kubernetes叢集的兩種方式

1 kubeadm部署

(1) Kubeadm是一個K8s部署工具,提供kubeadm initkubeadm join,用於快速部署Kubernetes叢集。這裡採用kubeadm搭建叢集。

(2) kubeadm工具功能

kubeadm init #初始化一個Master節點

kubeadm join #將工作節點加入叢集

kubeadm upgrade #升級K8s版本

kubeadm token

#管理 kubeadm join 使用的令牌

kubeadm reset #清空 kubeadm init 或者 kubeadm join 對主機所做的任何更改

kubeadm version #列印 kubeadm 版本

kubeadm alpha #預覽可用的新功能

2二進位制包部署

github下載發行版的二進位制包,手動部署每個元件,組成Kubernetes叢集。

1.2 準備環境

1伺服器要求

建議最小硬體配置: 2CPU2G記憶體、30G硬碟

伺服器最好可以訪問外網,會有從網上拉取映象需求,如果伺服器不能上網,需要提前下載對應映象並匯入節點

2伺服器規劃

作業系統: CentOS7.5

主機名

IP

軟體

k8s-master1

(24G)

主網絡卡eth1:172.16.1.81
副網絡卡eth0:
10.0.0.81

docker-ce-19.03.9kubernetes-1.20

k8s-node1

(48G)

主網絡卡eth1:172.16.1.83
副網絡卡eth0:
10.0.0.83

docker-ce-19.03.9kubernetes-1.20

3架構圖

1.3 作業系統初始化配置

172.16.1.8183節點上操作

(1) 關閉防火牆
# systemctl stop firewalld
# systemctl disable firewalld

(2) 關閉selinux
# sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
# setenforce 0 # 臨時

(3) 關閉swap
# swapoff -a # 臨時
# sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久

(4) master新增hosts
cat >> /etc/hosts << EOF
172.16.1.81 k8s-master1
172.16.1.83 k8s-node1
EOF

(5) 將橋接的IPv4流量傳遞到iptables的鏈
# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# sysctl --system # 生效,手動載入所有的配置檔案

(6) 時間同步
# yum install ntpdate -y
# ntpdate ntp.aliyun.com

# crontab -e

# crontab -l

*/5 * * * * /usr/sbin/ntpdate ntp.aliyun.com &>/dev/null

(7) 部署docker

這裡使用Docker作為容器引擎,也可以換成別的,例如containerd

1) 安裝依賴包

# yum install -y yum-utils device-mapper-persistent-data lvm2

2) 新增Docker軟體包源

# yum-config-manager \

--add-repo \

https://download.docker.com/linux/centos/docker-ce.repo

3) 更新為阿里雲的源

# wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4) 清理源快取

# yum clean all

5) 安裝指定版本的Docker CE

# yum list docker-ce --showduplicates | sort -r

# yum list docker-ce-cli --showduplicates | sort -r

# yum install docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7 -y

6) 啟動Docker服務並設定開機啟動

# systemctl start docker

# systemctl enable docker

# docker version # 可以看到docker客戶端和服務端都是同一個版本

# docker info

7) 新增阿里雲的映象倉庫

# mkdir -p /etc/docker

# tee /etc/docker/daemon.json <<-'EOF'

{

"registry-mirrors": ["https://b1cx9cn7.mirror.aliyuncs.com"]

}

EOF

8) 重啟docker

# systemctl daemon-reload

# systemctl restart docker

(8) 增加 iptables conntrack 表大小,防止iptables效能不佳

參考網站: https://docs.projectcalico.org/maintenance/troubleshoot/troubleshooting#configure-networkmanager

# sysctl -w net.netfilter.nf_conntrack_max=1000000

# echo "net.netfilter.nf_conntrack_max=1000000" >> /etc/sysctl.conf

(9) 設定容器執行時和kubelet使用systemd作為cgroup驅動

1)編輯"/etc/docker/daemon.json"檔案,追加"exec-opts"配置。

{

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

}

2)重啟docker

#systemctl daemon-reload

# systemctl restart docker

3)驗證配置生效

# docker info | grep Cgroup

Cgroup Driver: systemd

2 安裝kubeadm/kubelet/kubectl

172.16.1.8183節點上操作

kubeadm #用來初始化叢集的指令

kubelet #在叢集中的每個節點上用來啟動Pod和容器等

kubectl #用來與叢集通訊的命令列工具

2.1 新增阿里雲YUM軟體源

# cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

#yumclean all

# yum makecache

2.2 安裝

由於版本更新頻繁,這裡指定版本號部署

# yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0
# systemctl enable kubelet

3 部署Kubernetes Master

172.16.1.81節點上操作

官方文件:

# https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/

# https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/

3.1 命令列方式引導

# kubeadm init \
--apiserver-advertise-address=172.16.1.81 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all

引數說明:

(1) --apiserver-advertise-address # 叢集通告地址

(2) --image-repository # 由於預設拉取映象地址k8s.gcr.io國內無法訪問,這裡指定阿里雲映象倉庫地址

(3) --kubernetes-version # K8s版本,與上面安裝的一致

(4) --service-cidr # 叢集內部虛擬網路,Pod統一訪問入口

(5) --pod-network-cidr # Pod網路,,與下面部署的CNI網路元件yaml中保持一致

輸出內容:

……(省略的日誌)

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

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

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.16.1.81:6443 --token s53bbu.zzmnnbxtss6ydl70 \

--discovery-token-ca-cert-hash sha256:cfb5e3e7711d91dd47007b6681230cf9dcc920d231c15b9dd3bf3ea1479f6571

# 初始化完成後,最後會輸出一個join命令,先記住,下面用

3.2 使用配置檔案方式引導

# cat > kubeadm-config.conf << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
imageRepository: registry.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
EOF


# kubeadm init --config kubeadm-config.conf --ignore-preflight-errors=all

3.3 拷貝kubectl使用的連線k8s認證檔案到預設路徑

# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
#
sudo chown $(id -u):$(id -g) $HOME/.kube/config

檢視工作節點:

# kubectl get nodes
NAME STATUS ROLES AGE VERSION

k8s-master1 NotReady control-plane,master 6m33s v1.20.0

注:由於網路外掛還沒有部署,還沒有準備就緒 NotReady

4 加入Kubernetes Node

172.16.1.83節點上操作

官方文件:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/

向叢集新增新節點,執行在kubeadm init輸出的kubeadm join命令

# kubeadm join 172.16.1.81:6443 --token s53bbu.zzmnnbxtss6ydl70 \

--discovery-token-ca-cert-hash sha256:cfb5e3e7711d91dd47007b6681230cf9dcc920d231c15b9dd3bf3ea1479f6571

:預設token有效期為24小時,當過期之後,該token就不可用了。這時就需要重新建立token,可以

直接使用命令快捷生成。kubeadm token create --print-join-command

5 部署容器網路(CNI)

172.16.1.81節點上操作

Calico是一個純三層的資料中心網路方案,是目前Kubernetes主流的網路方案。

官方文件:

https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network

5.1下載YAML

# wget https://docs.projectcalico.org/manifests/calico.yaml

:calico映象版本為v3.20.0

5.2 修改CALICO_IPV4POOL_CIDR

1修改calico.yaml檔案中定義Pod網路(CALICO_IPV4POOL_CIDR),與前面kubeadm init

--pod-network-cidr指定的一樣。

2部署

# kubectl apply -f calico.yaml
[root@k8s-master1 k8s]# kubectl get pods -A -o wide

3Calico Pod狀態Running,節點準備就緒

[root@k8s-master1 k8s]# kubectl get nodes

NAME STATUS ROLES AGE VERSION

k8s-master1 Ready control-plane,master 44m v1.20.0

k8s-node1 Ready <none> 41m v1.20.0

6 測試kubernetes叢集

172.16.1.81節點上操作

Kubernetes叢集中建立一個pod,驗證是否正常執行

# kubectl create deployment nginx --image=nginx
# kubectl expose deployment nginx --name=nginx --port=80 --target-port=80 --type=NodePort
# kubectl get pod,svc

:訪問地址:http://NodeIP:Port

7 部署 Dashboard

172.16.1.81節點上操作

7.1 說明

Dashboard是官方提供的一個UI,可用於基本管理K8s資源。

1官方文件

https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

2gitlab專案地址

https://github.com/kubernetes/dashboard

3版本相容

https://github.com/kubernetes/dashboard/releases/tag/v2.3.1

4下載

# wget -O kubernetes-dashboard.yaml \

https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml

7.2 部署

1修改kubernetes-dashboard.yaml配置

由於預設kubernetes-dashboard只能叢集內部訪問,因此修改ServiceNodePort型別,暴露到k8s叢集外部進行訪問。

2應用kubernetes-dashboard.yaml

[root@k8s-master1 ~]# kubectl apply -f kubernetes-dashboard.yaml
# 檢視pod狀態
[root@k8s-master1 ~]# kubectl get pod -n kubernetes-dashboard -o
wide

:kubernetesdashboardpod執行正常,訪問地址:https://NodeIP:30001

3建立訪問dashboard的token

(1) 建立serviceaccount並賦權

1) kube-system名稱空間中建立serviceaccount/dashboard-admin

# kubectl create serviceaccount dashboard-admin -n kube-system

2) 繫結kube-system名稱空間中serviceaccount/dashboard-admin到叢集角色cluster-admin

# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin \

--serviceaccount=kube-system:dashboard-admin

(2) 獲取訪問token

1)獲取kube-system名稱空間中serviceaccount/dashboard-adminsecrets名稱

# kubectl describe serviceaccount dashboard-admin -n kube-system

2) 獲取kube-system名稱空間中secrets/dashboard-admin-token-f8fd5登入k8s叢集的token

# kubectl describe secrets dashboard-admin-token-f8fd5 -n kube-system > dashboard-admin.token

3) 補充:一條命令獲取token

# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

7.3 token登入Dashboard

https://kubernetes.io/docs/reference/access-authn-authz/authentication/

到此,kubeadm方式部署K8S1.20Master叢集就完成了,k8s叢集全部pod狀態如下所示。

8 切換容器引擎為Containerd

172.16.1.8183節點上操作

參考資料:https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/

(1) 容器執行時

1) 為了在 Pod 中執行容器,Kubernetes使用容器執行時(Container Runtime)你需要在叢集內

每個節點上安裝一個容器執行時以使Pod可以執行在上面。

2) 預設情況下,Kubernetes使用容器執行時介面(Container Runtime InterfaceCRI)來與你所

選擇的容器執行時互動。

3) 如果你不指定執行時,則kubeadm會自動嘗試檢測到系統上已經安裝的執行時,方法是掃描

一組眾所周知的 Unix 域套接字。如果同時檢測到 Docker containerd,則優先選擇 Docker。這

是必然的,因為 Docker 18.09 附帶了 containerd 並且兩者都是可以檢測到的,即使你僅安裝了

Docker

4) 如果檢測到其他兩個或多個執行時,kubeadm輸出錯誤資訊並退出。kubelet通過內建的

dockershim CRI實現與Docker整合。

(2) Cgroup驅動程式

1)控制組用來約束分配給程序的資源

2)Linux系統發行版使用systemd作為其初始化系統時,初始化程序會生成並使用一個root控制組 (cgroup),並充當cgroup管理器。Systemdcgroup整合緊密,並將為每個systemd單元分配一個

cgroup。你也可以配置容器執行時和kubelet使用cgroupfs。連同systemd一起使用cgroupfs

味著將有兩個不同的cgroup管理器。

3)單個cgroup管理器將簡化分配資源的檢視,並且預設情況下將對可用資源和使用中的資源具有

更一致的檢視。當有兩個管理器共存於一個系統中時,最終將對這些資源產生兩種檢視。在此領域

人們已經報告過一些案例,某些節點配置讓kubeletdocker使用cgroupfs,而節點上執行的其餘

程序則使用systemd; 這類節點在資源壓力下會變得不穩定。

4)注意:

更改已加入叢集的節點的cgroup驅動是一項敏感的操作。如果kubelet已經使用某cgroup驅動的

語義建立了pod,更改執行時以使用別的cgroup驅動,當為現有Pods重新建立PodSandbox時會

產生錯誤。重啟kubelet也可能無法解決此類問題。如果你有切實可行的自動化方案,使用其他已更

新配置的節點來替換該節點,或者使用自動化方案來重新安裝。

8.1 安裝和配置的先決條件

# 建立 .conf 檔案以在啟動時載入模組

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf

overlay

br_netfilter

EOF

sudo modprobe overlay

sudo modprobe br_netfilter

# 設定必需的 sysctl 引數,這些引數在重新啟動後仍然存在。

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf

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

net.ipv4.ip_forward = 1

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

EOF

# 應用 sysctl 引數而無需重新啟動

sudo sysctl --system

8.2安裝containerd(linux)

#安裝依賴包

yum install -y yum-utils device-mapper-persistent-data lvm2


#配置docker倉庫源

yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

#更新為阿里雲的docker倉庫源

wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#安裝

yum install -y containerd.io
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
systemctl restart containerd

systemctl enable containerd

8.3 修改配置檔案

設定拉取Docker Hub映象配置加速地址為阿里雲映象倉庫地址

cgroups驅動設定為systemd

#修改配置檔案

vi /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2"
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
...
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://b1cx9cn7.mirror.aliyuncs.com
"]

#重新啟動
systemctl restart containerd

8.4 配置kubelet使用containerd

# vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd

# systemctl restart kubelet

8.5 驗證

[root@k8s-master1 ~]# kubectl get nodes -o wide

:切回Docker引擎,就是把kubelet配置引數去掉即可。

8.6 管理容器工具

containerd使crictl工具檢查和除錯容器。

專案地址:https://github.com/kubernetes-sigs/cri-tools/

1設定crictl連線containerd

# vi /etc/crictl.yaml

runtime-endpoint: unix:///run/containerd/containerd.sock

image-endpoint: unix:///run/containerd/containerd.sock

timeout: 10

debug: false

[root@k8s-master1 ~]# crictl images

2 dockercrictl命令對照表

映象相關功能

Docker

Containerd

顯示本地映象列表

docker images

crictl images

下載映象

docker pull

crictl pull

上傳映象

docker push

例如buildk

刪除本地映象

docker rmi

crictl rmi

檢視映象詳情

docker inspect IMAGE-ID

crictl inspecti IMAGE-ID

容器相關功能

Docker

Containerd

顯示容器列表

docker ps

crictl ps

建立容器

docker create

crictl create

啟動容器

docker start

crictl start

停止容器

docker stop

crictl stop

刪除容器

docker rm

crictl rm

檢視容器詳情

docker inspect

crictl inspect

attach

docker attach

crictl attach

exec

docker exec

crictl exec

logs

docker logs

crictl logs

stats

docker stats

crictl stats

POD相關功能

Docker

Containerd

顯示 POD 列表

crictl pods

檢視 POD 詳情

crictl inspectp

執行 POD

crictl runp

停止 POD

crictl stopp

9補充

9.1 k8s刪除一直處於terminating狀態的pod

# kubectl delete pod [pod name] --force --grace-period=0 -n [namespace]

9.2 無法訪問k8s.gcr.io的解決辦法

由於一些原因,在國內無法訪問k8s.gcr.io上的映象,在安裝kubernetes時,很多官方映象

又是都存在k8s.gcr.io上,在國內大都使用阿里雲的映象。

https://cloud.google.com/container-registry/

使用阿里雲映象地址:

地址1: registry.aliyuncs.com/google_containers

地址2: registry.cn-hangzhou.aliyuncs.com/google_containers