Replica Set

ReplicaSet是下一代Replication Controller。*ReplicaSet和 [Replication Controller*](https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/) 之间的唯一区别就是选择器支持。ReplicaSet支持 labels user guide 描述的新的set-based selector requirement,而Replication Controller仅支持equality-based selector requirement。

关于Label Selector:https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ ,本文的示例种也有用到两种selector。

如何使用ReplicaSet

支持Replication Controller的大多数 kubectl 命令也支持ReplicaSets。 rolling-update 命令是一个例外。如果您想要滚动更新功能,请考虑使用Deployment。 此外, rolling-update 命令是必不可少的,而Deployment是声明式的,因此我们建议您通过 rollout 命令使用Deployment。

虽然ReplicaSet可独立使用,但是目前它主要被 Deployment 作为编排Pod创建、删除和更新的机制。当您使用Deployment时,您不必担心如何管理Deployment创建的ReplicaSet。Deployment拥有并管理其ReplicaSet。

何时使用ReplicaSet

ReplicaSet确保在任何时间都会运行指定数量的Pod副本。但是,Deployment是一个更高层次的概念——它管理ReplicaSet,并提供对Pod的声明性更新以及许多其他有用的功能。因此,我们建议您使用Deployment而不是直接使用ReplicaSet,除非您需要自定义更新编排或根本不需要更新。

这实际上意味着您可能永远不需要操作ReplicaSet对象:使用Deployment替代,并在spec部分中定义应用程序。

示例

  1. apiVersion: apps/v1beta2 # for versions before 1.6.0 use extensions/v1beta1
  2. kind: ReplicaSet
  3. metadata:
  4. name: frontend
  5. labels:
  6. app: guestbook
  7. tier: frontend
  8. spec:
  9. # this replicas value is default
  10. # modify it according to your case
  11. replicas: 3
  12. selector:
  13. # 下面的是equality-based selector requirement
  14. matchLabels:
  15. tier: frontend
  16. # 下面的是set-based selector requirement
  17. matchExpressions:
  18. - {key: tier, operator: In, values: [frontend]}
  19. template:
  20. metadata:
  21. labels:
  22. app: guestbook
  23. tier: frontend
  24. spec:
  25. containers:
  26. - name: php-redis
  27. image: gcr.io/google_samples/gb-frontend:v3
  28. resources:
  29. requests:
  30. cpu: 100m
  31. memory: 100Mi
  32. env:
  33. - name: GET_HOSTS_FROM
  34. value: dns
  35. # If your cluster config does not include a dns service, then to
  36. # instead access environment variables to find service host
  37. # info, comment out the 'value: dns' line above, and uncomment the
  38. # line below.
  39. # value: env
  40. ports:
  41. - containerPort: 80

将此清单保存为frontend.yaml ,并将其提交给Kubernetes集群,即可创建你所定义的ReplicaSet以及ReplicaSet管理的Pod。

  1. $ kubectl create -f frontend.yaml
  2. replicaset "frontend" created
  3. $ kubectl describe rs/frontend
  4. Name: frontend
  5. Namespace: default
  6. Selector: tier=frontend,tier in (frontend)
  7. Labels: app=guestbook
  8. tier=frontend
  9. Annotations: <none>
  10. Replicas: 3 current / 3 desired
  11. Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
  12. Pod Template:
  13. Labels: app=guestbook
  14. tier=frontend
  15. Containers:
  16. php-redis:
  17. Image: gcr.io/google_samples/gb-frontend:v3
  18. Port: 80/TCP
  19. Requests:
  20. cpu: 100m
  21. memory: 100Mi
  22. Environment:
  23. GET_HOSTS_FROM: dns
  24. Mounts: <none>
  25. Volumes: <none>
  26. Events:
  27. FirstSeen LastSeen Count From SubobjectPath Type Reason Message
  28. --------- -------- ----- ---- ------------- -------- ------ -------
  29. 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh
  30. 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy
  31. 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l
  32. $ kubectl get pods
  33. NAME READY STATUS RESTARTS AGE
  34. frontend-9si5l 1/1 Running 0 1m
  35. frontend-dnjpy 1/1 Running 0 1m
  36. frontend-qhloh 1/1 Running 0 1m

编写ReplicaSet的spec

与所有其他Kubernetes API对象一样,ReplicaSet需要apiVersionkindmetadata 等字段。关于使用清单的一般信息,请参阅 hereherehere

ReplicaSet还需要一个 .spec section

Pod模板

.spec.template.spec 唯一必需的字段。 .spec.template是一个 pod template 。 它与 pod 有完全相同的模式——除了是嵌套的,没有apiVersion 以及kind 以外。

除Pod必需的字段外,ReplicaSet中的Pod模板必须指定适当的标签和适当的重新启动策略。

对于标签,请确保不会与其他Controller重叠。 有关更多信息,请参阅 pod selector

对于 restart policy.spec.template.spec.restartPolicy 的唯一允许的值是Always ,这是默认值。

对于本地容器重新启动,ReplicaSet将委托给Node上的代理,例如 Kubelet 或Docker。

Pod选择器

.spec.selector 字段是一个 label selector 。 一个ReplicaSet管理所有与标签选择器相匹配的Pod。它不区分其创建或删除的Pod,也不区分另一个人或进程创建或删除的Pod。这允许我们在不影响正在运行的Pod的前提下替换ReplicaSet。

