前言 ??
Kubernetes 社區大約每 4 個月發布次要版本,次要版本包括新增功能和改進。補丁發布更為頻繁(有時每周都會發布),適用于次要版本中的關鍵 Bug 修復。修補程序版本包括針對安全漏洞或主要 bug 的修復。對于受支持版本列表以外的群集,AKS 將不會在正常運行時間或其他方面做出任何保證。為了使AKS版本始終能獲得支持,需要制定計劃將AKS升級至受支持版本。在AKS Kubernetes 發布日歷(https://learn.microsoft.com/zh-cn/azure/aks/supported-kubernetes-versions?tabs=azure-cli#aks-kubernetes-release-calendar)上參考即將推出的版本發布和棄用事項。
AKS版本升級路徑說明?
升級受支持的 AKS 群集時,不能跳過 Kubernetes 次要版本。Kubernetes 控制平面版本傾斜策略不支持跳過次要版本。例如,對于以下升級過程:
-
1.28.x ->1.29.x:允許。
-
1.27.x ->1.28.x:允許。
-
1.27.x ->1.29.x:允許。
若要從 1.27.x ->1.29.x 升級,請執行以下操作:
-
從 1.27.x ->1.28.x 升級。
-
從 1.28.x ->1.29.x 升級。
僅當從不受支持的版本升級回受支持的最低版本時,才能跳過多個版本。例如,如果 1.27 是最低受支持的次要版本,可以從不受支持的 1.25.x 升級到受支持的 1.27.x。 ??
從跳過兩個或更多次要版本的不支持版本執行升級時,執行升級時不保證任何功能,并且不在服務級別協議和有限保修范圍內。運行不受支持的版本的群集具有將控制平面升級與節點池升級分離的靈活性。但是,如果版本明顯過期,建議重新創建群集。
AKS升級策略?
從 Kubernetes 1.19 開始,開源社區已將支持時間延長到 1 年。AKS 承諾啟用修補程序并提供與上游承諾使用量匹配的支持。對于版本 1.19 和更高版本上的 AKS 群集,每年至少升級一次,以便始終使用受支持的版本。
AKS升級將會有什么影響?
-
AKS次要版本升級將會更新棄用API,如果在升級AKS前不對棄用API進行處理,兩個版本的AKS API不兼容,會造成AKS升級失敗和使用棄用API的資源部署失敗。已棄用 API 的遷移指南(https://kubernetes.io/zh-cn/docs/reference/using-api/deprecation-guide/)。
-
所有pod將會重啟。2024年06月06日國內關閉了docker hub鏡像緩存服務,在這期間pod沒有重啟過的在AKS升級后鏡像會丟失,而且無法從docker hub中拉取,從而導致pod拉取鏡像失敗。
-
沒有對節點池預設的labels和Taints在AKS升級后會被清除。
-
會對有依賴性的服務產生影響,需要按照啟動的先后順序重啟服務。
升級步驟?
升級狀態跟蹤表
升級路線?
例:1.22.6 → 1.27.3 → 1.28.9 → 1.29.4
AKS Upgrade PreCheck?
-
在升級前進行AKS現狀檢查,并進行統計,需要處理的郵件發送至各位Owner及時處理。
-
與客戶及涉及到的各個應用溝通時間窗口并安排升級計劃。
-
提前發送郵件book需要參與AKS升級的相關人員(應用開發/Cloud Team/SRE Team)的時間。
檢查是否存在即將廢棄的API?
-
微軟提供的查詢語句
查詢query:
AzureDiagnostics
| where Category == "kube-audit"
| where log_s has 'deprecated' and TimeGenerated > ago(1d)
| extend log = parse_json(tostring(parse_json(log_s)))
| extend removed_release = toreal(tostring(log.annotations['k8s.io/removed-release']))
| where removed_release == '1.26' or removed_release == '1.27'
| extend verb = tostring(log.verb)
| extend userAgent = tostring(log.userAgent)
| extend username = tostring(log.user.username)
| extend resource = tostring(log.objectRef.resource)
| extend apiGroup = tostring(log.objectRef.apiGroup)
| extend apiVersion = tostring(log.objectRef.apiVersion)
| extend requestURI = tostring(split(log.requestURI, '?')[0])
| extend source_ip = tostring(log.sourceIPs[0])
| extend api = strcat(apiGroup, '/', apiVersion)
| project TimeGenerated, userAgent, username, api, resource, verb, requestURI, source_ip, Resource
-
命令檢查廢棄API?
例:從 v1.27 版本開始不再提供 storage.k8s.io/v1beta1 API 版本的 CSIStorageCapacity。
$?kubectl get csistoragecapacities.storage.k8s.io?-A?-o=jsonpath="{$.items[?(@.apiVersion=='storage.k8s.io/v1beta1')].metadata.name}";
注意:在AKS升級前,需要為所有可能的中斷做好準備。 這些中斷包括 API 中斷性變更、棄用以及 Helm 和容器存儲接口 (CSI) 等依賴項導致的中斷。 預測這些中斷并在不停機的情況下遷移關鍵工作負載可能比較困難。可以將 AKS 群集配置為自動停止包含次要版本更改和已棄用 API 的升級操作,并提醒你注意此問題。 此功能有助于避免意外中斷,并使你有時間在繼續升級之前及時解決已棄用的 API。參考:發生 API 中斷性變更時自動停止 Azure Kubernetes 服務 (AKS) 群集升級
檢查部署源文件api version?
檢查部署源文件中的api version,例如helm等,如果存在目標版本即將要廢棄的api version,需要在AKS升級前計劃修改,在修改前注意檢查是否開啟資源自動同步。
檢查公共Image ??
-
檢查是否存在已經丟失公共鏡像源的服務。
-
檢查是否存在仍然在使用被自動清除策略刪除的鏡像。
附:掃描namespace下所有鏡像的檢查命令
$ kubectl describe pod -n <namespace> |?grep?Image | awk?'{print $2}'?|?grep?-v?'ID'?|?sort?-u
檢查節點親和性?
檢查是否存在有節點依賴的服務。
$ kubectl get deployments.apps -A -o=jsonpath="{$.items[?(@.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution)].metadata.name}";
$ kubectl get statefulsets.apps -A -o=jsonpath="{$.items[?(@.spec.template.spec.affinity.deAffinity.requiredDuringSchedulingIgnoredDuringExecution)].metadata.name}";
$ kubectl get deployments.apps -A -o=jsonpath="{$.items[?(@.apiVersion=='apps/v1')].spec.template.spec.nodeSelector}";
$ kubectl get statefulsets.apps -A -o=jsonpath="{$.items[?(@.apiVersion=='apps/v1')].spec.template.spec.nodeSelector}";
查看所有節點及labels并記錄。
$ kubectl?get?node?--show-labels
檢查是否有污點?
檢查節點是否標記有污點并記錄。
$ kubectl?get?nodes?-o jsonpath='{range $.items[?(.spec.taints)]}{@.metadata.name} ? {@.spec.taints}{"\n"}{end}'
檢查PDB設置?
升級前備份并刪除PDB,系統PDB除外,否則會導致AKS集群升級失敗。
參考:排查由于 PDB 導致的逐出失敗而導致的 UpgradeFailed 錯誤(https://learn.microsoft.com/zh-cn/troubleshoot/azure/azure-kubernetes/create-upgrade-delete/error-code-poddrainfailure)
檢查地址空間?
升級前確認地址空間充足。 ??
打開Azure Portal > Kubernetes 服務 > 設置 - 節點池 > 選擇節點池 > 配置 - 子網 > 點擊子網 > 復制Subnet并搜索
檢查服務器類型配額是否足夠?
查看使用的服務器類型
檢查升級節點激增數?
$ az aks nodepool show --name?<nodePool>?--resource-group?<resourceGroup>?--cluster-name?<clusterName>?|grep maxSurge
設置節點激增數(設置AKS集群升級中同時升級的節點數),一般是按照節點池總數的三分之一或二分之一設置。
# Set max surge for a new node pool
az aks nodepool add --name mynodepool --resource-group MyResourceGroup --cluster-name MyManagedCluster --max-surge 33%# Update max surge for an existing node pool
az aks nodepool update --name mynodepool --resource-group MyResourceGroup --cluster-name MyManagedCluster --max-surge 5
檢查并記錄升級前所有pod狀態?
升級前記錄所有pod狀態,在AKS升級完成后作為參考。
檢查JDK版本?
在AKS升級到1.25版本后,Pod可能由于內存飽和或內存不足而停止工作。
現象:
-
節點上的內存壓力
-
與升級前應用的內存使用量相比,增加了應用的內存使用率
-
節點上的 CPU 限制
-
由于 OOM 錯誤而導致 Pod 失敗
在以下環境中運行的應用可能會降低性能:
-
對于 低于版本 11.0.18 或版本 1.8.0 372 的 JRE 版本 ,Java 運行時環境 (JRE) ()
-
低于版本 5.0 的 .NET 版本
-
Node.js
參考:群集升級到 Kubernetes 1.25 后,Pod 中會出現內存飽和
https://learn.microsoft.com/zh-cn/troubleshoot/azure/azure-kubernetes/create-upgrade-delete/aks-memory-saturation-after-upgrade
掃描namespace下所有pod的JDK版本
$ vim show_pods_jdk_version.sh
#!/usr/bin/bash
for?pod?in?`kubectl get po -n?$1?| awk?'{print $1}'?| grep -v NAME`
do
??echo?$pod
? result=$(kubectl?exec?-it -n?$1?$pod?-- java -version 2>/dev/null)
??if?[[ $? != 0 ]];?then
? ??echo?'no_jdk'
??else
? ??echo?`kubectl?exec?-it -n?$1?$pod?-- java -version 2>/dev/null | grep?'openjdk version\|java version'`
??fi
done
$ bash show_pods_jdk_version.sh <namespace>
??
AKS Upgrade Cut Over ??
Kubernetes服務 > 群集配置 > 升級版本 > 選擇下一個次版本 > 保存
強制升級(可選項)
用戶也可以嘗試臨時性的disable該檢查,強制讓aks先完成升級。但這就意味著后續升級到新版本之后,用戶業務pod可能會直接無法使用(新k8s版本上老舊的api已經下架)
參考:Stop Azure Kubernetes Service (AKS) cluster upgrades automatically on API breaking changes
https://docs.azure.cn/en-us/aks/stop-cluster-upgrade-api-breaking-changes#bypass-validation-to-ignore-api-changes
$ az aks update --name myAKSCluster --resource-group?myResourceGroup --enable-force-upgrade --upgrade-override-until?2023-10-01T13:00:00Z ??//預估的時間窗口
AKS Upgrade PostCheck?
檢查node labels?
設置labels ??
$ kubectl label nodes?<node>?<key>=<value>
檢查污點?
設置污點
$ kubectl taint nodes?<node>?<key>=<value>:NoSchedule?
檢查所有pod狀態?
對比在PreCheck中記錄的pod狀態檢查,如有問題及時處理。
通知應用自檢查?
確保所有pod正常啟動后檢查業務系統狀態,更新完成CMDB,并匯總業務的反饋信息做升級報告提交。