Kubernetes基本概念和术语之Deployment、Horizontal Pod Autoscaler和StatefulSet
1.Deployment
Deployment是为了更好的解决Pod的编排问题才引入的,可以把它看作是RC的一次升级,最大的升级是我么可以看到Pod部署的进度。
Deployment典型的使用场景如下:
- 创建一个Deployment对象来生成对应的Replica Set(相当于RC的进化版,kubernetes v1.2引入)并完成Pod副本的创建过程
- 检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期值)
- 更新Deployment以创建新的Pod(如镜像升级)
- 若当前Deployment不稳定则回滚到早先Deployment版本
- 暂停Deployment以便修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新发布
- 扩展Deployment以应对高负载
- 查看Deployment的状态,以此作为发布是否成功的指标
- 清理不在需要的旧版本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负载的度量指标:
- CPUUtilizationPercentage
- 应用程序自定义的度量指标,比如服务在每秒内的相应的请求数(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集群等,这些服务有以下一些共同点
- 每个节点有固定的身份ID,通过这个ID,集群中的成员可以互相发现并通信
- 集群规模比较固定,不会随意改动
- 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中
- 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损
如果用RC/Deployment控制Pod副本数的方式来实现上述有状态的集群,则我们会发现第一点就无法实现,因为Pod的名字是随机产生的,Pod的ip也是在运行期确定的且可能会变动,我们事先无法为每个Pod创建一个唯一的ID。。。为了解决以上问题,kubernetes从v1.5版本开始引入了StatefulSet,从本质上来它可以看做是RC/Deployment的一个特殊变种,它有如下一些特性:
- StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员
- StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
- 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域名都可以直接在配置文件中固定下来