ReplicationController

用於管理可水平擴充工作負載的舊版 API。已被 Deployment 和 ReplicaSet API 取代。

ReplicationController 確保在任何時間點都執行指定數量的 Pod 副本。換句話說,ReplicationController 確保 Pod 或同質 Pod 集合始終處於啟動並可用的狀態。

ReplicationController 的運作方式

如果 Pod 數量過多,ReplicationController 會終止額外的 Pod。如果 Pod 數量過少,ReplicationController 會啟動更多 Pod。與手動建立的 Pod 不同,由 ReplicationController 維護的 Pod 在失敗、刪除或終止時會自動替換。例如,在節點上進行破壞性維護(例如核心升級)後,您的 Pod 會重新建立。因此,即使您的應用程式僅需要單一 Pod,您也應該使用 ReplicationController。ReplicationController 類似於程序監管器,但 ReplicationController 不是監管單一節點上的個別程序,而是監管跨多個節點的多個 Pod。

在討論中,ReplicationController 通常縮寫為「rc」,並且在 kubectl 命令中作為快捷方式。

一個簡單的案例是建立一個 ReplicationController 物件,以可靠地無限期執行 Pod 的一個執行個體。更複雜的使用案例是執行複寫服務(例如 Web 伺服器)的數個相同副本。

執行範例 ReplicationController

此範例 ReplicationController 組態執行三個 nginx Web 伺服器的副本。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

下載範例檔案,然後執行此命令來執行範例工作

kubectl apply -f https://k8s.io/examples/controllers/replication.yaml

輸出類似於此

replicationcontroller/nginx created

使用此命令檢查 ReplicationController 的狀態

kubectl describe replicationcontrollers/nginx

輸出類似於此

Name:        nginx
Namespace:   default
Selector:    app=nginx
Labels:      app=nginx
Annotations:    <none>
Replicas:    3 current / 3 desired
Pods Status: 0 Running / 3 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:       app=nginx
  Containers:
   nginx:
    Image:              nginx
    Port:               80/TCP
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>
Events:
  FirstSeen       LastSeen     Count    From                        SubobjectPath    Type      Reason              Message
  ---------       --------     -----    ----                        -------------    ----      ------              -------
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-qrm3m
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-3ntk0
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-4ok8v

在此,已建立三個 Pod,但尚無任何 Pod 正在執行,可能是因為正在提取映像檔。稍後,相同的命令可能會顯示

Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed

若要以機器可讀取的格式列出屬於 ReplicationController 的所有 Pod,您可以使用類似這樣的命令

pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
echo $pods

輸出類似於此

nginx-3ntk0 nginx-4ok8v nginx-qrm3m

在此,選擇器與 ReplicationController 的選擇器相同(在 kubectl describe 輸出中看到),並且在 replication.yaml 中以不同的形式呈現。--output=jsonpath 選項指定一個運算式,其中包含傳回清單中每個 Pod 的名稱。

撰寫 ReplicationController 資訊清單

與所有其他 Kubernetes 組態一樣,ReplicationController 需要 apiVersionkindmetadata 欄位。

當控制平面為 ReplicationController 建立新的 Pod 時,ReplicationController 的 .metadata.name 是命名這些 Pod 的基礎的一部分。ReplicationController 的名稱必須是有效的 DNS 子網域 值,但這可能會為 Pod 主機名稱產生非預期的結果。為了獲得最佳相容性,名稱應遵循更嚴格的 DNS 標籤 規則。

有關使用組態檔的一般資訊,請參閱物件管理

ReplicationController 也需要 .spec 區段

Pod 範本

.spec.template.spec 中唯一必要的欄位。

.spec.templatePod 範本。它與 Pod 具有完全相同的結構描述,只是它是巢狀結構,並且沒有 apiVersionkind

除了 Pod 的必要欄位之外,ReplicationController 中的 Pod 範本還必須指定適當的標籤和適當的重新啟動策略。對於標籤,請確保不要與其他控制器重疊。請參閱Pod 選擇器

僅允許 .spec.template.spec.restartPolicy 等於 Always,如果未指定,則為預設值。

對於本機容器重新啟動,ReplicationController 會委派給節點上的代理程式,例如 Kubelet

ReplicationController 上的標籤

ReplicationController 本身可以有標籤 (.metadata.labels)。通常,你會將這些標籤設定為與 .spec.template.metadata.labels 相同;如果未指定 .metadata.labels,則預設為 .spec.template.metadata.labels。然而,它們可以不同,且 .metadata.labels 不會影響 ReplicationController 的行為。

Pod 選取器

