使用 kubeadm 建立高可用性叢集
此頁面說明使用 kubeadm 設定高可用性 Kubernetes 叢集的兩種不同方法
- 使用堆疊式控制平面節點。此方法需要較少基礎架構。etcd 成員與控制平面節點共置。
- 使用外部 etcd 叢集。此方法需要更多基礎架構。控制平面節點與 etcd 成員分離。
在繼續之前,您應仔細考量哪種方法最符合您的應用程式與環境需求。高可用性拓撲的選項概述了每種方法的優點與缺點。
如果您在設定 HA 叢集時遇到問題,請在 kubeadm 問題追蹤器中回報這些問題。
另請參閱升級文件。
注意
此頁面未說明在雲端供應商上執行叢集。在雲端環境中,此處記錄的兩種方法都不適用於類型為 LoadBalancer 的 Service 物件,或動態 PersistentVolumes。事前準備
先決條件取決於您為叢集控制平面選擇的拓撲
您需要
- 三部或更多符合 kubeadm 控制平面節點最低需求的機器。擁有奇數個控制平面節點有助於在機器或區域故障時進行領導者選舉。
- 包括已設定並可運作的 容器執行期
- 三部或更多符合 kubeadm 工作節點最低需求的機器
- 包括已設定並可運作的容器執行期
- 叢集中所有機器之間的完整網路連線能力 (公用或私有網路)
- 所有機器上的超級使用者權限,使用
sudo
- 您可以使用不同的工具;本指南在範例中使用
sudo
。
- 您可以使用不同的工具;本指南在範例中使用
- 從一部裝置到系統中所有節點的 SSH 存取權
- 所有機器上皆已安裝
kubeadm
與kubelet
。
請參閱 堆疊式 etcd 拓撲 以取得背景資訊。
您需要
- 三部或更多符合 kubeadm 控制平面節點最低需求的機器。擁有奇數個控制平面節點有助於在機器或區域故障時進行領導者選舉。
- 包括已設定並可運作的 容器執行期
- 三部或更多符合 kubeadm 工作節點最低需求的機器
- 包括已設定並可運作的容器執行期
- 叢集中所有機器之間的完整網路連線能力 (公用或私有網路)
- 所有機器上的超級使用者權限,使用
sudo
- 您可以使用不同的工具;本指南在範例中使用
sudo
。
- 您可以使用不同的工具;本指南在範例中使用
- 從一部裝置到系統中所有節點的 SSH 存取權
- 所有機器上皆已安裝
kubeadm
與kubelet
。
您還需要
- 三部或更多額外機器,將成為 etcd 叢集成員。在 etcd 叢集中擁有奇數個成員是實現最佳投票仲裁的要求。
- 這些機器同樣需要安裝
kubeadm
與kubelet
。 - 這些機器也需要已設定並可運作的容器執行期。
- 這些機器同樣需要安裝
請參閱 外部 etcd 拓撲 以取得背景資訊。
容器映像檔
每部主機應具有從 Kubernetes 容器映像檔登錄檔 registry.k8s.io
讀取與提取映像檔的權限。如果您想要部署主機無法存取以提取映像檔的高可用性叢集,這是可行的。您必須透過其他方式確保相關主機上已提供正確的容器映像檔。
命令列介面
若要在叢集設定完成後管理 Kubernetes,您應在您的 PC 上安裝 kubectl。在每個控制平面節點上安裝 kubectl
工具也很有用,因為這有助於疑難排解。
兩種方法的第一步
為 kube-apiserver 建立負載平衡器
注意
負載平衡器有許多組態。以下範例僅為其中一種選項。您的叢集需求可能需要不同的組態。建立名稱可解析為 DNS 的 kube-apiserver 負載平衡器。
在雲端環境中,您應將控制平面節點置於 TCP 轉發負載平衡器之後。此負載平衡器將流量分配給其目標清單中的所有健康控制平面節點。apiserver 的健康狀態檢查是在 kube-apiserver 監聽的連接埠 (預設值
:6443
) 上進行 TCP 檢查。不建議在雲端環境中直接使用 IP 位址。
負載平衡器必須能夠在 apiserver 連接埠上與所有控制平面節點通訊。它也必須允許在其監聽連接埠上接收傳入流量。
確保負載平衡器的位址始終與 kubeadm 的
ControlPlaneEndpoint
位址相符。閱讀 軟體負載平衡選項 指南以取得更多詳細資訊。
將第一個控制平面節點新增至負載平衡器,並測試連線
nc -v <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
將此輸出複製到文字檔。稍後您將需要它來將控制平面和工作節點加入叢集。
當
--upload-certs
與kubeadm init
一起使用時,主要控制平面的憑證會被加密並上傳到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 設定相同
- 確保第一個控制平面節點已完全初始化。
- 使用您儲存到文字檔的加入命令,加入每個控制平面節點。建議一次加入一個控制平面節點。
- 別忘了來自
--certificate-key
的解密金鑰在兩小時後過期,預設情況下。
啟動控制平面後的常見任務
安裝工作節點
工作節點可以使用您先前儲存的命令加入叢集,該命令是來自 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 agent。如果您不完全信任節點上使用者會話的安全性,請考慮其他方法。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