kubernetes-statefulset介绍

91 阅读4分钟

StatefulSet 介绍

需要借助 operater完成有状态应用的迁移

  • 需要指定replicas 但是每个replicas的标志是固定的, 由Headless Service 生成
  • 需要持久化存储 并且每个pod副本(容器应用)需要独占存储 所以就用volumeTemplate定义
  • pod的管理策略 需要有先后之分
  • 通常需要开发代码 完成有状态应用的扩容 重启 缩容等场景

功能:负责编排有状态(Stateful Application)应用

有状态应用解释

会在其会话中保存客户端的数据,并且有可能会在客户端下一次的请求中使用这些数据

应用上常见的状态类型:会话状态、连接状态、配置状态、集群状态、持久性状态等

大型应用通常具有众多功能模块,这些模块通常会被设计为有状态模块和无状态模块两部分

  • 业务逻辑模块一般会被设计为无状态,这些模块需要将其状态数据保存在有状态的中间件服务上,如消息队列、数据库或缓存系统等
  • 无状态的业务逻辑模块易于横向扩展,有状态的后端则存在不同的难题

StatefulSet控制器的特殊设计

StatefulSet控制器自Kubernetes v1.9版本才正式引入,为实现有状态应用编排,它依赖于几个特殊设计

各Pod副本分别具有唯一的名称标识

这依赖于一个专用的Headless Service实现

基于Pod管理策略(Pod Management Policy)

定义创建、删除及扩缩容等管理操作期间,施加在Pod副本上的操作方式

  • OrderedReady 参数
    • 例如mysql 主从复制的创建 需要先上主库 然后再上从库
    • 创建或扩容时,顺次完成各Pod副本的创建
      • 要求只有前一个Pod转为Ready状态后,才能进行后一个Pod副本的创建
    • 删除或缩容时,逆序、依 次完成相关Pod副本的终止
  • Parallel 参数
    • 各Pod副本的创建或删除操作不存在顺序方面的要求,可同时进行

各Pod副本存储的状态数据并不相同,需要专用且稳定的Volume 确保数据是独占的

  • 基于podTemplate定义Pod模板
  • 在podTemplate上 使用volumeTemplate为各Pod副本动态置备PersistentVolume

在动态的环境中 按需临时创建pvc

需要volumeTemplate 定义pv和pvc

Pod副本的专用名称标识

每个StatefulSet对象强依赖于一个专用的Headless Service对象

StatefulSet中的各Pod副本分别拥有唯一的名称标识

  • 前缀格式为“(statefulsetname)(statefulset_name)-(ordinal)”
  • 后缀格式为“(servicename).(service_name).(namespace).cluster.local”

各Pod的名称标识可由ClustrDNS直接解析为Pod IP

volumeTemplate

  • 在创建Pod副本时绑定至专有的PVC
  • PVC的名称遵循特定的格式,从而能够与StatefulSet控制器对象的Pod副本建立关联关系
  • 支持从静态置备 或 动态置备的PV(建议的方式)中完成绑定
  • 删除Pod(例如缩容),并不会一并删除相关的PVC

StatefulSet存在的问题

  • 各有状态、分布式应用在启动、扩容、缩容等运维操作上的步骤存在差异,甚至完全不同,因而StatefulSet只能提供一个基础的编排框架
  • 有状态应用所需要的管理操作,需要由用户自行编写代码完成

StatefulSet 资源规范及示例

image.png

StatefulSet yaml示例

创建 headless service

apiVersion: v1
kind: Service
metadata:
  name: demodb
  namespace: default
  labels:
    app: demodb
spec:
  clusterIP: None
  ports:
  - port: 9907
  selector:
    app: demodb

创建StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: demodb
  namespace: default
spec:
  selector:
    matchLabels:
      app: demodb
  serviceName: "demodb"
  replicas: 2
  template:
    metadata:
      labels:
        app: demodb
    spec:
      containers:
      - name: demodb-shard
        image: ikubernetes/demodb:v0.1
        ports:
        - containerPort: 9907
          name: db
        env:
        - name: DEMODB_DATADIR
          value: "/demodb/data"
        livenessProbe:
          initialDelaySeconds: 2
          periodSeconds: 10
          httpGet:
            path: /status
            port: db
        readinessProbe:
          initialDelaySeconds: 15
          periodSeconds: 30
          httpGet:
            path: /status?level=full
            port: db 
        volumeMounts:
        - name: data
          mountPath: /demodb/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs-csi"
      resources:
        requests:
          storage: 2Gi

StatefulSet 更新策略

  • rollingUpdate:滚动更新,自动触发
  • onDelete:删除时更新,手动触发

配置策略参数

maxUnavailable

  • 定义单批次允许更新的最大副本数量

partition

  • 用于定义更新分区的编号
  • 其序号大于等于该编号的Pod都将被更新,小于该分区号的都不予更新;
  • 默认编号为0,即更新所有副本;

Operator 简介(增强的StatefulSet)

operatorhub.io/

Operator 是增强型的控制器(Controller),它扩展了Kubernetes API的功能,并基于该扩展管理复杂应用程序

  • Operator 是 Kubernetes 的扩展软件,它利用定制的资源类型来增强自动化管理应用及其组件的能力,从而扩展了集群的行为模式
  • 使用自定义资源(例如CRD)来管理应用程序及其组件
  • 将应用程序视为单个对象,并提供面向该应用程序的自动化管控操作,例如部署、配置、升级、备份、故障转移和灾难恢复等