.spec.selector 欄位是一個標籤選取器。ReplicationController 管理所有標籤與選取器相符的 Pod。它不會區分它建立或刪除的 Pod,以及其他人或程序建立或刪除的 Pod。這允許在不影響正在執行的 Pod 的情況下替換 ReplicationController。

如果已指定,則 .spec.template.metadata.labels 必須等於 .spec.selector,否則 API 將會拒絕。如果未指定 .spec.selector,則預設為 .spec.template.metadata.labels

此外,你通常不應建立任何標籤與此選取器相符的 Pod,無論是直接建立、使用另一個 ReplicationController 建立,還是使用另一個控制器(例如 Job)建立。如果你這樣做,ReplicationController 會認為是它建立了其他 Pod。Kubernetes 不會阻止你這樣做。

如果你最終有多個控制器具有重疊的選取器,你將必須自行管理刪除(請參閱下方)。

多個副本

你可以透過將 .spec.replicas 設定為你希望同時執行的 Pod 數量,來指定應同時執行的 Pod 數量。任何時候執行的數量可能會更高或更低,例如,如果副本數量剛剛增加或減少,或者 Pod 正在優雅地關閉,而替換的 Pod 提前啟動。

如果你未指定 .spec.replicas,則預設為 1。

使用 ReplicationController

刪除 ReplicationController 及其 Pod

若要刪除 ReplicationController 及其所有 Pod,請使用 kubectl delete。Kubectl 會將 ReplicationController 縮減為零,並等待它刪除每個 Pod,然後再刪除 ReplicationController 本身。如果此 kubectl 命令被中斷,可以重新啟動。

當使用 REST API 或 用戶端程式庫 時,你需要明確地執行這些步驟(將副本數量縮減為 0,等待 Pod 刪除,然後刪除 ReplicationController)。

僅刪除 ReplicationController

你可以刪除 ReplicationController,而不會影響其任何 Pod。

使用 kubectl 時,請為 kubectl delete 指定 --cascade=orphan 選項。

當使用 REST API 或 用戶端程式庫 時,你可以刪除 ReplicationController 物件。

一旦原始的 ReplicationController 被刪除,你可以建立一個新的 ReplicationController 來替換它。只要新舊 .spec.selector 相同,新的 ReplicationController 就會採用舊的 Pod。然而,它不會努力使現有的 Pod 與新的、不同的 Pod 範本相符。若要以受控方式將 Pod 更新為新的規格,請使用滾動更新

將 Pod 從 ReplicationController 隔離

可以透過變更 Pod 的標籤,將 Pod 從 ReplicationController 的目標集中移除。此技術可用於將 Pod 從服務中移除,以進行偵錯和資料復原。以這種方式移除的 Pod 將會自動替換(假設副本數量也沒有變更)。

常見使用模式

重新排程

如上所述,無論你想要保持執行 1 個 Pod 還是 1000 個 Pod,ReplicationController 都將確保指定數量的 Pod 存在,即使在節點故障或 Pod 終止(例如,由於另一個控制代理的動作)的情況下也是如此。

擴展

ReplicationController 能夠透過更新 replicas 欄位,手動或由自動擴展控制代理擴展或縮減副本數量。

滾動更新

ReplicationController 旨在透過逐個替換 Pod,來促進對服務進行滾動更新。

#1353 中所述,建議的方法是建立一個新的 ReplicationController,副本數為 1,然後逐個擴展新的控制器 (+1) 和縮減舊的控制器 (-1),然後在舊的控制器達到 0 個副本後將其刪除。無論是否發生意外故障,這都會可預測地更新 Pod 集合。

理想情況下,滾動更新控制器會將應用程式的就緒狀態納入考量,並確保在任何給定時間都有足夠數量的 Pod 在生產性地提供服務。

這兩個 ReplicationController 需要建立具有至少一個區分標籤的 Pod,例如 Pod 主要容器的映像標籤,因為通常是映像更新促使滾動更新。

多個發布軌跡

除了在滾動更新進行時執行應用程式的多個發布版本外,常見的做法是使用多個發布軌跡長時間甚至持續執行多個發布版本。這些軌跡將透過標籤來區分。

例如,一個服務可能以所有標籤為 tier in (frontend), environment in (prod) 的 Pod 為目標。現在假設你有 10 個複製的 Pod 組成此層。但你想要能夠「金絲雀測試」此元件的新版本。你可以設定一個 ReplicationController,將 replicas 設定為 9,用於大部分副本,標籤為 tier=frontend, environment=prod, track=stable,另一個 ReplicationController,將 replicas 設定為 1,用於金絲雀測試,標籤為 tier=frontend, environment=prod, track=canary。現在,該服務涵蓋了金絲雀測試和非金絲雀測試 Pod。但你可以分別操作這些 ReplicationController 來測試事物、監控結果等等。

