複製控制器

用於管理可水平擴充套件的工作負載的舊版 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,但還沒有一個正在執行,可能是因為映象正在拉取。稍後,相同的命令可能會顯示

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 需要 `apiVersion`、`kind` 和 `metadata` 欄位。

當控制平面為 ReplicationController 建立新的 Pod 時,ReplicationController 的 `。metadata.name` 是命名這些 Pod 的基礎之一。ReplicationController 的名稱必須是有效的 DNS 子域名值,但這可能會導致 Pod 主機名出現意外結果。為了獲得最佳相容性,名稱應遵循更嚴格的 DNS 標籤規則。

有關配置檔案的通用資訊,請參閱 物件管理

ReplicationController 還需要一個 .spec 部分

Pod 模板

`.spec.template` 是 `.spec` 唯一必需的欄位。

`.spec.template` 是一個 Pod 模板。它與 Pod 具有完全相同的模式,只是它被巢狀,並且沒有 `apiVersion` 或 `kind`。

除了 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`。

此外,您通常不應直接使用另一個 ReplicationController 或其他控制器(如 Job)建立任何標籤與此選擇器匹配的 Pod。如果這樣做,ReplicationController 會認為它建立了其他 Pod。Kubernetes 不會阻止您這樣做。

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

多個副本

您可以透過將 `。spec.replicas` 設定為您希望同時執行的 Pod 數量來指定同時執行多少個 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 的標籤將其從 ReplicationController 的目標集中移除。此技術可用於將 Pod 從服務中移除以進行除錯和資料恢復。以這種方式移除的 Pod 將自動替換(假設副本數量也未更改)。

常見使用模式

重新排程

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

擴縮

ReplicationController 允許透過更新 `replicas` 欄位來手動或透過自動擴縮控制代理,來向上或向下擴縮副本數量。

滾動更新

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

#1353 中所述,推薦的方法是建立一個具有 1 個副本的新 ReplicationController,逐個擴縮新控制器(+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 與 Service 一起使用

多個 ReplicationController 可以位於一個 Service 之後,這樣,例如,一些流量流向舊版本,一些流量流向新版本。

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 是下一代 ReplicationController,它支援新的基於集合的標籤選擇器。它主要由Deployment 用作協調 Pod 建立、刪除和更新的機制。請注意,我們建議使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定義更新協調或根本不需要更新。

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

裸 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 物件定義以瞭解 ReplicationController 的 API。
最後修改時間:2024 年 3 月 14 日下午 2:28 PST:新增元資料以使用 API 參考連結機制 (c889d9b251)