使用 kubeadm 建立高可用叢集
本頁面介紹兩種使用 kubeadm 設定高可用 Kubernetes 叢集的方法。
- 使用堆疊式控制平面節點。這種方法所需的基礎設施較少。etcd 成員和控制平面節點位於同一位置。
- 使用外部 etcd 叢集。這種方法所需的基礎設施較多。控制平面節點和 etcd 成員是分離的。
在繼續之前,您應該仔細考慮哪種方法最能滿足您的應用程式和環境需求。高可用拓撲選項概述了每種方法的優缺點。
如果在設定高可用叢集時遇到問題,請在 kubeadm 問題跟蹤器中報告。
另請參閱升級文件。
注意
本頁面不涉及在雲提供商上執行叢集。在雲環境中,此處介紹的兩種方法都不適用於型別為 LoadBalancer 的 Service 物件,或動態 PersistentVolumes。準備工作
前提條件取決於您為叢集控制平面選擇的拓撲
您需要
- 三臺或更多滿足 kubeadm 最低要求的控制平面節點機器。擁有奇數個控制平面節點有助於在機器或區域故障時進行領導者選舉。
- 包括一個已設定並執行的容器執行時
- 三臺或更多滿足 kubeadm 最低要求的 worker 節點機器
- 包括一個已設定並執行的容器執行時
- 叢集中所有機器之間的完整網路連線(公共或私有網路)
- 所有使用
sudo
的機器上的超級使用者許可權- 您可以使用不同的工具;本指南在示例中使用
sudo
。
- 您可以使用不同的工具;本指南在示例中使用
- 從一臺裝置到系統中所有節點的 SSH 訪問
- 所有機器上已安裝
kubeadm
和kubelet
。
請參閱堆疊式 etcd 拓撲以瞭解上下文。
您需要
- 三臺或更多滿足 kubeadm 最低要求的控制平面節點機器。擁有奇數個控制平面節點有助於在機器或區域故障時進行領導者選舉。
- 包括一個已設定並執行的容器執行時
- 三臺或更多滿足 kubeadm 最低要求的 worker 節點機器
- 包括一個已設定並執行的容器執行時
- 叢集中所有機器之間的完整網路連線(公共或私有網路)
- 所有使用
sudo
的機器上的超級使用者許可權- 您可以使用不同的工具;本指南在示例中使用
sudo
。
- 您可以使用不同的工具;本指南在示例中使用
- 從一臺裝置到系統中所有節點的 SSH 訪問
- 所有機器上已安裝
kubeadm
和kubelet
。
您還需要
- 三臺或更多額外的機器,它們將成為 etcd 叢集成員。etcd 叢集中擁有奇數個成員是實現最佳投票仲裁的要求。
- 這些機器同樣需要安裝
kubeadm
和kubelet
。 - 這些機器還需要一個已設定並執行的容器執行時。
- 這些機器同樣需要安裝
請參閱外部 etcd 拓撲以瞭解上下文。
容器映象
每個主機都應該能夠訪問並從 Kubernetes 容器映象倉庫 registry.k8s.io
拉取映象。如果你想部署一個主機無法拉取映象的高可用叢集,這是可能的。你必須透過其他方式確保相關的容器映象已在相關主機上可用。
命令列介面
設定集群后,為了管理 Kubernetes,您應該在您的 PC 上安裝 kubectl。在每個控制平面節點上安裝 kubectl
工具也很有用,因為這有助於故障排除。
兩種方法的首要步驟
為 kube-apiserver 建立負載均衡器
注意
負載均衡器有許多配置。以下示例只是一種選擇。您的叢集要求可能需要不同的配置。建立一個 kube-apiserver 負載均衡器,其名稱可解析為 DNS。
在雲環境中,您應該將控制平面節點放置在 TCP 轉發負載均衡器後面。此負載均衡器將流量分發到其目標列表中所有健康的控制平面節點。apiserver 的健康檢查是對 kube-apiserver 監聽的埠(預設值
:6443
)進行 TCP 檢查。不建議在雲環境中使用 IP 地址。
負載均衡器必須能夠透過 apiserver 埠與所有控制平面節點通訊。它還必須允許在其監聽埠上接收傳入流量。
確保負載均衡器的地址始終與 kubeadm 的
ControlPlaneEndpoint
地址匹配。閱讀軟體負載均衡選項指南以獲取更多詳細資訊。
將第一個控制平面節點新增到負載均衡器,並測試連線
nc -zv -w 2 <LOAD_BALANCER_IP> <PORT>
連線被拒絕是預期的,因為 API 伺服器尚未執行。但是,超時意味著負載均衡器無法與控制平面節點通訊。如果發生超時,請重新配置負載均衡器以與控制平面節點通訊。
將剩餘的控制平面節點新增到負載均衡器目標組。
堆疊式控制平面和 etcd 節點
第一個控制平面節點的步驟
初始化控制平面
sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" --upload-certs
您可以使用
--kubernetes-version
標誌設定要使用的 Kubernetes 版本。建議 kubeadm、kubelet、kubectl 和 Kubernetes 的版本保持一致。--control-plane-endpoint
標誌應設定為負載均衡器的地址或 DNS 和埠。--upload-certs
標誌用於將應在所有控制平面例項之間共享的證書上傳到叢集。如果您希望手動或使用自動化工具在控制平面節點之間複製證書,請刪除此標誌並參考下面的手動證書分發部分。
注意
kubeadm init
標誌--config
和--certificate-key
不能混合使用,因此,如果您想使用 kubeadm 配置,則必須在適當的配置位置(在InitConfiguration
和JoinConfiguration: controlPlane
下)新增certificateKey
欄位。注意
一些 CNI 網路外掛需要額外的配置,例如指定 Pod IP CIDR,而另一些則不需要。請參閱 CNI 網路文件。要新增 Pod CIDR,請傳遞--pod-network-cidr
標誌,或者如果您使用 kubeadm 配置檔案,請在ClusterConfiguration
的networking
物件下設定podSubnet
欄位。輸出類似於
... You can now join any number of control-plane node by running the following command on each as a root: kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07 Please note that the certificate-key gives access to cluster sensitive data, keep it secret! As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward. Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
將此輸出複製到文字檔案。稍後您將需要它來將控制平面和工作節點加入叢集。
當
kubeadm init
與--upload-certs
一起使用時,主控制平面證書被加密並上傳到kubeadm-certs
Secret 中。要重新上傳證書並生成新的解密金鑰,請在已加入叢集的控制平面節點上使用以下命令
sudo kubeadm init phase upload-certs --upload-certs
您還可以在
init
期間指定一個自定義--certificate-key
,該金鑰稍後可由join
使用。要生成此類金鑰,您可以使用以下命令kubeadm certs certificate-key
證書金鑰是十六進位制編碼的字串,是一個大小為 32 位元組的 AES 金鑰。
注意
kubeadm-certs
Secret 和解密金鑰在兩小時後過期。注意
正如命令輸出所述,證書金鑰允許訪問叢集敏感資料,請保密!應用您選擇的 CNI 外掛:按照這些說明安裝 CNI 提供商。確保配置與 kubeadm 配置檔案中指定的 Pod CIDR(如果適用)相對應。
注意
您必須選擇一個適合您用例的網路外掛並在進入下一步之前部署它。如果您不這樣做,將無法正確啟動叢集。輸入以下命令,觀察控制平面元件的 Pod 啟動
kubectl get pod -n kube-system -w
其餘控制平面節點的步驟
對於每個額外的控制平面節點,您應該
執行之前在第一個節點上由
kubeadm init
輸出給出的加入命令。它應該看起來像這樣sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07
--control-plane
標誌告訴kubeadm join
建立一個新的控制平面。--certificate-key ...
將導致控制平面證書從叢集中的kubeadm-certs
Secret 下載,並使用給定的金鑰解密。
您可以並行加入多個控制平面節點。
外部 etcd 節點
使用外部 etcd 節點設定叢集與堆疊式 etcd 的過程類似,不同之處在於您應該首先設定 etcd,並且應該在 kubeadm 配置檔案中傳遞 etcd 資訊。
設定 etcd 叢集
按照這些說明設定 etcd 叢集。
按照此處所述設定 SSH。
將以下檔案從叢集中的任何 etcd 節點複製到第一個控制平面節點
export CONTROL_PLANE="ubuntu@10.0.0.7" scp /etc/kubernetes/pki/etcd/ca.crt "${CONTROL_PLANE}": scp /etc/kubernetes/pki/apiserver-etcd-client.crt "${CONTROL_PLANE}": scp /etc/kubernetes/pki/apiserver-etcd-client.key "${CONTROL_PLANE}":
- 將
CONTROL_PLANE
的值替換為第一個控制平面節點的user@host
。
- 將
設定第一個控制平面節點
建立一個名為
kubeadm-config.yaml
的檔案,其內容如下--- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration kubernetesVersion: stable controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" # change this (see below) etcd: external: endpoints: - https://ETCD_0_IP:2379 # change ETCD_0_IP appropriately - https://ETCD_1_IP:2379 # change ETCD_1_IP appropriately - https://ETCD_2_IP:2379 # change ETCD_2_IP appropriately caFile: /etc/kubernetes/pki/etcd/ca.crt certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
注意
堆疊式 etcd 和外部 etcd 的區別在於,外部 etcd 設定需要一個配置檔案,其中在etcd
的external
物件下包含 etcd 端點。在堆疊式 etcd 拓撲的情況下,這會自動管理。將配置模板中的以下變數替換為叢集的適當值
LOAD_BALANCER_DNS
LOAD_BALANCER_PORT
ETCD_0_IP
ETCD_1_IP
ETCD_2_IP
以下步驟與堆疊式 etcd 設定類似
在此節點上執行
sudo kubeadm init --config kubeadm-config.yaml --upload-certs
。將返回的輸出加入命令寫入文字檔案以備後用。
應用您選擇的 CNI 外掛。
注意
您必須選擇一個適合您用例的網路外掛並在進入下一步之前部署它。如果您不這樣做,將無法正確啟動叢集。
其餘控制平面節點的步驟
這些步驟與堆疊式 etcd 設定相同
- 確保第一個控制平面節點完全初始化。
- 使用您儲存到文字檔案中的 join 命令加入每個控制平面節點。建議一次加入一個控制平面節點。
- 別忘了
--certificate-key
的解密金鑰預設在兩小時後過期。
引導控制平面後的常見任務
安裝 worker 節點
工作節點可以使用您之前作為 kubeadm init
命令的輸出儲存的命令加入叢集
sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
手動證書分發
如果您選擇不使用帶有 --upload-certs
標誌的 kubeadm init
,這意味著您將不得不手動將證書從主控制平面節點複製到加入的控制平面節點。
有很多方法可以做到這一點。以下示例使用 ssh
和 scp
如果您想從一臺機器控制所有節點,則需要 SSH。
在您的主裝置上啟用 ssh-agent,該裝置可以訪問系統中所有其他節點
eval $(ssh-agent)
將您的 SSH 身份新增到會話中
ssh-add ~/.ssh/path_to_private_key
在節點之間進行 SSH 以檢查連線是否正常工作。
當您 SSH 到任何節點時,新增
-A
標誌。此標誌允許您透過 SSH 登入的節點訪問您 PC 上的 SSH 代理。如果您不完全信任節點上使用者會話的安全性,請考慮其他方法。ssh -A 10.0.0.7
在任何節點上使用 sudo 時,請確保保留環境,以便 SSH 轉發正常工作
sudo -E -s
在所有節點上配置 SSH 後,您應該在執行
kubeadm init
後在第一個控制平面節點上執行以下指令碼。此指令碼會將證書從第一個控制平面節點複製到其他控制平面節點在以下示例中,將
CONTROL_PLANE_IPS
替換為其他控制平面節點的 IP 地址。USER=ubuntu # customizable CONTROL_PLANE_IPS="10.0.0.7 10.0.0.8" for host in ${CONTROL_PLANE_IPS}; do scp /etc/kubernetes/pki/ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/ca.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.pub "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host: scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt # Skip the next line if you are using external etcd scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key done
注意
僅複製上述列表中的證書。kubeadm 將負責為加入的控制平面例項生成其餘證書,並附帶所需的 SAN。如果您錯誤地複製了所有證書,可能會因缺少所需的 SAN 而導致其他節點的建立失敗。然後,在每個加入的控制平面節點上,您必須在執行
kubeadm join
之前執行以下指令碼。此指令碼會將之前從主目錄複製的證書移動到/etc/kubernetes/pki
USER=ubuntu # customizable mkdir -p /etc/kubernetes/pki/etcd mv /home/${USER}/ca.crt /etc/kubernetes/pki/ mv /home/${USER}/ca.key /etc/kubernetes/pki/ mv /home/${USER}/sa.pub /etc/kubernetes/pki/ mv /home/${USER}/sa.key /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/ mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt # Skip the next line if you are using external etcd mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key