本作品由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.9Pod網路元件
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 https://download.docker.com/linux/debian/gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 2. 配置Aliyun映象源
curl -fsSL https://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] https://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 https://packages.cloud.google.com/apt/doc/apt-key.gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list # 2. 配置Aliyun映象源
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
echo "deb https://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: https://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 https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 2. 使用給自定義映象倉庫安裝
kubectl apply -f https://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地址(https://www.jsdelivr.com/github)
curl -s https://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 https://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 https://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 https://endpoint.fastgit.org/https://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 https://endpoint.fastgit.org/https://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 https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
# 1.1 為避免特殊網路環境中的清單檔案載入問題,可以使用jsdelivr提供的加速方案加速地址
kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/[email protected]/manifests/metallb.yaml # 2. 替換名稱空間。名稱空間需要與剛剛建立的ConfigMap相同。
curl -sL https://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 https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
# 1.1 同樣可以使用jsdelivr提供的加速方案
kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml # 2. 替換名稱空間
curl -s https://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
參考資料
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://github.com/flannel-io/flannel/blob/master/Documentation/kubernetes.md