Azure Kubernetes Service(AKS)的具狀態工作負載升級模式

Note

本文提及「從屬(複本)」一詞,而 Microsoft 已不再使用此術語。 當這個詞從 Redis 軟體中移除時,我們也會從本文中移除。

利用這些模式來協調資料庫可用性與 Azure Kubernetes Service (AKS) 節點池滾動升級。

本文中的程序是規劃架構,而非可用性或資料穩定性保證。 結果取決於你的資料庫拓撲、複製模式、儲存空間、運算元、中斷設定、客戶端重試行為及工作負載。 在具代表性的環境中排練完整程序,並評估是否符合你的恢復時間目標(RTO)及恢復點目標(RPO)。

本文涵蓋的資料庫升級模式

本文提供具備有狀態工作負載的 AKS 叢集的資料庫專用升級模式,包括:

  • PostgreSQL 受控切換。
  • Redis 叢集以複本優先進行滾動升級。
  • MongoDB 複本集次要節點優先輪流升級。
  • 安全性回應的緊急升級檢查清單。
  • 驗證與回滾規劃。

與標準的 AKS 節點池升級不同,這些模式會協調資料庫複製檢查與角色變更,並搭配 Kubernetes 節點替換。 資料庫與 AKS 管理員可以使用這些模式。 請使用負責管理您部署環境的資料庫操作員文件中記載的切換或升級作業。 不要用操作員專屬的指令來取代這些模式。

如需詳細資訊,請參閱下列相關文章:


為了快速開始,請選擇部署產品與拓撲的模式:

選擇資料庫升級模式

資料庫類型 升級模式 可用性考量 適用對象
PostgreSQL 受控切換 在連線耗盡和切換時會暫停寫入。 在您的環境中測量間隔。 支援故障轉移機制的主態與串流待機部署
Redis 叢集 副本優先滾動升級 用戶端在故障轉移期間可能會收到暫時錯誤或重定向。 Redis 叢集使用非同步複寫。 Redis叢集部署,每個主節點都有副本
MongoDB 次級-先行滾動升級 寫入失敗會從階段下降開始,直到新初選當選。 具有可選次要節點的三個以上成員複本集

緊急升級檢查清單

如果你需要加速升級以解決安全問題,千萬不要跳過資料庫健康與復原檢查。

  1. 確認工作負載及 AKS 升級前置條件:

    # Verify the database pods and their node placement.
    kubectl get pods -l tier=database -o wide
    
    # Confirm that the latest backup job completed.
    kubectl get job backup-job -o jsonpath='{.status.completionTime}'
    

    同時也可透過資料庫或操作員支援的指令來驗證複製健康狀況。 在隔離環境中還原最新備份,並確認用戶端會重試暫時連線與選擇錯誤。

  2. 只選擇與你的產品和拓撲相符的圖案:

    對於其他資料庫產品,請依照該產品或其 Kubernetes 營運商的升級指引。

  3. 帶著安全網跑步:

    • 務必事先測試回復程序。
    • 在升級期間監視應用程式計量。
    • 讓資料庫小組保持待命狀態。
    • 若複寫、定額數、槽位覆蓋率或應用程式健康狀況惡化,請停止升級。

PostgreSQL 受控切換

使用這個受控切換模式來管理帶有串流備援的 PostgreSQL 主伺服器。 範例中顯示健康檢查,但升遷、封閉及重新加入成員的指令,取決於你的 PostgreSQL 運算子或高可用性實作。

Important

在應用程式寫入暫停、候選備援節點已追上主節點狀態,且高可用性機制能夠隔離或重新設定舊主節點之前,不要將備援節點提升為主節點。 在原主伺服器仍接受寫入時,將備用伺服器升級為主伺服器可能會造成資料庫時間軸產生分歧。

Prerequisites

  • 請使用支援的 PostgreSQL 版本及支援的運算子或高可用性實作。
  • 將成員分散至不同的故障網域。 為您的部署作業設定 Pod 中斷預算和拓撲分散限制。
  • 透過在隔離環境中還原最近的備份來驗證其可用性。
  • 確認應用程式在主要變更後會重新連接。
  • 在開始 AKS 升級前,記錄操作員專用的切換、回滾與重新連接指令。