.spec.template.metadata.labels 必须与.spec.selector 匹配,否则将被API拒绝。

在Kubernetes 1.8中,ReplicaSet类型上当前的API版本是apps/v1beta2 ,默认启用。API版本extensions/v1beta1 已被弃用。 在API版本apps/v1beta2 中,如果没有设置,则.spec.selector.metadata.labels 默认不再与.spec.template.metadata.labels 一致。 因此,必须明确设定这些字段。 另外,在API版本apps/v1beta2 中,一旦ReplicaSet创建, .spec.selector 是不可变的。

此外,您通常不应创建任何标签与此选择器匹配的Pod,不管是直接创建、使用ReplicaSet或其他Controller(例如Deployment)。 如果这样做,ReplicaSet会认为它创建了其他Pod。Kubernetes并不会阻止你这样做。

如果您最终使用具有重叠选择器的多个Controller,则必须自行管理删除。

ReplicaSet上的标签

ReplicaSet本身可以有标签( .metadata.labels )。 通常,您应该将这些该字段设置为与.spec.template.metadata.labels 相同。 但是,也允许不同,.metadata.labels 不会影响ReplicaSet的行为。

Replicas(副本)

您可以通过设置.spec.replicas 来指定同时运行多少个Pod。任何时间运行的Pod个数都可能会更高或更低,例如,如果replica刚刚增加或减少;或者如果Pod优雅关闭,而替换提前启动。

如果不指定.spec.replicas ,则默认为1。

使用ReplicaSet

删除ReplicaSet和其Pod

可使用 kubectl delete 删除ReplicaSet及其所有pod。Kubectl将ReplicaSet缩放为零,并等待它删除每个Pod,然后再删除ReplicaSet本身。 如果这个kubectl命令被中断,可以重启。

当使用REST API或Go语言客户端库时,需要明确执行这些步骤(将副本缩放为0,等待Pod删除,然后删除ReplicaSet)。

只删除ReplicaSet

可以只删除ReplicaSet,而不影响ReplicaSet的任何Pod,使用 kubectl delete--cascade=false 选项即可。

使用REST API或Go语言客户端库时,只需删除ReplicaSet对象即可。

原始的ReplicaSet被删除后,您可以创建一个新的ReplicaSet来替换它。只要新旧ReplicaSet的.spec.selector 相同,那么新ReplicaSet就会使用旧ReplicaSet的Pod。然而,它不会努力使已存在的Pod去匹配一个新的、不同的Pod模板。要想以可控的方式将Pod更新为新的spec,请使用 rolling update

从ReplicaSet隔离Pod

可以通过更改其标签的方式,从ReplicaSet中删除Pod。此技术可用于从Service中删除Pod,从而进行debug、数据恢复等。以这种方式删除的Pod将被自动替换(假设副本的数量也不会改变)。

ReplicaSet伸缩

只需更新.spec.replicas 字段即可轻松缩放ReplicaSet。ReplicaSet controller会确保集群中有指定数量的Pod可用并可操作。

ReplicaSet作为Horizontal Pod Autoscaler(HPA)目标

ReplicaSet也可以是 Horizontal Pod Autoscalers (HPA) 的目标。也就是说,ReplicaSet可以由HPA自动伸缩。以下是一个HPA指向我们在上一个示例中创建的ReplicaSet的示例。

  1. apiVersion: autoscaling/v1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: frontend-scaler
  5. spec:
  6. scaleTargetRef:
  7. kind: ReplicaSet
  8. name: frontend
  9. minReplicas: 3
  10. maxReplicas: 10
  11. targetCPUUtilizationPercentage: 50

将此清单保存为hpa-rs.yaml 并将其提交到Kubernetes集群,这样就会创建一个HPA,根据Pod副本的CPU使用率自动调整目标ReplicaSet。

  1. kubectl create -f hpa-rs.yaml

或者,您可以使用kubectl autoscale 命令来完成相同的操作(并且更容易!)

  1. kubectl autoscale rs frontend

ReplicaSet的替代方案

Deployment(推荐)

Deployment 是一种更高级的API对象,它以与kubectl rolling-update 类似的方式,更新其底层的ReplicaSet及其Pod。如果您想要滚动更新的功能,则建议使用Deployment,因为与kubectl rolling-update 不同,它们是声明式、服务器端的,并且具有其他特性。有关使用Deployment运行无状态应用的更多信息,请阅读 Run a Stateless Application Using a Deployment

Bare Pod(裸Pod)

与用户直接创建Pod的情况不同,ReplicaSet会替换由于任何原因被删除或终止的pod,例如在Node故障或Node中断维护(例如内核升级)的情况下。 因此,我们建议您使用ReplicaSet,即使您的应用程序只需要一个Pod。 与process supervisor(进程管理器)类似,ReplicaSet只能监视多个Node上的多个Pod,而不是单个Node上的单个进程。ReplicaSet将本地容器的重启委托给Node上的某个代理(例如,Kubelet或Docker)。

Job(作业)

对于可预期会终止的Pod(即批处理作业),可以使用 Job 而非ReplicaSet。

DaemonSet

对于提供机器级功能(例如机器监控或日志)的Pod,请使用 DaemonSet 而非ReplicaSet。 这些Pod的生命周期与机器的生命周期相关:在其他Pod启动之前,这些Pod需要在机器上运行;当机器准备重启/关闭时,可安全终止这些Pod。

原文

https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/