pod调度之Deployment或RC:全自动调度

在最早的kubernetes版本里只有一个pod副本控制器RC(Replication Controller)
RC独立于所控制的pod,并通过Lable标签这个松耦合关联关系控制目标pod实例的创建和销毁。
RC的标签选择器只能选择一个标签,于是有了RC的增强版:RS(RepicaSet),RS拥有集合石的标签选择器,可以选择多个pod标签。kubernetes的滚动升级就是运用了RS的这个特性来实现的。
通常,我们使用Deployment对象调用RS控制器来自动完成pod副本的部署,版本更新,回滚等操作。
Deployment或RC的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。
下面是一个Deployment配置的例子,使用这个配置文件可以创建一个ReplicaSet,这个ReplicaSet会创建3个nginx应用的Pod。

vim nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80

运行kubectl create 命令创建这个Deployment

[root@bogon ~]# kubectl create -f nginx-deployment.yaml 
deployment.apps/nginx-deployment created

查看Deployment的状态

[root@bogon ~]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           37s

该状态说明Deployment 已经创建好所有3个副本,并且所有副本都是可用的。
查看RS的状态

[root@bogon ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-85ff79dd56   3         3         3       46s

查看Pod状态信息

[root@bogon ~]# kubectl get pods
NAME                                READY   STATUS      RESTARTS   AGE
nginx-deployment-85ff79dd56-jcl67   1/1     Running     0          6m41s
nginx-deployment-85ff79dd56-jsmkp   1/1     Running     0          6m41s
nginx-deployment-85ff79dd56-s7b6t   1/1     Running     0          6m41s

从调度策略上来说,这3个nginx pod由系统全自动完成调度。他们各自运行在哪个节点上,完全有master的scheduler经过一系列算法计算得出,用户无法敢于调度过程和结果。

Deployment的升级

将Pod镜像更新为nginx:1.9.1。
方法一:
kubectl set image 命令为Deployment设置新的镜像名称:

–record: 记录每个版本使用的命令

[root@bogon ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
deployment.apps/nginx-deployment image updated

方法二:
kubectl edit 命令修改deployment的配置。
将nginx:1.91改为nginx:1.10.1

[root@bogon ~]# kubectl edit deployment/nginx-deployment
deployment.apps/nginx-deployment edited

查看Deployment的更新 过程

[root@bogon ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out

Deployment是如何完成Pod更新的呢?

kubectl describe deployment/nginx-deployment查看更新过程

kubectl describe deployment/nginx-deployment
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  32m    deployment-controller  Scaled up replica set nginx-deployment-54f57cf6bf to 3
  Normal  ScalingReplicaSet  22m    deployment-controller  Scaled up replica set nginx-deployment-56f8998dbc to 1
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled down replica set nginx-deployment-54f57cf6bf to 2
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled up replica set nginx-deployment-b44c4b8f to 1
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled down replica set nginx-deployment-56f8998dbc to 0
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled up replica set nginx-deployment-b44c4b8f to 2
  Normal  ScalingReplicaSet  5m13s  deployment-controller  Scaled down replica set nginx-deployment-54f57cf6bf to 1
  Normal  ScalingReplicaSet  5m13s  deployment-controller  Scaled up replica set nginx-deployment-b44c4b8f to 3
  Normal  ScalingReplicaSet  5m11s  deployment-controller  Scaled down replica set nginx-deployment-54f57cf6bf to 0

当更新Deployment时,系统创建了一个ReplicaSet(nginx-deployment-b44c4b8f),并将其副本数量扩展到1,然后将旧的ReplicaSet 缩减为2。
之后,系统继续按照相同的更新策略对新旧两个ReplicaSet 进行逐个调整。
最后新的ReplicaSet运行了3个新版本Pod副本,旧的ReplicaSet 副本数量则缩减为0.
整个升级的过程中,系统会保证至少有两个pod可用,并且最多同时运行4个pod,这是Deployment通过复杂算法完成的。

通过spec.strategy参数设置,目前之前两种更新策略:

  • Recreate(重建)
    在更新Pod时,会先杀掉所有正在运行的pod,然后重建新的Pod
  • RollingUpdate(滚动更新)
    默认策略。以滚动更新的方式来逐个 更新Pod。

暂停更新

kubectl rollout pause  deployment/nginx-deployment

恢复更新

kubectl rollout resume  deployment/nginx-deployment

Deployment的回滚

首先,用kubectl rollout histroy命令检查这个Deployment部署的历史记录:

[root@bogon ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>
4         kubectl set image deployment/nginx-deployment nginx=nginx:1.10.3 --record=true

none:表示在做更新操作时没有加上–record参数。

回滚到指定的部署版本号:

[root@bogon ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back

可以从Deployment 时间信息中看到回滚到版本的2的操作过程。

在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。
此时我们可以利用 Deployment/RC 的Scale机制来完成这些工作。

Kubernetes对Pod的扩容和缩容操作提供了手动自动两种模式。

手动模式通过执行kubectl scale命令对一个 Deployment/RC 进行Pod副本数量的设置,即可一键完成。

自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。

手动扩容和缩容机制

以Deployment nginx 为例:
已运行的pod副本数量为3个:

[root@bogon ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-56f8998dbc-5q64q   1/1     Running   0          70m
nginx-deployment-56f8998dbc-c4s2q   1/1     Running   0          72m
nginx-deployment-56f8998dbc-s2s2b   1/1     Running   0          71m

通过kubectl scale命令可以将Pod副本数量从初始的3个更新为5个:

[root@bogon ~]# kubectl scale deployment/nginx-deployment --replicas 5
deployment.apps/nginx-deployment scaled

[root@bogon ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-56f8998dbc-5q64q   1/1     Running   0          77m
nginx-deployment-56f8998dbc-c4s2q   1/1     Running   0          79m
nginx-deployment-56f8998dbc-jqwm8   1/1     Running   0          25s
nginx-deployment-56f8998dbc-s2s2b   1/1     Running   0          77m
nginx-deployment-56f8998dbc-x9bhg   1/1     Running   0          25s

将–replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,以实现应用集群缩容:

[root@bogon ~]# kubectl scale deployment/nginx-deployment --replicas 1
deployment.apps/nginx-deployment scaled

[root@bogon ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-56f8998dbc-s2s2b   1/1     Running   0          79m

自动扩容和缩容机制

从Kubernetes v1.1 版本开始,新增了名为Horizontal Pod Autoscaler(HPA)的控制器,用于实现基于CPU使用率进行自动Pod扩容和缩容的功能。

HPA控制器基于Master的kube-controller-manager服务启动参数–horizontal-pod-autoscaler-sync-period定义的时长(默认30s),周期性地检测目标Pod的CPU使用率,并在满足条件时对 Deployment/RC 或 Deployment 中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。

HPA的工作原理

kubernetes中的某个Metrics Server(Heapster<已弃用!!>或自定义Metrics Server) 持续采集所有Pod副本的指标数据。

HPA控制器通过Metrics Server的API获取这些数据,基于用户定义的扩容缩容规则进行计算,得到目标Pod副本数量。

当目标Pod副本数量与当前副本数量不同时,HPA控制器就向Pod的副本控制器(Deployment,RC,或者ReplicaSet)发起scale操作,调整Pod的副本数量,完成扩容缩容操作。

指标类型

Master节点上的kube-Controller-manger服务支持检测目标Pod的某种性能指标,以计算是否需要调整副本数量。
目前HPA能够管理的指标类型如下:

  • Pod资源使用率:
    pod级别的性能指标
    通常是一个比率值,例如cpu使用率。
  • Pod自定义指标:
    pod级别的性能指标
    通常是一个数值,例如接收的请求数量。
  • Object 自定义指标或外部自定义指标:
    通常是一个数值,需要容器应用以某种方式提供。例如通过HTTP URL "/metrics"提供,或者使用外部服务提供的指标采集URL。

扩容缩容算法详解

Autoscale 控制器从聚合API获取到Pod性能指标数据之后,基于下面的算法计算出目标pod的副本数量,与当前运行的pod副本数量进行对比,决定是否需要进行扩容缩容操作:

当前副本数 vs(当前指标值/期望的指标值)

将结果向上取整数。

HPA 配置详解

HorizontalPodAutoscale 资源对象处于Kubernetes·的API组“autoscaling”中。
目标包括v1和v2两个版本。

autoscaling/v1: 仅支持基于cpu使用率的自动扩容缩容。

autoscaling/v2: 用于支持基于任意指标的自动扩容缩容配置。包括基于资源使用率,pod指标,其他指标等类型的指标数据。

主要参数如下:

  1. scaleTargetRef:
    目标作用对象。可以是Deployment,ReplicaSet,RC.
  2. minReplicas:
    pod副本数量的最小值
  3. maxReplicas:
    pod副本数量的最大值
  4. metrics
    目标指标值。

metrics中的type(指标类型)设置可以为以下三种的任意组合:

  1. Resource
    可以设置的资源为cpu和内存。
    要求预先启动Merics Server服务(Heapster)。

  2. Pods

  3. Object
    推荐使用

pods类型和object类型都属于自定义指标类型。指标的数据通常需要搭建自定义Metrics Server和监控工具进行采集和处理。
要求预先启动自定义Metrics server服务(prometheus监控组件)

基于自定义指标的HPA实践

基于prometheus监控系统对HPA的基础组件部署和HPA配置进行详细说明。

你可能感兴趣的:(k8s)