將 ReplicationController 與服務搭配使用

多個 ReplicationController 可以位於單個服務之後,這樣,例如,某些流量會流向舊版本,而某些流量會流向新版本。

ReplicationController 永遠不會自行終止,但預期它不會像服務那樣長壽。服務可能由多個 ReplicationController 控制的 Pod 組成,並且預期在服務的生命週期內可能會建立和銷毀許多 ReplicationController(例如,執行服務的 Pod 更新)。服務本身及其用戶端都應對維護服務 Pod 的 ReplicationController 保持不知情。

編寫用於複製的程式

由 ReplicationController 建立的 Pod 旨在是可互換且語義上相同的,儘管它們的配置可能會隨著時間的推移而變得異質。這顯然適用於複製的無狀態伺服器,但 ReplicationController 也可用於維護主節點選舉、分片和工作池應用程式的可用性。此類應用程式應使用動態工作分配機制,例如 RabbitMQ 工作佇列,而不是對每個 Pod 的配置進行靜態/一次性自訂,這被認為是一種反模式。任何執行的 Pod 自訂,例如資源的垂直自動調整大小(例如,CPU 或記憶體),都應由另一個線上控制器程序執行,與 ReplicationController 本身類似。

ReplicationController 的職責

ReplicationController 確保所需數量的 Pod 與其標籤選取器相符且可運作。目前,只有已終止的 Pod 會從其計數中排除。在未來,系統提供的就緒狀態和其他資訊可能會被納入考量,我們可能會針對替換策略新增更多控制項,並且我們計劃發出事件,外部用戶端可以使用這些事件來實作任意複雜的替換和/或縮減策略。

ReplicationController 永遠受限於此狹隘的職責。它本身不會執行就緒探測或存活探測。它並非執行自動擴展,而是旨在由外部自動擴展器控制(如 #492 中所述),這會變更其 replicas 欄位。我們不會將排程策略(例如,分散)新增至 ReplicationController。它也不應驗證受控制的 Pod 是否與目前指定的範本相符,因為這會阻礙自動調整大小和其他自動化程序。同樣地,完成期限、排序依賴性、配置擴展和其他功能屬於其他地方。我們甚至計劃分解大量 Pod 建立的機制 (#170)。

ReplicationController 旨在成為可組合的建構區塊基本元件。我們預期未來會在它和其他互補的基本元件之上建構更高層級的 API 和/或工具,以方便使用者使用。「巨集」操作目前由 kubectl(run、scale)支援,是此概念驗證範例。例如,我們可以想像像 Asgard 這樣的工具管理 ReplicationController、自動擴展器、服務、排程策略、金絲雀測試等等。

API 物件

Replication controller 是 Kubernetes REST API 中的頂層資源。有關 API 物件的更多詳細資訊,請參閱:ReplicationController API 物件

ReplicationController 的替代方案

ReplicaSet

ReplicaSet 是下一代 ReplicationController,它支援新的基於集合的標籤選取器。它主要由 Deployment 用作協調 Pod 建立、刪除和更新的機制。請注意,除非你需要自訂更新協調或根本不需要更新,否則我們建議使用 Deployment 而不是直接使用 Replica Set。

Deployment 是一個更高層級的 API 物件,它會更新其底層的 Replica Set 及其 Pod。如果你想要滾動更新功能,建議使用 Deployment,因為它們是宣告式的、伺服器端,並且具有其他功能。

裸 Pod

與使用者直接建立 Pod 的情況不同,ReplicationController 會替換因任何原因(例如節點故障或破壞性節點維護,例如核心升級)而被刪除或終止的 Pod。因此,即使你的應用程式只需要單個 Pod,我們也建議你使用 ReplicationController。可以將其視為類似於進程監管器,只是它監管多個節點上的多個 Pod,而不是單個節點上的個別進程。ReplicationController 將本機容器重新啟動委派給節點上的某些代理程式,例如 kubelet。

工作

對於預期會自行終止的 Pod(即批次工作),請使用 Job 而不是 ReplicationController。

DaemonSet

對於提供機器層級功能(例如機器監控或機器記錄)的 Pod,請使用 DaemonSet 而不是 ReplicationController。這些 Pod 的生命週期與機器生命週期相關聯:Pod 需要在其他 Pod 啟動之前在機器上執行,並且當機器準備好重新啟動/關閉時可以安全地終止。

下一步

  • 了解 Pod
  • 了解 Deployment,ReplicationController 的替代方案。
  • ReplicationController 是 Kubernetes REST API 的一部分。閱讀 ReplicationController 物件定義,以了解 Replication controller 的 API。
上次修改時間:2024 年 3 月 14 日下午 2:28 PST:Add metadata to use mechanism for API reference links (c889d9b251)