如何在Kubernetes中管理有状态应用

比特筑梦说
• 阅读 3277

在Kubernetes中,StatefulSet被用来管理有状态应用的API对象。StatefulSets在Kubernetes 1.9版本才稳定。StatefulSet管理Pod部署和扩容,并为这些Pod提供顺序和唯一性的保证。与Deployment相似的地方是,StatefulSet基于spec规格管理Pod;与Deployment不同的地方是,StatefulSet需要维护每一个Pod的唯一身份标识。这些Pod基于同样的spec创建,但互相之间不能替换,每一个Pod都保留自己的持久化标识。


1、使用StatefulSet的场景

对于下面的应用场景,StatefulSets是有价值的:

  • 稳定、唯一的网络标识
  • 稳定、持久的存储
  • 按照顺序、优雅的部署和扩容
  • 按照顺序、优雅的删除和终止
  • 按照顺序、自动滚动更新

上述的稳定是持久的同义词,如果应用不需要稳定的标识或者顺序的部署、删除、扩容,则应该使用无状态的副本集。Deployment或者ReplicaSet的控制器更加适合无状态业务场景。

2、StatefulSet的限制

  • 在Kubernetes 1.9版本之前是beta版本,在Kubernetes 1.5版本之前是不提供的。
  • Pod存储由PersistentVolume(storage类或者管理员预先创建)提供。
  • 删除或者缩容StatefulSet不会删除与StatefulSet关联的数据卷,这样能够保证数据的安全性。
  • 当前的StatefulSets需要一个Headless服务来为Pod提供网络标识,此Headless服务需要通过手工创建。

3、组件

下面是一个StatefuleSet组成的示例:

  • 一个名称为nginx的Headless服务,用来控制网络域。
  • 一个名称为web的statefulSet,它拥有nginx容器(在唯一的Pod启动)的3个副本集。
  • 使用PersistenVolumes(由PersistentVolume
    Provisioner提供)提供稳定存储的volumeClaimTemplates。
apiVersion:v1
kind:Service
metadata:
  name:nginx
  labels:
     app:nginx
spec:
  ports:
  -port:80
     name:web
  clusterIP:None //Headless服务
  selector:
     app:nginx
---
apiVersion:apps/v1
kind:StatefulSet
metadata:
  name:web
spec:
  selector:
     matchLabels:
       app:nginx# has to match .spec.template.metadata.labels
  serviceName:"nginx"
  replicas:3 # by default is 1
  template:
     metadata:
       labels:
         app:nginx # has to match .spec.selector.matchLabels
     spec:
       terminationGracePeriodSeconds:10
       containers:
       -name:nginx
         image:k8s.gcr.io/nginx-slim:0.8
         ports:
         -containerPort:80
           name:web
         volumeMounts: #挂接数据卷
         -name:www
           mountPath:/usr/share/nginx/html #挂接路径为容器的/usr/share/nginx/html
  volumeClaimTemplates: #数据卷生命模板
  -metadata:
       name:www
     spec:
       accessModes:["ReadWriteOnce"]
       storageClassName:my-storage-class
       resources:
         requests:
           storage:1Gi 

4、Pod选择器

必须设置StatefulSet的sepc.selector,以匹配.spec.template.metadata.labels。在Kubernetes 1.8之前,spec.selector是可以忽略的,它被设置一个默认值。在1.8或者后续的版本,如果不设置sepc.selector,则会导致创建StatefulSet失败。

5、Pod身份标识

StatfuleSet Pod拥有一个唯一的身份标识,它由顺序、稳定的网络标识和稳定的存储所组成。此身份标识一直跟随着Pod,不过它被调度到那个Node上。

5.1 序数索引(Ordinal Index)

对于拥有N个副本集的StatefulSet,在StatefulSet中的每一个Pod都会被指派一个整型的序数,此序数在0和N之间,在整个集合中是唯一的。

5.2 网络ID(Stable Network ID)

