Kubernetes集群部署筆記
- 2021 年 9 月 1 日
- 筆記
- containerd, Debian, DevOps, docker, flannel, kubeadm, Kubernetes, metallb, podman
本作品由Galen Suen採用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。由原作者轉載自個人站點。
概述
本文用於整理基於Debian作業系統使用kubeadm工具部署Kubernetes集群的操作過程。該集群部署於一組本地虛擬伺服器上,用於學習Kubernetes
的基礎概念和基本操作,並作為今後其他學習內容的實踐部署提供環境。
考慮到不同的網路環境,本文中一些步驟會記錄兩種操作方式,通過鏡像等方式加快部署效率、避免部署錯誤。有關鏡像同步的方案,可參考附件內容中的同步所需鏡像。
隨著作業系統和各相關組件版本的更新,筆者將在驗證通過後對本文進行補充和更新。
伺服器
受限於本地物理伺服器的配置,虛擬伺服器配置規劃如下表。
Host | OS | IP | CPU | RAM | K8s | Roles |
---|---|---|---|---|---|---|
k8s-n0 |
Debian 10.10 | 10.0.0.50 |
2 vCPUs | 4 GB | v1.22.1 | control-plane , master |
k8s-n1 |
Debian 10.10 | 10.0.0.51 |
4 vCPUs | 6 GB | v1.22.1 | |
k8s-n2 |
Debian 10.10 | 10.0.0.52 |
4 vCPUs | 6 GB | v1.22.1 | |
k8s-n3 |
Debian 10.10 | 10.0.0.53 |
4 vCPUs | 6 GB | v1.22.1 |
所有虛擬伺服器CPU均為amd64
架構。
截止本文發布時,筆者基於最新Debian 11 (“bullseye”)部署的集群仍然存在一些問題,故暫且發布基於Debian 10 (“buster”)的筆記。
網路環境
本地網路IP地址範圍為10.0.0.0/24
,其中:
10.0.0.2
–10.0.0.99
為靜態分配,供虛擬伺服器使用10.0.0.100
–10.0.0.200
用於DHCP
自動分配10.0.0.201
–10.0.0.254
為靜態分配,供負載均衡器使用
其他組件
-
容器運行時
containerd v1.4.9 -
Pod網路組件
flannel v0.14.0 -
負載均衡器
metallb v0.10.2 -
持久卷供應
local-path-provisioner v0.0.20
準備工作
伺服器配置
本文假設伺服器硬體和作業系統已經配置完畢,所有伺服器上都已經正確配置了ssh
服務和sudo
許可權。
作為參考,這裡記錄筆者配置sudo
許可權和ssh
服務的過程。
-
配置
sudo
許可權如操作人員的登錄用戶已經被正確配置了sudo許可權,可跳過此步驟。
本示例中,操作人員的登錄用戶名為
tiscs
,需要實際環境情況進行替換。# 使用root用戶登錄系統 # 安裝sudo,並配置sudo許可權 apt update apt install sudo echo "tiscs ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/tiscs # 這在生產環境絕不是個好主意,僅僅是為了演練環境操作方便
-
配置
ssh
服務# 安裝openssh-server,並配置ssh服務為自動啟動 sudo apt update sudo apt install openssh-server sudo systemctl enable ssh --now
配置過程
安裝容器運行時
本文配置的集群選擇containerd作為容器運行時。
在所有節點上執行如下操作。
-
配置模組載入
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 sudo sysctl --system
-
配置APT源
# 安裝依賴項 sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# 根據網路環境選擇官方源或鏡像源 # 1. 配置Docker官方源 curl -fsSL //download.docker.com/linux/debian/gpg \ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg echo "deb [arch=amd64] //download.docker.com/linux/debian $(lsb_release -cs) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 2. 配置Aliyun鏡像源 curl -fsSL //mirrors.aliyun.com/docker-ce/linux/debian/gpg \ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg echo "deb [arch=amd64] //mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
安裝containerd
sudo apt update sudo apt install -y containerd.io
-
初始化配置
sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml
# 配置systemd cgroup驅動 sudo sed -i 's|\(\s\+\)\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]|\1\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]\n\1 SystemdCgroup = true|g' /etc/containerd/config.toml
# (可選)配置阿里雲容器鏡像源 sudo sed -i 's/registry-1.docker.io/xrb7j2ja.mirror.aliyuncs.com/g' /etc/containerd/config.toml # (可選)配置sandbox image地址 # 為了方便,這裡配置為與kubelet所需相同的版本(可以使用kubeadm config images list命令查看) sudo sed -i 's|k8s.gcr.io/pause:.\+|registry.cn-beijing.aliyuncs.com/choral-k8s/pause:3.5|g' /etc/containerd/config.toml
# 重啟containerd服務 sudo systemctl restart containerd
安裝kubeadm
在所有節點上執行如下操作。
-
配置APT源
# 根據網路環境選擇官方源或鏡像源 # 1. 配置Docker官方源 curl -fsSL //packages.cloud.google.com/apt/doc/apt-key.gpg \ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg echo "deb //apt.kubernetes.io/ kubernetes-xenial main" \ | sudo tee /etc/apt/sources.list.d/kubernetes.list # 2. 配置Aliyun鏡像源 curl -fsSL //mirrors.aliyun.com/docker-ce/linux/debian/gpg \ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg echo "deb //mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" \ | sudo tee /etc/apt/sources.list.d/kubernetes.list
-
安裝
kubeadm
、kubelet
和kubectl
sudo apt install -y kubelet=1.22.1-00 kubeadm=1.22.1-00 kubectl=1.22.1-00 sudo apt-mark hold kubelet kubeadm kubectl
-
安裝並配置
crictl
(可選)可以安裝並配置
crictl
,便於在k8s
節點上管理容器運行時。# 安裝crictl工具 sudo apt install -y cri-tools # 配置crictl使用containerd運行時 cat <<EOF | sudo tee /etc/crictl.yaml runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false EOF # 驗證crictl配置 sudo crictl images # 列出所有鏡像
配置控制平面節點
在k8s-n0
節點上執行如下操作。
-
預先下載所需鏡像
# 查看所需的鏡像列表 kubeadm config images list --kubernetes-version=v1.22.1 # --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s # 1. 使用默認容器鏡像倉庫 sudo kubeadm config images pull --kubernetes-version=v1.22.1 # 2. 使用自建容器鏡像倉庫 sudo kubeadm config images pull --kubernetes-version=v1.22.1 \ --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
-
初始化控制平面節點
# --apiserver-advertise-address: 當前節點IP地址 # --pod-network-cidr : Pod網路地址段(CIDR: //datatracker.ietf.org/doc/html/rfc4632) # 1. 使用默認容器鏡像倉庫 sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \ --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 # 2. 使用自建容器鏡像倉庫 sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \ --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 \ --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
執行完上述操作後,
kubeadm init
命令會輸出用於添加節點到集群中的說明,請保存該說明中的內容。示例如下:sudo kubeadm join 10.0.0.50:6443 \ --token vafq03.5dl6j1cbcd1yzf3c \ --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
-
添加kubectl配置(可選)
mkdir -p ~/.kube sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config
-
安裝網路組件
# 1. 使用默認鏡像倉庫(quay.io/coreos)安裝 kubectl apply -f //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 2. 使用給自定義鏡像倉庫安裝 kubectl apply -f //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \ | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f - # 2.1 如果訪問raw.githubusercontent.com上的文件存在網路問題 # 可以使用jsdelivr提供的GitHub CDN地址(//www.jsdelivr.com/github) curl -s //cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml \ | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f -
添加工作節點
在k8s-n1
、k8s-n2
和k8s-n3
節點上執行如下操作。該操作中需要的token值和hash值通過上述步驟中的kubeadm init
操作獲取。
-
添加工作節點
sudo kubeadm join 10.0.0.50:6443 \ --token vafq03.5dl6j1cbcd1yzf3c \ --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
-
查看節點狀態
在
k8s-n0
節點上執行如下操作。kubectl get nodes kubectl top nodes
安裝Helm工具(可選)
本文暫不涉及使用helm
執行的操作,該步驟可選。
-
安裝Helm工具
# 下載並安裝 curl -sL //get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz | tar xzf - linux-amd64/helm sudo cp ./linux-amd64/helm /usr/local/bin/helm rm -rf ./linux-amd64 sudo chown root:root /usr/local/bin/helm sudo chmod 755 /usr/local/bin/helm # 驗證helm安裝 helm version
安裝Metrics Server(可選)
部署metrics server
以啟用指標服務,未安裝metrics server
前,kubectl top
命令無法正常執行。
在k8s-n0
節點上執行如下操作。
-
執行清單文件
這裡需要注意,為解決證書錯誤,需要添加
metrics-server
容器的參數--kubelet-insecure-tls
,這裡選擇通過sed
命令修改清單文件後再使用kubectl
執行。# 1. 使用官方鏡像地址直接安裝 curl -sL //github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \ | sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f - # 1.1 為避免特殊網路環境中的清單文件載入問題,可以使用FastGit提供的加速方案 curl -sL //endpoint.fastgit.org///github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \ | sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f - # 2. 使用自定義鏡像地址安裝 curl -sL //endpoint.fastgit.org///github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \ | sed \ -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" \ -e "s|k8s.gcr.io/metrics-server|registry.cn-beijing.aliyuncs.com/choral-k8s|g" \ | kubectl apply -f -
#
安裝負載均衡組件
由雲服務商提供的Kubernetes
服務,通常會提供內置的負載均衡實現。而筆者部署環境為私有環境,需要一個輕量的負載均衡實現以支撐LoadBalancer
類型的服務。
筆者選擇MetalLB作為負載均衡實現,配置為二層網路模式。LoadBalancer
地址範圍配置為10.0.0.201-10.0.0.254
,需根據具體網路環境進行修改。
在k8s-n0
節點上執行如下操作。
-
安裝
MetalLB
# 創建用於部署MetalLB的命名空間 kubectl create namespace metallb-system # 創建必須的配置文件 cat <<EOF | kubectl apply -f - --dry-run=client apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: - 10.0.0.201-10.0.0.254 EOF # 1. 直接執行清單文件 kubectl apply -f //raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml # 1.1 為避免特殊網路環境中的清單文件載入問題,可以使用jsdelivr提供的加速方案加速地址 kubectl apply -f //cdn.jsdelivr.net/gh/metallb/[email protected]/manifests/metallb.yaml # 2. 替換命名空間。命名空間需要與剛剛創建的ConfigMap相同。 curl -sL //cdn.jsdelivr.net/gh/metallb/[email protected]/manifests/metallb.yaml \ | sed -e "s|namespace: metallb-system|namespace: kube-system|g" | kubectl apply -f -
安裝持久卷供應程式
Kubernetes
內置的local-storage
存儲類無法動態供應卷,為便於基於該環境演練時自動創建持久卷,選擇使用local-path-provisioner
作為持久卷供應程式。
-
創建所需的目錄
在所有節點上執行如下操作。
sudo mkdir -p /opt/local-path-provisioner
-
安裝
local-path-provisioner
在
k8s-n0
節點上執行如下操作。# 1. 使用官方清單文件地址直接安裝 kubectl apply -f //raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml # 1.1 同樣可以使用jsdelivr提供的加速方案 kubectl apply -f //cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml # 2. 替換命名空間 curl -s //cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml \ | sed \ -e "1,6d" \ -e "s/local-path-storage/kube-system/" \ | kubectl apply -f -
-
配置默認存儲類
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
檢查集群工作狀態
在k8s-n0
節點上執行如下操作。
-
查看節點狀態
kubectl get nodes
kubectl top nodes
-
查看Pod狀態
kubectl get pods -A
kubectl top pods -A
附加內容
同步所需鏡像
由於特殊網路環境問題,需要同步kubelet所需鏡像至其他鏡像倉庫的,可參考如下操作。
筆者開發環境中使用podman管理容器和鏡像,已將docker
設置為podman
的別名(alias docker=podman
)。
-
同步kubelet所需鏡像
首先,需要創建私有鏡像倉庫認證憑據。
# 根據需要將`registry.cn-beijing.aliyuncs.com`替換為私有鏡像倉庫地址 docker login registry.cn-beijing.aliyuncs.com
創建一個腳本
gcr_mirror_sync.sh
,內容如下。# gcr_mirror_sync.sh # 根據需要將`registry.cn-beijing.aliyuncs.com/choral-k8s/`替換為私有鏡像倉庫地址 while read o do { t=$(echo $o | sed 's|k8s.gcr.io.*/|registry.cn-beijing.aliyuncs.com/choral-k8s/|g') docker pull $o docker tag $o $t docker push $t docker rmi $o docker rmi $t } done < "${1:-/dev/stdin}"
該腳本有兩種使用方法。
kubeadm config images list --kubernetes-version=v1.22.1 | bash gcr_mirror_sync.sh
# 列出所需鏡像列表並保存到文件 kubeadm config images list --kubernetes-version=v1.22.1 > gcr-image-list # 拷貝該文件至gcr_mirror_sync.sh所在主機,然後執行該腳本 bash gcr_mirror_sync.sh gcr-image-list
-
同步附加組件鏡像
# 根據需要將`registry.cn-beijing.aliyuncs.com/choral-k8s/`替換為私有鏡像倉庫地址。 # 同步metrics server所需鏡像 docker pull k8s.gcr.io/metrics-server/metrics-server:v0.5.0 docker tag k8s.gcr.io/metrics-server/metrics-server:v0.5.0 registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0 docker push registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0 docker rmi k8s.gcr.io/metrics-server/metrics-server:v0.5.0 docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0 # 同步flannel所需鏡像 docker pull quay.io/coreos/flannel:v0.14.0 docker tag quay.io/coreos/flannel:v0.14.0 registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0 docker push registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0 docker rmi quay.io/coreos/flannel:v0.14.0 docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
參考資料
-
//kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
-
//kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
-
//github.com/flannel-io/flannel/blob/master/Documentation/kubernetes.md