一、StatefulSet概述

应用程序存在有状态和无状态两种类别,因为无状态类应用的pod资源可按需增加、减少或重构,而不会对由其提供的服务产生除了并发相应能力之外的其他严重影响。pod资源的常用控制器中,deployment、replicaset和daemonset等常用于管理无状态应用。但实际情况是,应用本身就是分布式的集群,各应用实例彼此之间存在着关联关系,甚至是次序、角色方面的相关性,其中的每个实例都有其自身的独特性而无法轻易由其他实例所取代。

1、stateful应用和stateless应用

应用程序与用户、设备、其他应用程序或外部组件进行通信时,根据其是否需要记录前一次或多次通信中的相关信息以作为下一次通信的分类标准,可以将那些需要记录信息的应用程序称为有状态(stateful)应用,而无须记录的则称为无状态(stateless)应用。

状态是进程的时间属性。无状态意味着一个进程不必跟踪过去的交互操作,本质上可以说它是一个纯粹的功能性行为。相应地,有状态则意味着进程存储了以前交互过程的记录,并且可以基于它对新的请求进行响应。至于状态信息被保存在内存中。

存储是表述持久保存数据的方法,现今通常是指机械硬盘或ssd设备。若进程仅需操作内存中的数据,则表示其无须进行磁盘I/O操作;如果产生了I/O操作,则通常意味着数据的只读访问或读写访问行为。

2、statefulset的特性

statefulset简称sts,是pod资源控制器的一种实现,用于部署和扩展有状态应用的pod资源,确保他们的运行顺序及每个pod资源的唯一性。其与ReplicaSet控制器不同的是,虽然所有pod对象都基于同一个spec配置所创建,但statefulset需要为每个pod维持一个唯一且固定的标识符,必要时还要为其创建专用的存储卷。StatefulSet主要适用于那些依赖于下列类型资源的应用程序:

稳定且唯一的网络标识符

稳定且持久的存储

有序、优雅地部署和扩展

有序、优雅地删除和终止

有序而自动地滚动更新。

一般来说,一个典型、完整可用的StatefulSet通常由三个组件构成:Headless Service、StatefulSet和volumeClaimTemplate。其中,Headless Service用于为pod资源标识符生成可解析的DNS资源记录,StatefulSet用于管控pod资源,volumeClaimTemplate则基于静态或动态的PV供给方式为pod资源提供专有且固定的存储。

二、StatefulSet基础应用

1、创建statefulset对象

一个完整得分statefulset控制器需要由一个headless service、一个statefulset和一个volumeClaimTemplate组成。其中,Headless Service用于为pod资源标识符生成可解析的DNS资源记录,statefulset用于管控pod资源,volumeClaimTemplate则基于静态或动态的pv供给方式为pod资源提供专有且固定的存储:

apiVersion: v1
kind: Service
metadata:
  name: demo-svc
  labels:
    app: myapp-svc
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp-svc
  replicas: 2
  selector:
    matchLabels:
      app: myapp-pod
  template:
    metadata:
      labels:
        app: myapp-pod
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v5
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: myappdata
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: myappdata
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 2Gi

2、pod资源标识符及存储卷

由StatefulSet控制器创建的pod资源拥有固定、唯一的标识符和专用存储卷,即便重新调度或终止后重建,其名称也依然保持不变,且此前的存储卷及其数据不会丢失。

pod资源的固定标识符:

[root@master stateful]# kubectl get pods --show-labels
NAME      READY   STATUS    RESTARTS   AGE   LABELS
myapp-0   1/1     Running   1          22h   app=myapp-pod,controller-revision-hash=myapp-6c6b4f98d5,statefulset.kubernetes.io/pod-name=myapp-0
myapp-1   1/1     Running   1          22h   app=myapp-pod,controller-revision-hash=myapp-6c6b4f98d5,statefulset.kubernetes.io/pod-name=myapp-1

pod资源的主机名同其资源名称相同,这些名称标识会由StatefulSet资源相关的Headless Service资源创建为dns资源记录,其域名格式为$(service_name).$(namespace).svc.cluster.local。

Headless Service资源借助于SRV记录来引用真正提供服务的后端pod资源的主机名称,进行指向包含pod IP地址的记录条目。此外,由statefulset控制器管控的pod资源终止后会有控制器自动进行重建,虽然其IP地址存在变化的可能性,但它的名称标识在重建后会保持不变。因此,当客户端尝试向statefulset资源的pod成员发出访问请求时,应该针对Headless Service资源的CNAME记录进行,它指向的SRV记录包含了当前处于就绪状态的pod资源,考虑到名称标识固定不变,也可以让客户端直接向SRV资源记录发出请求。

 

posted on 2019-08-23 14:16  自然洒脱  阅读(2264)  评论(0编辑  收藏  举报