步驟 1:驗證複製拓撲

對目前的主節點執行以下查詢:

kubectl exec <current-primary-pod> -- psql -X -c "
SELECT application_name, state, sync_state, write_lsn, flush_lsn, replay_lsn
FROM pg_stat_replication;"

預定的轉接候選人必須在該 streaming 州。 如果 RPO 需要同步複寫,也請確認候選項目是否具有設定所預期的sync_state。

在預定作為備援的節點上執行以下查詢:

kubectl exec <candidate-standby-pod> -- psql -X -c "
SELECT pg_is_in_recovery(), pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();"

確認 pg_is_in_recovery() 會傳回 true,且接收位置和重播位置符合您測試過的切換門檻。 PostgreSQL 的串流複製預設是非同步的,所以僅靠 Ready Pod 並不能確定待命已經追上。

步驟 2:暫停寫入並切換主節點

如果所有應用程式流量都經過 PgBouncer,請連接到 PgBouncer 管理資料庫並暫停應用程式資料庫:

kubectl exec <pgbouncer-pod> -- psql -p 6432 -U <admin-user> pgbouncer -c "PAUSE app_db;"

PAUSE 會根據已設定的連線集區模式,等待伺服器連線釋放。 在仰賴這項控制措施之前,請先確認應用程式的寫入作業無法繞過 PgBouncer。

在暫停寫入的情況下,請使用您的操作員或高可用性機制完成下列動作:

  1. 重新檢查候選人的 WAL 接球和重播位置。
  2. 執行支援的切換操作。
  3. 確認只存在一個可寫入的主要節點。
  4. 確認先前的主節點已被隔離,或已重新設定為待命節點。
  5. 確認寫入服務或端點是否解析到新的主節點。

只有在通過以下檢查後,才能繼續使用PgBouncer:

kubectl exec <pgbouncer-pod> -- psql -p 6432 -U <admin-user> pgbouncer -c "RESUME app_db;"

步驟 3:驗證切換

# Verify the new primary is writable and no longer in recovery.
kubectl exec <new-primary-pod> -- psql -X -c "SELECT pg_is_in_recovery();"

# Verify all expected standbys stream from the new primary.
kubectl exec <new-primary-pod> -- psql -X -c "
SELECT application_name, state, sync_state, replay_lsn
FROM pg_stat_replication;"

測試應用程式的讀取、寫入、交易及重新連線行為。 在繼續之前,請先比較寫入無法使用的時間長度和複寫結果是否符合您的 RTO 和 RPO。

可選的同步複寫配置

同步複製可以降低已確認交易的 RPO,但會增加提交延遲,且如果沒有所需的備用記憶體,可能會降低寫入可用性。 以下範例會等待任意兩個已命名且直接連線的待命伺服器重播每一筆已提交的交易:

# Use synchronous replication with multiple standbys
# postgresql.conf
synchronous_standby_names = 'ANY 2 (standby1, standby2, standby3)'
synchronous_commit = 'remote_apply'

選擇 synchronous_standby_names 並 synchronous_commit 根據測量的延遲、故障領域位置及耐久性需求。 這種配置並不保證特定的切換時間。

成功驗證

若要驗證進度,請使用下列檢查清單:

  • 新的主節點接受讀取和寫入作業。
  • 所有複本的複寫狀況均良好。
  • 應用程式會自動重新連線。
  • 資料完整性與應用程式一致性檢查通過。
  • 備份與還原測試均已在新的主要節點上通過。

升級 AKS 節點池