在StatefulSet中,每一个Pod的主机名称都由StatefulSet的名称和序数所组成。Pod的主机名称的格式:$(statefulset name)-$(ordinal)。如果创建了三个Pod,这他们的主机名称为web-0,web-1,web-2。StatefulSet能够使用Headless服务来控制Pod的域。Service管理的域的格式为:$(service name).$(namespace).svc.cluster.local,cluster.local是集群域。对于每一个被创建的Pod,它将得到一个DNS子域,格式为: $(podname).$(governing service domain),这里的管理服务在StatefulSet中,通过serviceName设置。

下面是StatefulSet中Pod在DNS中的名称:

如何在Kubernetes中管理有状态应用

5.3 稳定的存储

kubernetes为每一个VolumeClaimTemplate创建一个对应的PersistentVolume。在前面的nginx实例中,每一个Pod将会my-storage-class存储类型的PersistenVolume单一实例和1Gib的存储空间。

如果没有指定存储类,则会使用默认的存储。但一个Pod被调度到Node上,它的volumeMounts将会挂接PersistentVolumes,并将其与PersistentVolumeClaims进行关联。需要注意的是,即使在Pod被删除,PersistentVolumes与PersistentVolumeClaims之间的关联关系也不会被删除。

5.4 Pod命名标签

当StatefulSet控制器创建了Pod,它将会添加一个标签,为此Pod名称的集合。此标签将能够管理服务到指定的Pod。

6、部署和扩容保证

  • 对于一个带有N个副本集的StatefulSet,当Pod被部署,它们将按0到N-1的顺序被创建。
  • 当一Pod被删除时,它们将按照N-1到0的倒序被终止。
  • 在进行Pod扩容前,所有依赖的Pod应该都已在运行和准备好。
  • 在Pod被终止前,所有的依赖它的Pod都必须完全停止。

在前文创建的nginx例子中,将按照顺序部署web-0,web-1和web-2。web-1只能在web-0运行和准备好以后才能够被部署,web-2只能在web-1运行和准备好以后才能够被部署。如果web-0失败,就算web-1正在运行,web-2也是不能正常启动的,除非web-0被重启,并正常运行。

如果缩容上述例子,设置replicas=1,则web-2首先被终止,接着是web-1。如果在web-2被终止后,但在web-1被终止前,web-0失败了,web-1将不能被终止,除非web-0处于正常运行状态。

6.1 Pod管理策略

在Kubernetes 1.7以后,StatefulSet的唯一性标识可以通过.spec.podManagementPolicy的值进行保证。

6.1.1 OrderedReady Pod管理

OrderedReady pod管理是StatefulSets默认的管理模式,此模式安装顺序启动或者终止Pod。

6.1.2 并行Pod管理

并行Pod管理告诉StatefulSet控制器以并行的方式启动或者终止所有的Pod。

7、更新策略

在Kubernetes 1.7之后,运行通过配置StatefulSet的.spec.updateStrategy,实现Pod的容器、标签、资源请求/限制和注释自动更新。

7.1 On Delete策略

OnDelete更新策略是1.6之前版本的行为。当StatefulSet的.spec.updateStrategy.type被设置为OnDelete,则StatefulSet控制器将不会知道更新Pod。

7.2 Rolling Updates策略

RollingUpdate更新策略将实现StatefulSet中Pod的自动滚动更新,这是StatefulSet的默认更新模式。如果.spec.updateStrategy.type设置为 RollingUpdate,则StatefulSet控制器将会删除和重建StatefulSet中的每一Pod。它将会按照从最大到最小的序数终止Pod,并按照从小到大顺序重建Pod。

7.3 Partitions

RollingUpdate更新策略能够通过指定.spec.updateStrategy.rollingUpdate.partition进行分隔。当分隔被指定,所有序数大于或等于分隔的Pod将会被更新,其它的Pod将被不会进行更新。在大部分的情况下,不会使用分隔;当希望进行金丝雀发布,或者执行阶段发布时,分隔是很有用的。

作者简介: 季向远,北京神舟航天软件技术有限公司产品经理。本文版权归原作者所有。

微信号:RancherLabs

