第19章: kubeadm方式部署K8S1.20單Master叢集
kubeadm方式部署K8S1.20單Master叢集
作者 |
劉暢 |
時間 |
2021-08-24 |
目錄
1.1 生產環境可部署Kubernetes叢集的兩種方式 1
3.3 拷貝kubectl使用的連線k8s認證檔案到預設路徑 6
9.1 k8s刪除一直處於terminating狀態的pod 15
1 架構說明
1.1 生產環境可部署Kubernetes叢集的兩種方式
1 kubeadm部署
(1) Kubeadm是一個K8s部署工具,提供kubeadm init和kubeadm join,用於快速部署Kubernetes叢集。這裡採用kubeadm搭建叢集。
(2) kubeadm工具功能
kubeadm init #初始化一個Master節點
kubeadm join #將工作節點加入叢集
kubeadm upgrade #升級K8s版本
kubeadm token
kubeadm reset #清空 kubeadm init 或者 kubeadm join 對主機所做的任何更改
kubeadm version #列印 kubeadm 版本
kubeadm alpha #預覽可用的新功能
2二進位制包部署
從github下載發行版的二進位制包,手動部署每個元件,組成Kubernetes叢集。
1伺服器要求
建議最小硬體配置: 2核CPU、2G記憶體、30G硬碟
伺服器最好可以訪問外網,會有從網上拉取映象需求,如果伺服器不能上網,需要提前下載對應映象並匯入節點。
2伺服器規劃
作業系統: CentOS7.5
主機名 |
IP |
軟體 |
k8s-master1 (2核4G) |
主網絡卡eth1:172.16.1.81 |
docker-ce-19.03.9、kubernetes-1.20 |
k8s-node1 (4核8G) |
主網絡卡eth1:172.16.1.83 |
docker-ce-19.03.9、kubernetes-1.20 |
3架構圖
在172.16.1.81、83節點上操作
(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.81、83節點上操作
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只能叢集內部訪問,因此修改Service為NodePort型別,暴露到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-admin的secrets名稱
# 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.20單Master叢集就完成了,k8s叢集全部pod狀態如下所示。
8 切換容器引擎為Containerd
在172.16.1.81、83節點上操作
參考資料:https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
(1) 容器執行時
1) 為了在 Pod 中執行容器,Kubernetes使用容器執行時(Container Runtime)。你需要在叢集內
每個節點上安裝一個容器執行時以使Pod可以執行在上面。
2) 預設情況下,Kubernetes使用容器執行時介面(Container Runtime Interface,CRI)來與你所
選擇的容器執行時互動。
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管理器。Systemd與cgroup整合緊密,並將為每個systemd單元分配一個
cgroup。你也可以配置容器執行時和kubelet使用cgroupfs。連同systemd一起使用cgroupfs意
味著將有兩個不同的cgroup管理器。
3)單個cgroup管理器將簡化分配資源的檢視,並且預設情況下將對可用資源和使用中的資源具有
更一致的檢視。當有兩個管理器共存於一個系統中時,最終將對這些資源產生兩種檢視。在此領域
人們已經報告過一些案例,某些節點配置讓kubelet和docker使用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 docker與crictl命令對照表
映象相關功能 |
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