無需停機即可升級 Kubernetes 集群

無需停機即可升級 Kubernetes 集群

Kubernetes 叢集的升級過程

在某些時候,當使用 Kubernetes 叢集時,需要更新正在運行的節點。 這可能包括軟體包更新、核心更新或新虛擬機器映像的部署。 在 Kubernetes 術語中,這稱為 “自願中斷”.

這篇文章是 4 篇文章系列的一部分:

  1. 這個帖子。
  2. 正確關閉 Kubernetes 叢集中的 Pod
  3. 刪除 Pod 時延遲終止
  4. 如何使用 PodDisruptionBudgets 避免 Kubernetes 叢集停機

(預計在不久的將來會翻譯該系列中的其餘文章)

在本文中,我們將介紹 Kubernetes 提供的所有工具,以實現叢集中運行的節點零停機。

問題定義

我們首先會採取一種簡單的方法,找出問題並評估這種方法的潛在風險,並累積知識來解決我們在整個週期中遇到的每個問題。 結果是使用生命週期掛鉤、就緒探針和 Pod 中斷預算來實現零停機的配置。

為了開始我們的旅程,讓我們舉一個具體的例子。 假設我們有一個包含兩個節點的 Kubernetes 集群,其中運行一個應用程序,後面有兩個 pod Service:

無需停機即可升級 Kubernetes 集群

讓我們從兩個 pod 開始,其中 Nginx 和 Service 在兩個 Kubernetes 叢集節點上運行。

我們想要更新叢集中兩個工作節點的核心版本。 我們如何做到這一點? 一個簡單的解決方案是使用更新的配置啟動新節點,然後在啟動新節點時關閉舊節點。 雖然這可行,但這種方法會存在一些問題:

  • 當您關閉舊節點時,其上執行的 Pod 也將關閉。 如果需要清除 Pod 以正常關閉怎麼辦? 您正在使用的虛擬化系統可能不會等待清理過程完成。
  • 如果同時關閉所有節點怎麼辦? 當 Pod 移動到新節點時,您將獲得相當長的停機時間。

我們需要一種方法來從舊節點優雅地遷移 Pod,同時確保在對節點進行更改時沒有任何工作進程在運行。 或者,當我們對叢集進行完全替換時,如範例所示(即替換虛擬機器映像),我們希望將正在運行的應用程式從舊節點轉移到新節點。 在這兩種情況下,我們都希望防止在舊節點上調度新的 pod,然後從其中驅逐所有正在運行的 pod。 為了實現這些目標我們可以使用指令 kubectl drain.

重新分配節點上的所有 Pod

Drain 操作可讓您重新指派節點中的所有 Pod。 在drain執行期間,節點被標記為不可調度(標誌 NoSchedule)。 這可以防止新的 Pod 出現在其上。 然後drain開始從節點驅逐pod,關閉目前在節點上運行的容器,發送訊號 TERM pod 中的容器。

雖然 kubectl drain 會很好地驅逐 Pod,但還有兩個因素可能導致排空操作失敗:

  • 您的應用程式必須能夠在提交後正常終止 TERM 訊號. 當 pod 被驅逐時,Kubernetes 會發送一個訊號 TERM 容器並等待它們停止指定的時間,之後,如果它們沒有停止,則強制終止它們。 無論如何,如果您的容器無法正確感知訊號,如果 Pod 目前正在運行(例如,資料庫事務正在進行中),您仍然可能會錯誤地終止它們。
  • 您將丟失包含您的應用程式的所有 pod。 當新容器在新節點上啟動時,它可能不可用,或者如果您的 Pod 部署在沒有控制器的情況下,它們可能根本不會重新啟動。

避免停機

為了最大限度地減少自願中斷(例如節點上的排空操作)造成的停機時間,Kubernetes 提供了以下故障處理選項:

在本系列的其餘部分中,我們將使用這些 Kubernetes 功能來減輕 Pod 遷移的影響。 為了更容易理解主要思想,我們將使用上面的範例和以下資源配置:

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 2
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.15
       ports:
       - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
 name: nginx-service
spec:
 selector:
   app: nginx
 ports:
 - protocol: TCP
   targetPort: 80
   port: 80

此配置是一個最小的範例 Deployment,它管理叢集中的 nginx pod。 另外,配置描述了資源 Service,可用於存取叢集中的 nginx pod。

在整個週期中,我們將迭代擴展此配置,使其最終包含 Kubernetes 提供的用於減少停機時間的所有功能。

如需在 AWS 及其他平台上實現零停機的 Kubernetes 叢集更新的完全實作和測試版本,請造訪 Gruntwork.io.

也請閱讀我們部落格上的其他文章:

來源: www.habr.com

添加評論