点赞
收藏
评论区
推荐文章
Prodan Labs Prodan Labs
4年前
Kubernetes Pod 自动扩容 — HPA
Kubernetes增强了应用服务的横向扩容能力,在应对线上应用服务的资源使用率在高峰和低谷的时候,我们需要能够自动去感知应用的负载变化去调整Pod的副本数量,削峰填谷,提高集群的整体资源利用率和应用的服务质量。为此,Kubernetes1.2版本中引入HorizontalPodAutoscaling(HPA),它与kubectlsc
Stella981 Stella981
3年前
K8s——Ingress
在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,在Kubernetes中目前提供了以下几种方案:1.NodePort2.LoadBalancer3.IngressNodePort,简单来说,就是通过service这种资源对象,为后端
Stella981 Stella981
3年前
Kubernetes的四种用户部署场景,你知吗?
Kubernetes可以作为容器编排引擎、PaaS或者作为云原生应用的核心基础架构被用户部署到生产环境。这些用例并不是相互排斥的。DevOps可以委托基于Kubernetes的PaaS层完成整个应用生命周期的管理(ALM),也可以独立部署Kubernetes管理CI/CD工具部署的应用。对于新应用程序可以使用Kubernetes管理微服务架构的云原始应用,支
Wesley13 Wesley13
3年前
K8S基础概念
一、核心概念1、NodeNode作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的Kubelet、kubeproxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡。Node包含
Stella981 Stella981
3年前
Kubernetes Pod 故障归类与排查方法
Pod概念Pod是kubernetes集群中最小的部署和管理的基本单元,协同寻址,协同调度。Pod是一个或多个容器的集合,是一个或一组服务(进程)的抽象集合。Pod中可以共享网络和存储(可以简单理解为一个逻辑上的虚拟机,但并不是虚拟机)。Pod被创建后用一个UID来唯一标
Stella981 Stella981
3年前
Kubernetes运行有状态应用:7项有效注意事项
!(https://oscimg.oschina.net/oscnet/4c6911d85724cc605d670b07e94e41c2c30.gif)Kubernetes是一个开放编排平台,旨在用于部署,管理容器化的应用程序。在Kubernetes的早期,该平台主要支持和运行无状态应用程序。无状态应用程序,被认为在重新启动容器时不需要保留从上一
Wesley13 Wesley13
3年前
(三)Kubernetes 快速入门
 Kubernetes的核心对象APIServer提供了RESTful风格的编程接口,其管理的资源是KubernetesAPI中的端点,用于存储某种API对象的集合,例如,内置Pod资源是包含了所有Pod对象的集合。资源对象是用于表现集群状态的实体,常用于描述应于哪个节点进行容器化应用、需
Stella981 Stella981
3年前
Prometheus监控神器
在Kubernetes中手动部署Statefulset类型的Prometheus、Alertmanager集群,并使用StorageClass来持久化数据。本篇使用StorageClass来持久化数据,搭建Statefulset的Prometheus联邦集群,对于数据持久化,方案众多,如Thanos、M3DB、InfluxDB、VictorMetri
Stella981 Stella981
3年前
Kubernetes(K8S)
一、简介  Kubernetes是Google公司在2014年6月开源的一个容器集群管理系统,使用Go语言开发,也叫K8S。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着
Stella981 Stella981
3年前
K8s(7)
仪表板是基于Web的Kubernetes用户界面。您可以使用仪表板将容器化应用程序部署到Kubernetes集群,对容器化应用程序进行故障排除,以及管理集群资源。您可以使用仪表板来概述群集上运行的应用程序,以及创建或修改单个Kubernetes资源(例如部署,作业,守护进程等)。例如,您可以使用部署向导扩展部署,启动滚动更新,重新启动Pod或部署新应用程序
Stella981 Stella981
3年前
K8s StatfulSet使用总结
StatefulSet:在1.3以前K8s中StatefulSet叫PetSet(宠物集),由此也可看出StatefulSet是关注个体,而非群体。StatefulSet要满足以下几点:稳定且唯一的网络标识符;如:Redis集群,在Redis集群中,它是通过槽位来存储数据的,假如:第一个节点是0~1000,第二个节点是1