新聞中心
ReplicaSet
ReplicaSet 的目的是維護(hù)一組在任何時(shí)候都處于運(yùn)行狀態(tài)的 Pod 副本的穩(wěn)定集合。 因此,它通常用來保證給定數(shù)量的、完全相同的 Pod 的可用性。

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、清流ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的清流網(wǎng)站制作公司
ReplicaSet 的工作原理
ReplicaSet 是通過一組字段來定義的,包括一個(gè)用來識(shí)別可獲得的 Pod 的集合的選擇算符、一個(gè)用來標(biāo)明應(yīng)該維護(hù)的副本個(gè)數(shù)的數(shù)值、一個(gè)用來指定應(yīng)該創(chuàng)建新 Pod 以滿足副本個(gè)數(shù)條件時(shí)要使用的 Pod 模板等等。 每個(gè) ReplicaSet 都通過根據(jù)需要?jiǎng)?chuàng)建和 刪除 Pod 以使得副本個(gè)數(shù)達(dá)到期望值, 進(jìn)而實(shí)現(xiàn)其存在價(jià)值。當(dāng) ReplicaSet 需要?jiǎng)?chuàng)建新的 Pod 時(shí),會(huì)使用所提供的 Pod 模板。
ReplicaSet 通過 Pod 上的 metadata.ownerReferences 字段連接到附屬 Pod,該字段給出當(dāng)前對象的屬主資源。 ReplicaSet 所獲得的 Pod 都在其 ownerReferences 字段中包含了屬主 ReplicaSet 的標(biāo)識(shí)信息。正是通過這一連接,ReplicaSet 知道它所維護(hù)的 Pod 集合的狀態(tài), 并據(jù)此計(jì)劃其操作行為。
ReplicaSet 使用其選擇算符來辨識(shí)要獲得的 Pod 集合。如果某個(gè) Pod 沒有 OwnerReference 或者其 OwnerReference 不是一個(gè) 控制器,且其匹配到 某 ReplicaSet 的選擇算符,則該 Pod 立即被此 ReplicaSet 獲得。
何時(shí)使用 ReplicaSet
ReplicaSet 確保任何時(shí)間都有指定數(shù)量的 Pod 副本在運(yùn)行。 然而,Deployment 是一個(gè)更高級的概念,它管理 ReplicaSet,并向 Pod 提供聲明式的更新以及許多其他有用的功能。 因此,我們建議使用 Deployment 而不是直接使用 ReplicaSet,除非 你需要自定義更新業(yè)務(wù)流程或根本不需要更新。
這實(shí)際上意味著,你可能永遠(yuǎn)不需要操作 ReplicaSet 對象:而是使用 Deployment,并在 spec 部分定義你的應(yīng)用。
示例
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
將此清單保存到 ?frontend.yaml? 中,并將其提交到 Kubernetes 集群, 應(yīng)該就能創(chuàng)建 yaml 文件所定義的 ReplicaSet 及其管理的 Pod。
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
你可以看到當(dāng)前被部署的 ReplicaSet:
kubectl get rs
并看到你所創(chuàng)建的前端:
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 6s
你也可以查看 ReplicaSet 的狀態(tài):
kubectl describe rs/frontend
你會(huì)看到類似如下的輸出:
Name: frontend
Namespace: default
Selector: tier=frontend
Labels: app=guestbook
tier=frontend
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend",...
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: tier=frontend
Containers:
php-redis:
Image: gcr.io/google_samples/gb-frontend:v3
Port:
Host Port:
Environment:
Mounts:
Volumes:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 117s replicaset-controller Created pod: frontend-wtsmm
Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-b2zdv
Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-vcmts
最后可以查看啟動(dòng)了的 Pods:
kubectl get pods
你會(huì)看到類似如下的 Pod 信息:
NAME READY STATUS RESTARTS AGE
frontend-b2zdv 1/1 Running 0 6m36s
frontend-vcmts 1/1 Running 0 6m36s
frontend-wtsmm 1/1 Running 0 6m36s
你也可以查看 Pods 的屬主引用被設(shè)置為前端的 ReplicaSet。 要實(shí)現(xiàn)這點(diǎn),可取回運(yùn)行中的 Pods 之一的 YAML:
kubectl get pods frontend-b2zdv -o yaml
輸出將類似這樣,frontend ReplicaSet 的信息被設(shè)置在 metadata 的 ?ownerReferences ?字段中:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-02-12T07:06:16Z"
generateName: frontend-
labels:
tier: frontend
name: frontend-b2zdv
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: frontend
uid: f391f6db-bb9b-4c09-ae74-6a1f77f3d5cf
...
非模板 Pod 的獲得
盡管你完全可以直接創(chuàng)建裸的 Pods,強(qiáng)烈建議你確保這些裸的 Pods 并不包含可能與你 的某個(gè) ReplicaSet 的選擇算符相匹配的標(biāo)簽。原因在于 ReplicaSet 并不僅限于擁有 在其模板中設(shè)置的 Pods,它還可以像前面小節(jié)中所描述的那樣獲得其他 Pods。
apiVersion: v1
kind: Pod
metadata:
name: pod1
labels:
tier: frontend
spec:
containers:
- name: hello1
image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
labels:
tier: frontend
spec:
containers:
- name: hello2
image: gcr.io/google-samples/hello-app:1.0
由于這些 Pod 沒有控制器(Controller,或其他對象)作為其屬主引用,并且 其標(biāo)簽與 frontend ReplicaSet 的選擇算符匹配,它們會(huì)立即被該 ReplicaSet 獲取。
假定你在 frontend ReplicaSet 已經(jīng)被部署之后創(chuàng)建 Pods,并且你已經(jīng)在 ReplicaSet 中設(shè)置了其初始的 Pod 副本數(shù)以滿足其副本計(jì)數(shù)需要:
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
新的 Pods 會(huì)被該 ReplicaSet 獲取,并立即被 ReplicaSet 終止,因?yàn)?nbsp;它們的存在會(huì)使得 ReplicaSet 中 Pod 個(gè)數(shù)超出其期望值。
取回 Pods:
kubectl get pods
輸出顯示新的 Pods 或者已經(jīng)被終止,或者處于終止過程中:
NAME READY STATUS RESTARTS AGE
frontend-b2zdv 1/1 Running 0 10m
frontend-vcmts 1/1 Running 0 10m
frontend-wtsmm 1/1 Running 0 10m
pod1 0/1 Terminating 0 1s
pod2 0/1 Terminating 0 1s
如果你先行創(chuàng)建 Pods:
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
之后再創(chuàng)建 ReplicaSet:
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
你會(huì)看到 ReplicaSet 已經(jīng)獲得了該 Pods,并僅根據(jù)其規(guī)約創(chuàng)建新的 Pods,直到 新的 Pods 和原來的 Pods 的總數(shù)達(dá)到其預(yù)期個(gè)數(shù)。 這時(shí)取回 Pods:
kubectl get pods
將會(huì)生成下面的輸出:
NAME READY STATUS RESTARTS AGE
frontend-hmmj2 1/1 Running 0 9s
pod1 1/1 Running 0 36s
pod2 1/1 Running 0 36s
采用這種方式,一個(gè) ReplicaSet 中可以包含異質(zhì)的 Pods 集合。
編寫 ReplicaSet 的 spec
與所有其他 Kubernetes API 對象一樣,ReplicaSet 也需要 ?apiVersion?、?kind?、和 ?metadata ?字段。 對于 ReplicaSets 而言,其 ?kind ?始終是 ReplicaSet。
ReplicaSet 對象的名稱必須是合法的 DNS 子域名。
ReplicaSet 也需要 ?.spec? 部分。
Pod 模版
?.spec.template? 是一個(gè)Pod 模版, 要求設(shè)置標(biāo)簽。在 ?frontend.yaml? 示例中,我們指定了標(biāo)簽 ?tier: frontend?。 注意不要將標(biāo)簽與其他控制器的選擇算符重疊,否則那些控制器會(huì)嘗試收養(yǎng)此 Pod。
對于模板的重啟策略 字段,?.spec.template.spec.restartPolicy?,唯一允許的取值是 ?Always?,這也是默認(rèn)值.
Pod 選擇算符
?.spec.selector? 字段是一個(gè)標(biāo)簽選擇算符。 如前文中所討論的,這些是用來標(biāo)識(shí)要被獲取的 Pods 的標(biāo)簽。在簽名的 ?frontend.yaml? 示例中,選擇算符為:
matchLabels:
tier: frontend
在 ReplicaSet 中,?.spec.template.metadata.labels? 的值必須與 ?spec.selector? 值 相匹配,否則該配置會(huì)被 API 拒絕。
對于設(shè)置了相同的 ?
.spec.selector?,但 ?.spec.template.metadata.labels? 和 ?.spec.template.spec? 字段不同的 兩個(gè) ReplicaSet 而言,每個(gè) ReplicaSet 都會(huì)忽略被另一個(gè) ReplicaSet 所 創(chuàng)建的 Pods。
Replicas
你可以通過設(shè)置 ?.spec.replicas? 來指定要同時(shí)運(yùn)行的 Pod 個(gè)數(shù)。 ReplicaSet 創(chuàng)建、刪除 Pods 以與此值匹配。
如果你沒有指定 ?.spec.replicas?, 那么默認(rèn)值為 1。
使用 ReplicaSets
刪除 ReplicaSet 和它的 Pod
要?jiǎng)h除 ReplicaSet 和它的所有 Pod,使用 kubectl delete 命令。 默認(rèn)情況下,垃圾收集器 自動(dòng)刪除所有依賴的 Pod。
當(dāng)使用 REST API 或 ?client-go? 庫時(shí),你必須在刪除選項(xiàng)中將 ?propagationPolicy ?設(shè)置為 ?Background ?或 ?Foreground?。例如:
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"
只刪除 ReplicaSet
你可以只刪除 ReplicaSet 而不影響它的 Pods,方法是使用 kubectl delete 命令并設(shè)置 ?--cascade=orphan? 選項(xiàng)。
當(dāng)使用 REST API 或 ?client-go? 庫時(shí),你必須將 ?propagationPolicy ?設(shè)置為 ?Orphan?。 例如:
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"
一旦刪除了原來的 ReplicaSet,就可以創(chuàng)建一個(gè)新的來替換它。 由于新舊 ReplicaSet 的 ?.spec.selector? 是相同的,新的 ReplicaSet 將接管老的 Pod。 但是,它不會(huì)努力使現(xiàn)有的 Pod 與新的、不同的 Pod 模板匹配。 若想要以可控的方式更新 Pod 的規(guī)約,可以使用 Deployment 資源,因?yàn)?nbsp;ReplicaSet 并不直接支持滾動(dòng)更新。
將 Pod 從 ReplicaSet 中隔離
可以通過改變標(biāo)簽來從 ReplicaSet 的目標(biāo)集中移除 Pod。 這種技術(shù)可以用來從服務(wù)中去除 Pod,以便進(jìn)行排錯(cuò)、數(shù)據(jù)恢復(fù)等。 以這種方式移除的 Pod 將被自動(dòng)替換(假設(shè)副本的數(shù)量沒有改變)。
縮放 RepliaSet
通過更新 ?.spec.replicas? 字段,ReplicaSet 可以被輕松的進(jìn)行縮放。ReplicaSet 控制器能確保匹配標(biāo)簽選擇器的數(shù)量的 Pod 是可用的和可操作的。
在降低集合規(guī)模時(shí),ReplicaSet 控制器通過對可用的 Pods 進(jìn)行排序來優(yōu)先選擇 要被刪除的 Pods。其一般性算法如下:
- 首先選擇剔除懸決(Pending,且不可調(diào)度)的 Pods
- 如果設(shè)置了 ?
controller.kubernetes.io/pod-deletion-cost? 注解,則注解值 較小的優(yōu)先被裁減掉 - 所處節(jié)點(diǎn)上副本個(gè)數(shù)較多的 Pod 優(yōu)先于所處節(jié)點(diǎn)上副本較少者
- 如果 Pod 的創(chuàng)建時(shí)間不同,最近創(chuàng)建的 Pod 優(yōu)先于早前創(chuàng)建的 Pod 被裁減。 (當(dāng) ?
LogarithmicScaleDown?這一 特性門控 被啟用時(shí),創(chuàng)建時(shí)間是按整數(shù)冪級來分組的)。
如果以上比較結(jié)果都相同,則隨機(jī)選擇。
Pod 刪除開銷
FEATURE STATE: Kubernetes v1.22 [beta]
通過使用 ?controller.kubernetes.io/pod-deletion-cost? 注解,用戶可以對 ReplicaSet 縮容時(shí)要先刪除哪些 Pods 設(shè)置偏好。
此注解要設(shè)置到 Pod 上,取值范圍為 [-2147483647, 2147483647]。 所代表的的是刪除同一 ReplicaSet 中其他 Pod 相比較而言的開銷。 刪除開銷較小的 Pods 比刪除開銷較高的 Pods 更容易被刪除。
Pods 如果未設(shè)置此注解,則隱含的設(shè)置值為 0。負(fù)值也是可接受的。 如果注解值非法,API 服務(wù)器會(huì)拒絕對應(yīng)的 Pod。
此功能特性處于 Beta 階段,默認(rèn)被禁用。你可以通過為 kube-apiserver 和 kube-controller-manager 設(shè)置 特性門控 ?PodDeletionCost ?來啟用此功能。
此機(jī)制實(shí)施時(shí)僅是盡力而為,并不能對 Pod 的刪除順序作出任何保證;
用戶應(yīng)避免頻繁更新注解值,例如根據(jù)某觀測度量值來更新此注解值是應(yīng)該避免的。 這樣做會(huì)在 API 服務(wù)器上產(chǎn)生大量的 Pod 更新操作。
使用場景示例
同一應(yīng)用的不同 Pods 可能其利用率是不同的。在對應(yīng)用執(zhí)行縮容操作時(shí),可能 希望移除利用率較低的 Pods。為了避免頻繁更新 Pods,應(yīng)用應(yīng)該在執(zhí)行縮容 操作之前更新一次 ?controller.kubernetes.io/pod-deletion-cost? 注解值 (將注解值設(shè)置為一個(gè)與其 Pod 利用率對應(yīng)的值)。 如果應(yīng)用自身控制器縮容操作時(shí)(例如 Spark 部署的驅(qū)動(dòng) Pod),這種機(jī)制 是可以起作用的。
ReplicaSet 作為水平的 Pod 自動(dòng)縮放器目標(biāo)
ReplicaSet 也可以作為 水平的 Pod 縮放器 (HPA) 的目標(biāo)。也就是說,ReplicaSet 可以被 HPA 自動(dòng)縮放。 以下是 HPA 以我們在前一個(gè)示例中創(chuàng)建的副本集為目標(biāo)的示例。
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: frontend-scaler
spec:
scaleTargetRef:
kind: ReplicaSet
name: frontend
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 50
將這個(gè)列表保存到 ?hpa-rs.yaml? 并提交到 Kubernetes 集群,就能創(chuàng)建它所定義的 HPA,進(jìn)而就能根據(jù)復(fù)制的 Pod 的 CPU 利用率對目標(biāo) ReplicaSet進(jìn)行自動(dòng)縮放。
kubectl apply -f https://K8S.io/examples/controllers/hpa-rs.yaml
或者,可以使用 ?kubectl autoscale? 命令完成相同的操作。 (而且它更簡單!)
kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50
ReplicaSet 的替代方案
Deployment (推薦)
Deployment 是一個(gè) 可以擁有 ReplicaSet 并使用聲明式方式在服務(wù)器端完成對 Pods 滾動(dòng)更新的對象。 盡管 ReplicaSet 可以獨(dú)立使用,目前它們的主要用途是提供給 Deployment 作為 編排 Pod 創(chuàng)建、刪除和更新的一種機(jī)制。當(dāng)使用 Deployment 時(shí),你不必關(guān)心 如何管理它所創(chuàng)建的 ReplicaSet,Deployment 擁有并管理其 ReplicaSet。 因此,建議你在需要 ReplicaSet 時(shí)使用 Deployment。
裸 Pod
與用戶直接創(chuàng)建 Pod 的情況不同,ReplicaSet 會(huì)替換那些由于某些原因被刪除或被終止的 Pod,例如在節(jié)點(diǎn)故障或破壞性的節(jié)點(diǎn)維護(hù)(如內(nèi)核升級)的情況下。 因?yàn)檫@個(gè)原因,我們建議你使用 ReplicaSet,即使應(yīng)用程序只需要一個(gè) Pod。 想像一下,ReplicaSet 類似于進(jìn)程監(jiān)視器,只不過它在多個(gè)節(jié)點(diǎn)上監(jiān)視多個(gè) Pod, 而不是在單個(gè)節(jié)點(diǎn)上監(jiān)視單個(gè)進(jìn)程。 ReplicaSet 將本地容器重啟的任務(wù)委托給了節(jié)點(diǎn)上的某個(gè)代理(例如,Kubelet 或 Docker)去完成。
Job
使用Job 代替ReplicaSet, 可以用于那些期望自行終止的 Pod。
DaemonSet
對于管理那些提供主機(jī)級別功能(如主機(jī)監(jiān)控和主機(jī)日志)的容器, 就要用 ?DaemonSet ?而不用 ReplicaSet。 這些 Pod 的壽命與主機(jī)壽命有關(guān):這些 Pod 需要先于主機(jī)上的其他 Pod 運(yùn)行, 并且在機(jī)器準(zhǔn)備重新啟動(dòng)/關(guān)閉時(shí)安全地終止。
ReplicationController
ReplicaSet 是 ReplicationController 的后繼者。二者目的相同且行為類似,只是 ReplicationController 不支持 標(biāo)簽用戶指南 中討論的基于集合的選擇算符需求。 因此,相比于 ReplicationController,應(yīng)優(yōu)先考慮 ReplicaSet。
分享文章:創(chuàng)新互聯(lián)kubernetes教程:KubernetesReplicaSet
標(biāo)題路徑:http://www.dlmjj.cn/article/djpjogd.html


咨詢
建站咨詢