一個 az aks nodepool upgrade 操作會升級整個節點池。 AKS 會增加突波容量,封鎖並排空舊節點,重新映像化,並依節點池升級設定重複這個過程。 不要對每個節點執行一次指令,或在管理操作前手動清空節點。

  1. 列出叢集支援的升級目標:

    az aks get-upgrades \
       --resource-group <resource-group-name> \
       --name <cluster-name> \
       --output table
    
  2. 確認控制平面已處於所選的目標版本。 根據測試過的工作負載行為、配額及可用子網路位址,配置節點池的滾動升級設定。 以下範例使用建議的生產 maxSurge 值:

    az aks nodepool update \
       --resource-group <resource-group-name> \
       --cluster-name <cluster-name> \
       --name <node-pool-name> \
       --max-surge 33% \
       --drain-timeout <minutes> \
       --node-soak-duration <minutes>
    
  3. 為節點集區啟動一次受管理的升級,使用由 az aks get-upgrades 傳回的目標:

    az aks nodepool upgrade \
       --resource-group <resource-group-name> \
       --cluster-name <cluster-name> \
       --name <node-pool-name> \
       --kubernetes-version <target-version>
    
  4. 在整個作業過程中監控 AKS 升級事件及資料庫健康狀況:

    kubectl events --all-namespaces
    kubectl get pods -l app=postgres -o wide --watch
    

    監控可觀察系統中的複製、資料庫可用性、應用程式錯誤、延遲及儲存健康狀況。 如果 Pod 中斷預算阻塞了排水,請修正工作負載可用性問題,而不是繞過預算。

驗證與恢復

管理升級完成後,請驗證節點版本、PostgreSQL 拓撲及應用程式行為:

kubectl get nodes
kubectl get pods -l app=postgres -o wide
kubectl exec <current-primary-pod> -- psql -X -c "
SELECT application_name, state, sync_state, replay_lsn
FROM pg_stat_replication;"

AKS 不支援將叢集或節點池降級到較早的 Kubernetes 版本。 若資料庫狀況不佳,請停止應用程式寫入,並使用資料庫操作員支援的復原或切換程序。 除非先前的 PostgreSQL 主要節點已安全地重新加入目前的時間軸,並由高可用性機制升級為主要節點,否則請勿將寫入重新導向至該節點。 如果 Kubernetes 升級導致無法恢復的相容性問題,請透過將工作負載移至測試過的叢集或節點池,並依照你的復原計畫還原或複製資料來恢復服務。


Redis 叢集複本節點優先輪流升級

用這個模式來設計至少三個主節點,且每個主節點至少有一個副本的 Redis 叢集。 文件中記載的 Redis 叢集節點升級順序為:先升級複本節點,手動將每個主要節點容錯移轉至已升級的複本節點,然後再升級已降級的原主要節點。 Redis 叢集可在拓撲變更時回傳暫態錯誤或重定向。 由於 Redis 叢集使用非同步複製,可能會遺失已確認的寫入。 升級前驗證客戶端重試行為及可接受的 RPO。

Note

如果是由 Redis 操作員管理叢集,請使用其文件中的滾動升級工作流程。 除非文件有指示,否則不要把手動叢集指令和主動操作員合併使用。

步驟 1:記錄並驗證拓撲結構

kubectl exec <redis-pod> -- redis-cli CLUSTER NODES
kubectl exec <redis-pod> -- redis-cli --cluster check 127.0.0.1:6379

記錄每個節點的 ID、角色、主節點與複本的對應關係,以及雜湊槽範圍。 除非所有 16,384 個槽位都已涵蓋、每個主要節點在不同的故障域中都有健康的複本節點,且叢集回報 cluster_state:ok,否則請勿繼續。

步驟二:升級複製品

對每個複製品,一次一個:

  1. 使用操作員或工作負載部署機制,在升級後的 AKS 容量下取代或重新啟動複本。
  2. 等待 Pod 進入就緒狀態,並讓複寫追上進度。
  3. 使用 CLUSTER NODES 確認其仍指派給預期的主要節點。

不要為了保留 Redis 節點身份而執行 CLUSTER FORGET Pod 重啟。 如果替換節點有新的身份,使用 redis-cli --cluster add-node 與 --cluster-slave--cluster-master-id 來添加它作為預期主節點的副本。 等待新的副本出現在叢集拓撲中。

kubectl exec <existing-redis-pod> -- redis-cli --cluster add-node \
   <new-replica-ip>:6379 127.0.0.1:6379 \
   --cluster-slave \
   --cluster-master-id <primary-node-id>

