Kubernetes基本概念和术语之Deployment、Horizontal Pod Autoscaler和StatefulSet

1.Deployment

Deployment是为了更好的解决Pod的编排问题才引入的,可以把它看作是RC的一次升级,最大的升级是我么可以看到Pod部署的进度。

Deployment典型的使用场景如下:

  1. 创建一个Deployment对象来生成对应的Replica Set(相当于RC的进化版,kubernetes v1.2引入)并完成Pod副本的创建过程
  2. 检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期值)
  3. 更新Deployment以创建新的Pod(如镜像升级)
  4. 若当前Deployment不稳定则回滚到早先Deployment版本
  5. 暂停Deployment以便修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新发布
  6. 扩展Deployment以应对高负载
  7. 查看Deployment的状态,以此作为发布是否成功的指标
  8. 清理不在需要的旧版本ReplicaSets

创建Deployment的命令

kubectl create -f {deployment_fileName}.yaml

查看Deployment信息

kubectl get deployments

2.Horizontal Pod Autoscaler

Horizontal Pod Autoscaler简称HPA,意思是Pod横向自动扩容,与RC、Deployment都属于资源对象,通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数,这就是HPA的实现原理。

当前HPA有以下两种方式作为Pod负载的度量指标:

  1. CPUUtilizationPercentage
  2. 应用程序自定义的度量指标,比如服务在每秒内的相应的请求数(QPS或TPS)

CPUUtilizationPercentage是目标Pod所有副本自身的CPU利用率的平均值。一个Pod自身的CPU利用率=该Pod当前CPU的使用量÷Pod Request的值

CPUUtilizationPercentage计算过程中Pod的CPU使用量是1min内的平均值,可以通过Heapster组件(需要安装)来查,如果目标Pod没有定义Pod Request的值,则无法使用CPUUtilizationPercentage来实现Pod横向扩容的能力。除了使用CPUUtilizationPercentage,Kubernetes从v1.2开始尝试支持应用程序自定义的度量指标。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: pho-apache
  namespace: default
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    kind: Deployment
    name: php-apache
  targetCPUUtilizationPercentage: 90

如上定义,我们可以知晓HPA控制的对象为php-apache的Deployment里的Pod副本,当这些Pod副本的CPUUtilizationPercentage超过90%时会触发自动动态扩容,最大数量为10,最小为1,除了可以通过直接定义yaml文件并调用kubectl create命令来创建一个HPA的资源对象外,我们还可以直接命令行来创建,如下

kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10

3.StatefulSet

在kubernetes中,RC、Deployment、Job、DaemonSet等都是面向无状态的服务,但现实中有很多服务是有状态的,例如mysql集群、zk集群等,这些服务有以下一些共同点

  1. 每个节点有固定的身份ID,通过这个ID,集群中的成员可以互相发现并通信
  2. 集群规模比较固定,不会随意改动
  3. 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中
  4. 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损

如果用RC/Deployment控制Pod副本数的方式来实现上述有状态的集群,则我们会发现第一点就无法实现,因为Pod的名字是随机产生的,Pod的ip也是在运行期确定的且可能会变动,我们事先无法为每个Pod创建一个唯一的ID。。。为了解决以上问题,kubernetes从v1.5版本开始引入了StatefulSet,从本质上来它可以看做是RC/Deployment的一个特殊变种,它有如下一些特性:

  1. StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员
  2. StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
  3. StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了数据安全)

StatefulSet除了要与PV卷捆绑使用已存储Pod的状态数据,还要与Headless Service配合使用,即在每个StatefulSet的定义中要声明它属于哪个Headless Service,Headless Service与普通Service的区别在于,它没有Cluster IP,如果解析Headless Service的域名,它返回的是该service对应的全部Pod的endpoint列表。StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod实例创建了一个DNS域名,格式为:$(podname).$(headless service name),例如一个3节点的kafka的StatefulSet集群,对应的Headless Service的名字为kafka,StatefulSet的名字为kafka,则StatefulSet里边的3个Pod的DNS域名分别为kafka-0.kafka、kafka-1.kafka、kafka-2.kafka,这些DNS域名都可以直接在配置文件中固定下来

相关推荐