本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Kubernetes 資料平面
選取 EC2 執行個體類型可能是客戶面臨的最困難決策之一,因為在具有多個工作負載的叢集中。沒有one-size-fits解決方案。以下是一些秘訣,可協助您避免擴展運算的常見陷阱。
自動節點自動擴展
我們建議您使用節點自動調整規模,以減少混音並與 Kubernetes 深度整合。建議大規模叢集使用受管節點群組和 Karpenter
受管節點群組將為您提供 Amazon EC2 Auto Scaling 群組的彈性,並為受管升級和組態提供額外優勢。它可以使用 Kubernetes Cluster Autoscaler
Karpenter 是由 AWS 建立的開放原始碼、工作負載原生節點自動擴展器。它會根據資源 (例如 GPU) 的工作負載需求,以及污點和容錯 (例如區域分散) 來擴展叢集中的節點,而無需管理節點群組。節點直接從 EC2 建立,可避免預設節點群組配額 - 每個群組 450 個節點 - 並提供更大的執行個體選擇彈性,並降低營運開銷。我們建議客戶盡可能使用 Karpenter。
使用許多不同的 EC2 執行個體類型
每個 AWS 區域每個執行個體類型的可用執行個體數量有限。如果您建立的叢集僅使用一種執行個體類型,並將節點數量擴展到超過該區域的容量,您會收到沒有執行個體可用的錯誤。為了避免此問題,您不應任意限制叢集中可以使用的執行個體類型。
根據預設,Karpenter 將使用廣泛的相容執行個體類型,並根據待定工作負載需求、可用性和成本在佈建時挑選執行個體。您可以擴大 NodePoolskarpenter.k8s.aws/instance-category
金鑰中使用的執行個體類型清單。
Kubernetes Cluster Autoscaler 需要類似大小的節點群組,才能持續擴展。您應該根據 CPU 和記憶體大小建立多個群組,並獨立擴展。使用 ec2-instance-selector
ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16 a1.2xlarge a1.4xlarge a1.metal c4.4xlarge c4.8xlarge c5.12xlarge c5.18xlarge c5.24xlarge c5.2xlarge c5.4xlarge c5.9xlarge c5.metal
偏好較大的節點來減少 API 伺服器負載
決定要使用的執行個體類型時,較少的大型節點會對 Kubernetes 控制平面造成較少的負載,因為會有較少的 kubelet 和執行中的 DaemonSets。不過,大型節點可能無法完全使用,就像較小的節點一樣。節點大小應根據您的工作負載可用性和擴展需求進行評估。
具有三個 u-24tb1.metal 執行個體 (24 TB 記憶體和 448 個核心) 的叢集有 3 個 kubelet,預設每個節點限制為 110 個 Pod。如果您的 Pod 各使用 4 個核心,則可能預期會發生這種情況 (4 個核心 x 110 = 440 個核心/節點)。使用 3 節點叢集時,您處理執行個體事件的能力會很低,因為 1 個執行個體中斷可能會影響叢集的 1/3。您應該在工作負載中指定節點需求和 Pod,以便 Kubernetes 排程器可以正確放置工作負載。
工作負載應定義所需的資源,以及透過污點、容錯和 PodTopologySpread
如果資源可用,Kubernetes 排程器會自動嘗試將工作負載分散到可用區域和主機。如果沒有可用的容量,Kubernetes Cluster Autoscaler 會嘗試在每個可用區域中平均新增節點。除非工作負載指定其他要求,否則 Karpenter 將嘗試盡可能快速且經濟實惠地新增節點。
若要強制工作負載隨著排程器和新節點分散到可用區域,您應該使用 topologySpreadConstraints:
spec: topologySpreadConstraints: - maxSkew: 3 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: dev: my-deployment - maxSkew: 2 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: dev: my-deployment
使用類似的節點大小來實現一致的工作負載效能
工作負載應定義需要執行的節點大小,以允許一致的效能和可預測的擴展。請求 500 公尺 CPU 的工作負載在具有 4 個核心的執行個體上的執行方式與具有 16 個核心的執行個體上的執行方式不同。避免使用爆量 CPUs執行個體類型,例如 T 系列執行個體。
為了確保工作負載獲得一致的效能,工作負載可以使用支援的 Karpenter 標籤
kind: deployment ... spec: template: spec: containers: nodeSelector: karpenter.k8s.aws/instance-size: 8xlarge
使用 Kubernetes Cluster Autoscaler 在叢集中排程的工作負載,應根據標籤比對將節點選擇器與節點群組進行比對。
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/nodegroup operator: In values: - 8-core-node-group # match your node group name
有效率地使用運算資源
運算資源包括 EC2 執行個體和可用區域。有效使用運算資源可提高您的可擴展性、可用性、效能,並降低您的總成本。在具有多個應用程式的自動擴展環境中,高效的資源使用非常困難。建立 Karpenter
Karpenter 允許工作負載宣告所需的運算資源類型,而無需先建立節點群組或設定特定節點的標籤污點。如需詳細資訊,請參閱 Karpenter 最佳實務。請考慮在 Karpenter 佈建器中啟用整合,以取代使用率不足的節點。
自動化 Amazon Machine Image (AMI) 更新
將工作者節點元件保持在最新狀態,將確保您擁有最新的安全修補程式和與 Kubernetes API 相容的功能。更新 kubelet 是 Kubernetes 功能最重要的元件,但自動化作業系統、核心和本機安裝的應用程式修補程式將減少您擴展時的維護。
建議您為節點映像使用最新的 Amazon EKS 最佳化 Amazon Linux 2 或 Amazon EKS 最佳化 Bottlerocket AMI。Karpenter 將自動使用最新的可用 AMI
對於受管節點群組,您需要在可用於修補程式版本時,使用新的 AMI IDs 更新 Auto Scaling 群組 (ASG) 啟動範本。AMI 次要版本 (例如 1.23.5 到 1.24.3) 將可在 EKS 主控台和 API 中做為節點群組的升級。修補程式發行版本 (例如 1.23.5 到 1.23.6) 不會顯示為節點群組的升級。如果您想要讓節點群組與 AMI 修補程式版本保持最新狀態,您需要建立新的啟動範本版本,並讓節點群組將執行個體取代為新的 AMI 版本。
您可以從此頁面找到最新的可用 AMI,或使用 AWS CLI。
aws ssm get-parameter \ --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \ --query "Parameter.Value" \ --output text
針對容器使用多個 EBS 磁碟區
EBS 磁碟區具有根據磁碟區類型 (例如 gp3) 和磁碟大小的輸入/輸出 (I/O) 配額。如果您的應用程式與主機共用單一 EBS 根磁碟區,這可能會耗盡整個主機的磁碟配額,並導致其他應用程式等待可用容量。如果應用程式將檔案寫入其浮水印分割區、從主機掛載本機磁碟區,以及根據所使用的記錄代理程式登入標準輸出 (STDOUT),則會寫入磁碟。
為了避免磁碟 I/O 耗盡,您應該將第二個磁碟區掛載到容器狀態資料夾 (例如 /run/containerd),請使用個別的 EBS 磁碟區進行工作負載儲存,並停用不必要的本機記錄。
若要使用 eksctl
managedNodeGroups: - name: al2-workers amiFamily: AmazonLinux2 desiredCapacity: 2 volumeSize: 80 additionalVolumes: - volumeName: '/dev/sdz' volumeSize: 100 preBootstrapCommands: - | "systemctl stop containerd" "mkfs -t ext4 /dev/nvme1n1" "rm -rf /var/lib/containerd/*" "mount /dev/nvme1n1 /var/lib/containerd/" "systemctl start containerd"
如果您使用 terraform 佈建節點群組,請參閱 EKS terraform 藍圖blockDeviceMappings
若要將 EBS 磁碟區直接掛載到您的 Pod,您應該使用 AWS EBS CSI 驅動程式
--- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ebs-sc provisioner: ebs.csi.aws.com volumeBindingMode: WaitForFirstConsumer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ebs-claim spec: accessModes: - ReadWriteOnce storageClassName: ebs-sc resources: requests: storage: 4Gi --- apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: public.ecr.aws/docker/library/nginx volumeMounts: - name: persistent-storage mountPath: /data volumes: - name: persistent-storage persistentVolumeClaim: claimName: ebs-claim
如果工作負載使用 EBS 磁碟區,請避免具有低 EBS 連接限制的執行個體
EBS 是工作負載擁有持久性儲存的最簡單方法之一,但也附帶可擴展性限制。每個執行個體類型都有可連接的 EBS 磁碟區數量上限。工作負載需要宣告應該在哪些執行個體類型上執行,並限制具有 Kubernetes 污點的單一執行個體上的複本數量。
停用不必要的磁碟記錄
避免不必要的本機記錄,方法是不要在生產環境中使用偵錯記錄執行應用程式,並停用經常讀取和寫入磁碟的記錄。日誌記錄是本機日誌記錄服務,可將日誌緩衝區保留在記憶體中,並定期排清至磁碟。日誌優先於將每行立即記錄到磁碟的 syslog。停用 syslog 也會降低您需要的總儲存量,並避免需要複雜的日誌輪換規則。若要停用 syslog,您可以將下列程式碼片段新增至 cloud-init 組態:
runcmd: - [ systemctl, disable, --now, syslog.service ]
當作業系統更新速度為必要時,會備妥修補程式執行個體
重要
只有在需要時才應完成就地修補執行個體。Amazon 建議將基礎設施視為不可變且徹底測試透過較低環境提升的更新,就像應用程式一樣。本節適用於無法做到的情況。
在現有的 Linux 主機上安裝套件需要幾秒鐘的時間,而不會中斷容器化工作負載。套件可以安裝和驗證,無需封鎖、耗盡或取代執行個體。
若要取代執行個體,您必須先建立、驗證和分發新的 AMIs。執行個體需要建立替換,且舊執行個體需要封鎖和耗盡。然後,需要在新執行個體上建立工作負載,並針對所有需要修補的執行個體進行驗證和重複。安全地取代執行個體需要數小時、數天或數週的時間,而不會中斷工作負載。
Amazon 建議使用從自動化宣告式系統建置、測試和提升的不可變基礎設施,但如果您需要快速修補系統,則需要修補系統,並在有新的 AMIs 可用時予以取代。由於修補和取代系統之間的時間差異很大,我們建議您在需要時使用 AWS Systems Manager Patch Manager 自動修補節點。
修補節點可讓您快速推出安全性更新,並在 AMI 更新後定期取代執行個體。如果您使用作業系統搭配唯讀根檔案系統,例如 Flatcar Container Linux