14.1 使用 kubeadm 部署 Kubernetes
kubeadm 提供了 kubeadm init 以及 kubeadm join 這兩個指令,作為快速建立 Kubernetes 叢集的常用工具。
版本說明:Kubernetes 版本更新較快 (約每 4 個月一個新版本),本文件基於 Kubernetes 1.36 編寫。更完整的安裝和相容性說明請以 Kubernetes 官方 kubeadm 文件 和 containerd 官方文件 為準。
14.1.1 安裝 containerd
參考安裝 Docker 一節新增 apt/yum 源,之後執行如下指令。
# debian 系
$ sudo apt install containerd.io
# rhel 系
$ sudo yum install containerd.io
14.1.2 設定 containerd
先生成預設設定檔案,然後只調整與 kubeadm 相關的關鍵項:
$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
開啟 /etc/containerd/config.toml,確認 runc 選項使用 systemd cgroup 驅動:
# containerd 2.x(當前預設版本)
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options]
SystemdCgroup = true
# containerd 1.x(舊版本)使用以下路徑,2.x 亦相容
# [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
# SystemdCgroup = true
提示:
containerd config default生成的預設設定會自動使用當前版本的正確路徑。如果你使用的是 containerd 2.x,設定中的外掛路徑將以io.containerd.cri.v1.runtime開頭;如果仍在使用 1.x,則為io.containerd.grpc.v1.cri。
預設設定裡的其它內容通常可以保持不變。修改完成後重啟 containerd:
$ sudo systemctl restart containerd
14.1.3 安裝 kubelet、kubeadm、kubectl、cri-tools、kubernetes-cni
需要在每台機器上安裝以下的軟體套件:
Ubuntu/Debian
$ K8S_MINOR="v1.36"
$ sudo apt-get update
$ sudo apt-get install -y ca-certificates curl gpg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL "https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/deb/Release.key" | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ sudo chmod a+r /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl cri-tools kubernetes-cni
$ sudo apt-mark hold kubelet kubeadm kubectl
CentOS/Fedora
$ K8S_MINOR="v1.36"
$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/rpm/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/rpm/repodata/repomd.xml.key
EOF
$ sudo yum install -y kubelet kubeadm kubectl cri-tools kubernetes-cni
14.1.4 修改核心的執行引數
載入核心模組
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
cgroup v2 要求:必須
Kubernetes v1.36 預設要求節點使用 cgroup v2。kubelet 在 cgroup v1 節點上預設會拒絕啟動,但管理員可以在 kubelet 設定中設定 failCgroupV1: false 來相容 cgroup v1(僅建議用於遺留系統轉場期)。驗證節點是否支援 cgroup v2:
$ mount | grep cgroup2
如果輸出包含 cgroup2,則系統已支援 cgroup v2。對於仍在使用 cgroup v1 的系統(如較舊的 RHEL 8),建議升級核心或更新系統設定以啟用 cgroup v2。
停用 swap:必須
kubelet 預設要求停用 swap,否則可能導致初始化失敗或節點無法加入叢集。
$ sudo swapoff -a
# 如需永久停用,可在 /etc/fstab 中註解 swap 對應行
$ 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 --system
14.1.5 設定 kubelet
為了讓 kubelet 正確執行,我們需要對其進行一些必要的設定。
修改 kubelet.service(可選:IPVS 模式)
注意:kube-proxy 的 IPVS 模式已在 Kubernetes 1.35 中被標記為棄用;Kubernetes 1.36 文件仍將其列為已棄用模式,並推薦遷移到 nftables。新部署應使用預設的 iptables 模式或 nftables 模式(Kubernetes 1.33+ 穩定)。以下 IPVS 設定僅供舊環境參考。
/etc/systemd/system/kubelet.service.d/10-proxy-ipvs.conf 寫入以下內容
# 啟用 ipvs 相關核心模組(已棄用,建議遷移至 nftables)
[Service]
ExecStartPre=-/sbin/modprobe ip_vs
ExecStartPre=-/sbin/modprobe ip_vs_rr
ExecStartPre=-/sbin/modprobe ip_vs_wrr
ExecStartPre=-/sbin/modprobe ip_vs_sh
執行以下指令應用設定。
$ sudo systemctl daemon-reload
14.1.6 部署
安裝設定完成後,我們將分別在 Master 節點和 Worker 節點上進行部署操作。
master
$ sudo systemctl enable containerd
$ sudo systemctl start containerd
$ sudo kubeadm init \
--pod-network-cidr 10.244.0.0/16 \
--cri-socket unix:///run/containerd/containerd.sock \
--v 5
--pod-network-cidr 10.244.0.0/16引數與後續 CNI 外掛有關,這裡以flannel為例,若後續部署其他型別的網路外掛請更改此引數。- kubeadm 預設使用
registry.k8s.io拉取 Kubernetes 控制平面鏡像。受限網路環境可透過 kubeadm 設定檔案中的imageRepository指向受信任映象倉庫;不要把第三方映象倉庫當成通用預設值。
若
kubeadm預檢失敗,應按提示修復缺失依賴、核心引數、swap 或執行時設定。實驗環境確需忽略預檢時,只忽略明確理解且可接受的單項檢查,不建議使用--ignore-preflight-errors=all。
執行成功會輸出
...
[addons] Applied essential addon: CoreDNS
I1116 12:35:13.270407 86677 request.go:538] Throttling request took 181.409184ms, request: POST:https://<CONTROL_PLANE_HOST>:6443/api/v1/namespaces/kube-system/serviceaccounts
I1116 12:35:13.470292 86677 request.go:538] Throttling request took 186.088112ms, request: POST:https://<CONTROL_PLANE_HOST>:6443/api/v1/namespaces/kube-system/configmaps
[addons] Applied essential addon: kube-proxy
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
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 <CONTROL_PLANE_HOST>:6443 --token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<DISCOVERY_TOKEN_CA_CERT_HASH>
node 工作節點
在 另一主機 重複 部署 小節以前的步驟,安裝設定好 kubelet。根據提示,加入到叢集。
$ systemctl enable containerd
$ systemctl start containerd
$ kubeadm join <CONTROL_PLANE_HOST>:6443 \
--token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<DISCOVERY_TOKEN_CA_CERT_HASH> \
--cri-socket unix:///run/containerd/containerd.sock
其中 <CONTROL_PLANE_HOST>、<TOKEN> 和 <DISCOVERY_TOKEN_CA_CERT_HASH> 應使用你自己的 kubeadm init 輸出,不要複用範例值。
14.1.7 檢視服務
所有服務啟動後,透過 crictl 檢視本地實際執行的容器。這些服務大概分為三類:主節點服務、工作節點服務和其它服務。
CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock crictl ps -a
主節點服務
-
apiserver是整個系統的對外介面,提供 RESTful 方式供用戶端和其它元件呼叫; -
scheduler負責對資源進行排程,分配某個 pod 到某個節點上; -
controller-manager負責管理控制器,包括 endpoint-controller (重新整理服務和 pod 的關聯訊息) 和 replication-controller (維護某個 pod 的複製為設定的數值)。
工作節點服務
proxy為 pod 上的服務提供訪問的代理。
其它服務
- Etcd 是所有狀態的儲存資料庫;
14.1.8 使用
將 /etc/kubernetes/admin.conf 複製到 ~/.kube/config
執行 $ kubectl get all -A 檢視啟動的服務。
由於未部署 CNI 外掛,CoreDNS 未正常啟動。如何使用 Kubernetes,請參考後續章節。
14.1.9 部署 CNI
這裡以 flannel 為例進行介紹。
flannel
檢查 podCIDR 設定
$ kubectl get node -o yaml | grep CIDR
# 輸出
podCIDR: 10.244.0.0/16
podCIDRs:
# 注意:以下以 v0.28.4 為範例;安裝前請到 releases 頁面核驗當前版本
# 參見 https://github.com/flannel-io/flannel/releases
$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.28.4/Documentation/kube-flannel.yml
14.1.10 master 節點預設不能執行 pod
如果用 kubeadm 部署一個單節點叢集,預設情況下無法使用,請執行以下指令解除限制
$ kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# 較舊版本使用 master taint
# $ kubectl taint nodes --all node-role.kubernetes.io/master-
# 恢復預設值
# $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/control-plane=true:NoSchedule
...