Replica Sets

苏晓林 [email protected]

ReplicaSet是下一代的Replication Controller。两者之间的唯一区别在于对selector的支持。ReplicaSet支持集合类型的selector,而Replication Controller只支持等式类型的selector。

如何使用ReplicaSet

基本上所有支持Replication Controllers的kubectl命令都支持ReplicaSet(rolling-update命令除外)。当你准备使用滚动升级功能时,最好使用Deployments。并且,由于rolling-update命令是固定式的,而Deployments属于声明式,因此强烈建议使用rollout命令使用Deployments。

虽然ReplicaSet能够独立使用,但是在实际使用过程中,通常通过Deployments进行管理。当通过Deployments管理ReplicaSet时,你不必关心ReplicaSet,Deployments会自动对其进行管理。

何时使用ReplicaSet

ReplicaSet的作用是确保指定数量的pods在运行。而Deployment作为一个上层概念,通过管理ReplicaSet来来完成pod的更新和其它一些特性。强烈建议通过Deployments来管理ReplicaSets,而不要直接操作ReplicaSets,除非需要进行自定义更新流程或根本不需要更行。

因此实际上你可能永远也不用直接操作ReplicaSet,通过Deployments来管理并定义你的应用程序。

ReplicaSet例子

frontend.yaml

apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # this replicas value is default
  # modify it according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below.
          # value: env
        ports:
        - containerPort: 80

创建并查看该ReplicaSet及其管理的pods

$ kubectl create -f frontend.yaml
replicaset "frontend" created
$ kubectl describe rs/frontend
Name:        frontend
Namespace:    default
Selector:    tier=frontend,tier in (frontend)
Labels:        app=guestbook
        tier=frontend
Annotations:    <none>
Replicas:    3 current / 3 desired
Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:       app=guestbook
                tier=frontend
  Containers:
   php-redis:
    Image:      gcr.io/google_samples/gb-frontend:v3
    Port:       80/TCP
    Requests:
      cpu:      100m
      memory:   100Mi
    Environment:
      GET_HOSTS_FROM:   dns
    Mounts:             <none>
  Volumes:              <none>
Events:
  FirstSeen    LastSeen    Count    From                SubobjectPath    Type        Reason            Message
  ---------    --------    -----    ----                -------------    --------    ------            -------
  1m           1m          1        {replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-qhloh
  1m           1m          1        {replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-dnjpy
  1m           1m          1        {replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-9si5l
$ kubectl get pods
NAME             READY     STATUS    RESTARTS   AGE
frontend-9si5l   1/1       Running   0          1m
frontend-dnjpy   1/1       Running   0          1m
frontend-qhloh   1/1       Running   0          1m

定义ReplicaSet

与其它的Kubernetes API一样,ReplicaSet也需要apiVersion,kindmetadata字段。关于通用字段信息可查看对象管理

ReplicaSet的.spec信息:

Pod Template

.spec.template字段是.spec的唯一必需字段。该字段与pod的定义模版几乎完全一致,但是没有apiVersionkind字段,并且必须指定标签和重启策略。

标签必须不能与其它controllers的标签重叠,标签的详细信息可以查看pod selector

对于重启策略,.spec.template.spec.restartPolicy字段唯一允许的值为Always,默认即为此值。

Pod Selector

.spec.selector字段是一个标签selector,ReplicaSet会管理所有标签与该selector匹配的pods。无论pod是否由其创建、删除。因此可以在不影响运行中pod的情况下,更改该pod的ReplicaSet。

对于.spec.template.metadata.labels字段不匹配.spec.selector的pod,将会被拒绝。

在Kubernetes 1.8中,apps/v1beta2已经作为默认版本,extensions/v1beta1版本将会被移除。在apps/v1beta2版本中,.spec.selector.metadata.labels字段将不会默认填充.spec.template.metadata.labels字段的值,必须明确指定。注意,在apps/v1beta2版本中,.spec.selector字段在创建后将不允许改变。并且不要以任何其它的方式创建带有能够匹配该selector标签的pods,因为该ReplicaSet会认为这些pods是自己创建的。Kubernetes不会阻止你这么做,所以你必须自己规避这种情况。

当多个controllers的selectors重叠时,你需要自己管理删除操作。

ReplicaSet标签

ReplicaSet拥有自己的标签字段(.metadata.labels)。通常该字段的值与.spec.template.metadata.labels的值一致。但并不是强制性的,且.metadata.labels的值并不影响ReplicaSet的行为。

Replicas

通过设置.spec.replicas字段来控制pods的数量。未指定时,默认值为1。

ReplicaSet操作

删除ReplicaSet及其pods

可以通过命令kubectl deleteReplicaSet及其pods。Kubectl会首先将ReplicaSet的Replicas设置为0,然后等待所有pods删除以后,最后删除该ReplicaSet。如果这个kubectl命令被中断,它可以被重新启动。

当使用REST API或go客户端删除ReplicaSet及其pods时,你必须自己完成Kubectl完成的三个步骤(1.设置ReplicaSet为0 2.等待所有pods删除 3.删除ReplicaSet)。

只删除ReplicaSet

通过kubectl delete--cascade=false选项可以实现只删除ReplicaSet,而不影响其拥有的pods。

当使用REST API或go客户端时,只需删除该ReplicaSet即可。

当删除ReplicaSet后,你可以新建一个.spec.selector字段值相同的ReplicaSet来替代它。先创建的ReplicaSet会接管之前的pods。这种方式不会对之前已经存在的pod有任何影响。当你需要升级pod时,请使用滚动升级

pod脱离

pod可通过更改自己的标签,来脱离ReplicaSet的控制。当你需要调试或数据恢复时,可能会这么做。通过这种方式移除的pod,ReplicaSet会自动创建新的pod来替代原来的pod。

弹性伸缩

通过设置.spec.replicas字段可以控制该ReplicaSet下pods的数量。ReplicaSet controller会确保该ReplicaSet下有指定数量的可用的pods。

作为Horizontal Pod Autoscaler的目标

可以把ReplicaSet作为Horizontal Pod Autoscalers (HPA)的目标,来实现自动扩容/缩容。下面是一个HPA的例子。

//hpa-rs.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-scaler
spec:
  scaleTargetRef:
    kind: ReplicaSet
    name: frontend
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

创建该HPA

kubectl create -f hpa-rs.yaml

也可以通过kubectl autoscale命令完成上述操作

kubectl autoscale rs frontend

ReplicaSet的可替代者

Deployment (推荐)

Deployment是一个更高层的API对象,可以像kubectl rolling-update命令一样,升级其下的ReplicaSets及pods。目前官方推荐使用Deployment来完成滚动升级功能。因为Deploymen是声明式、服务端的,并且有一些附加特性。想查看更多通过Deployment部署无状态应用的信息,请点击Run a Stateless Application Using a Deployment

直接部署pod

由于直接部署的pod当出现问题时,无法自我恢复,因此除非特殊原因,否则强烈不建议这么干。

Job

使用Job来完成那些期望自动终止的pods。

DaemonSet

通过DaemonSet可以完成一些与主机相关的功能,如:监控或日志。通过DaemonSet可以实现在每台主机上运行某个pod,并且当新主机加入或之前的主机删除时,自动进行部署或删除。

results matching ""

    No results matching ""