步驟 3:容錯移轉並升級主要節點

對每個主要項目,每次處理一個:

  1. 選擇該主要節點的一個已升級且已趕上狀態的複本。

  2. 在你想升級的副本上執行,而不是在目前的主要副本上:CLUSTER FAILOVER

    kubectl exec <candidate-replica-pod> -- redis-cli CLUSTER FAILOVER
    
  3. 民調 ROLE、 INFO REPLICATION,或 CLUSTER NODES 直到候選人成為初選,而前初選是其複製品。 回應 OK 僅表示 Redis 已接受故障轉移請求。

  4. 在已升級的 AKS 容量上取代或重新啟動已降級的先前主要節點。

  5. 等待其恢復為已趕上狀態的複本,再繼續處理下一個主要節點。

不要使用 CLUSTER FAILOVER FORCE 或 TAKEOVER 在計劃升級期間使用。 這些選項繞過了正常的協調,需要分開的故障與復原程序。

步驟 4:驗證 Redis 叢集

kubectl exec <redis-pod> -- redis-cli CLUSTER INFO
kubectl exec <redis-pod> -- redis-cli CLUSTER NODES
kubectl exec <redis-pod> -- redis-cli --cluster check 127.0.0.1:6379

檢查插槽覆蓋率、主要節點到複本的指派情形、複寫健康狀況、應用程式的讀取與寫入、重新導向處理,以及實際觀察到的 RPO。


MongoDB 複本集次要節點優先輪流升級

對於具有可參與選舉之次要節點的三個以上成員 MongoDB 複寫集,請使用此模式。 在初選階段和選舉期間,寫作會失敗,直到有新的初選當選。 應用程式必須依據 MongoDB 驅動程式指引重新嘗試合格的寫入與暫態交易。

Note

如果 MongoDB 操作員管理副本集,請使用其文件化的滾動升級工作流程與準備度檢查。

步驟 1:驗證副本集

kubectl exec <mongodb-pod> -- mongosh --quiet --eval "rs.status()"

確認所有預期成員都健康,確認目前的初選,並確認至少有一個可當選的次選候選人已經追上。 也請透過測試還原來確認最新備份。

步驟二:升級次要設備

對每個次要項目,一次處理一個:

  1. 透過操作員或工作負載部署機制,取代或重新啟動升級後的 AKS 容量成員。

  2. 等待 Pod 進入就緒狀態。

  3. 在更新另一個成員之前,請確認該成員已回到 SECONDARY 狀態並追上進度。

    kubectl exec <mongodb-pod> -- mongosh --quiet --eval \
       "rs.status().members.map(member => ({name: member.name, state: member.stateStr, optime: member.optimeDate}))"
    

步驟 3:降低主電源電壓

僅針對目前的主節點執行 rs.stepDown()。 第一個論點明確規定了前一次初選不能連任的時間。 第二個引數指定可當選的次要節點有多少時間追上進度。 根據你測試過的選舉行為來選擇價值。

kubectl exec <current-primary-pod> -- mongosh --quiet --eval "rs.stepDown(60, 30)"

當主節點降級時,該指令可能會中斷連線或傳回錯誤。 從另一個成員輪詢複本集狀態,直到只選出一個新的主要節點:

kubectl exec <mongodb-pod> -- mongosh --quiet --eval \
   "rs.status().members.map(member => ({name: member.name, state: member.stateStr}))"

如果在設定期間內沒有可當選的次要候選人追上,主要候選人不會退出。 在重試前先解決複寫健康狀態。 在計劃升級時不要強迫降級。

步驟 4:升級並驗證先前的主要節點

在升級後的 AKS 容量上替換或重新啟動原本的主系統。 等它恢復為健康的次級,然後驗證:

  • 恰好有一個成員為 PRIMARY。
  • 所有其他承載資料的成員都是SECONDARY,且已趕上狀態。
  • 應用程式的讀取、寫入、可重試寫入及交易作業皆如預期般運作。
  • 測得的選舉間隔符合應用程式的 RTO。
  • 備份與還原檢查通過。