本作品由Galen Suen采用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。由原作者轉載自個人站點。
更新記錄
-
2021-09-04- 服務器操作系統由
Debian 10 ("buster")更新至Debian 11 ("bullseye"); - 使用
kube-router代替kube-proxy和flannel實現Service Proxy和Pod Network; - 修復一些代碼錯誤;
- 服務器操作系統由
-
2021-09-08- 部署
kube-router時添加運行參數--advertise-loadbalancer-ip=true;
- 部署
-
2021-09-18Kubernetes版本由v1.22.1更新至v1.22.2;
概述
本文用於整理基於Debian操作系統使用kubeadm工具部署Kubernetes集群的操作過程。該集群部署於一組本地虛擬服務器上,用於學習Kubernetes的基礎概念和基本操作,並作為今后其他學習內容的實踐部署提供環境。
考慮到不同的網絡環境,本文中一些步驟會記錄兩種操作方式,通過鏡像等方式加快部署效率、避免部署錯誤。有關鏡像同步的方案,可參考附件內容中的同步所需鏡像。
隨着操作系統和各相關組件版本的更新,筆者將在驗證通過后對本文進行補充和更新。
服務器
受限於本地物理服務器的配置,虛擬服務器配置規划如下表。
| Host | OS | IP | CPU | RAM | K8s | Roles |
|---|---|---|---|---|---|---|
k8s-n0 |
Debian 11.0 | 10.0.0.50 |
2 vCPUs | 4 GB | v1.22.2 | control-plane, master |
k8s-n1 |
Debian 11.0 | 10.0.0.51 |
4 vCPUs | 8 GB | v1.22.2 | |
k8s-n2 |
Debian 11.0 | 10.0.0.52 |
4 vCPUs | 8 GB | v1.22.2 | |
k8s-n3 |
Debian 11.0 | 10.0.0.53 |
4 vCPUs | 8 GB | v1.22.2 |
所有虛擬服務器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
kube-router v1.3.1 -
負載均衡器
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. 使用Google官方源 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和kubectlsudo apt install -y kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-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.2 # --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s # 1. 使用默認容器鏡像倉庫 sudo kubeadm config images pull --kubernetes-version=v1.22.2 # 2. 使用自建容器鏡像倉庫 sudo kubeadm config images pull --kubernetes-version=v1.22.2 \ --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.2 \ --skip-phases=addon/kube-proxy # 2. 使用自建容器鏡像倉庫 sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \ --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.2 \ --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s \ --skip-phases=addon/kube-proxy執行完上述操作后,
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
安裝網絡組件
-
安裝(已廢棄,使用flannelkube-router代替)# 1. 使用默認鏡像倉庫(quay.io/coreos)安裝 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 2 如果訪問raw.githubusercontent.com上的文件存在網絡問題 # 可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github) kubectl apply -f https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml -
安裝
kube-routercurl -s https://cdn.jsdelivr.net/gh/cloudnativelabs/kube-router@master/daemonset/generic-kuberouter-all-features.yaml \ | sed \ -e "s|%APISERVER%|$(kubectl get cm -n kube-public -o yaml cluster-info | sed -n 's/^ \+server: \(.\+\)/\1/p')|g" \ -e "s|%CLUSTERCIDR%|$(kubectl get cm -n kube-system -o yaml kubeadm-config | sed -n 's/^ \+podSubnet: \(.\+\)/\1/p')|g" \ -e "s|\(\s\+\)args:|\1args:\n\1- \"--advertise-loadbalancer-ip=true\"|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 - 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 # 2. 為避免特殊網絡環境中的清單文件加載問題,可以使用jsdelivr提供的加速方案加速地址 kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml
安裝持久卷供應程序
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 nodeskubectl top nodes -
查看Pod狀態
kubectl get pods -Akubectl 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.2 | bash gcr_mirror_sync.sh# 列出所需鏡像列表並保存到文件 kubeadm config images list --kubernetes-version=v1.22.2 > 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
