一、StatefulSet 资源对象需求背景

现在基本上很多服务中的应用都是有状态的,比如MySQL数据库、Redis等,因为其中的数据在不断地变化,所以这些应用每个时刻都处于一个不同的状态。或者一个系统中存在多个不同的应用,这些应用存在一定的依赖关系。例如一个博客服务,该服务中包含了Redis缓存和MySQL数据库,我们在启动时需要先启动 MySQL数据库,Redis缓存,再去启动博客应用。Kubernetes 未这种存在状态的应用专门设计了一种资源对象,就是 StatefulSet

StatefulSet用来描述有状态的应用,它把真实世界应用的状态,基本上归纳为2种情况:

  • 拓扑状态:应用的多个实例之间的关系不是完全对等的,在启动时必须要按照指定的顺序才能启动。即便是pod
  • 存储状态:应用的多个实例(Pod)分别绑定了不同的存储数据,即便是实例(Pod)被删除重建,重建后的实例还是能读到原来的那一份数据。

StatefulSet资源对象的核心功能就是能够通过某种方式记录这些状态,在这些实例(Pod)被重新创建时,能够为新的实例(Pod)恢复这些状态。

StatefulSet资源对象,在执行控制循环的时候,使用的是在yaml文件中serviceName字段的key-value匹配到的Headless Service类型的Service资源对象,来确定要使用的Pod。

二、在 Yaml 文件中定义 StatefulSet 资源对象

StatefulSet 资源对象类似于 Deployment 资源对象,都是包含多个 Pod 副本,但是 Deployment 资源对象的 Pod 副本Pod 名称不固定,而且启动顺序也是随机的,但是 StatefulSet 资源对象Pod 副本的名称是固定的,且启动关系也是确定的。

2.1 StatefulSet 资源对象状态

  • StatefulSet 资源对象的Pod 副本名一般取值为节点名 + 序号(序号从0开始,最大值未Pod副本数目-1)。StatefulSet 资源对象的Pod副本的启动先后顺序依赖于这个Pod副本的序号。
  • StatefulSet 资源对象的访问需要额外的创建对应的 Service 资源对象,该Service 资源对象的名称要与 StatefulSet 资源对象中定义的 ServiceName 一致。

2.2 StatefulSet 资源对象定义

StatefulSet 资源对象的简称是sts。下面是 StatefulSet 资源对象与其对应的 Service 资源对象在 Yaml 文件中定义的内容示例:

apiVersion: apps/v1		# API 资源对象的版本
kind: StatefulSet		# API 资源对象的类型
metadata:
  name: test-sts		# # API 资源对象名

spec:
  serviceName: test-svc
  volumeClaimTemplates: 		# 在StatefulSet 资源对象中直接定义对应的PVC
  - metadata:
      name: test-redis-pvc		# 定义了该 PVC 的名称
    spec:
      storageClassName: nfs-client		# 明确PVC与PV绑定的StorageClass
      accessModes:		# 定义需要的存储设备的权限
        - ReadWriteMany
      resources:		# 定义需要的存储容量大小
        requests:
          storage: 60Mi

  replicas: 2		# 明确 statefulSet 资源对象对应的 pod 副本数
  selector:		# 定义statefulSet 标签选择器
    matchLabels:
      app: test-sts

  template:
    metadata:		# statefulSet资源对象下Pod 副本中的标签
      labels:
        app: test-sts
    spec:
      containers:
      - image: redis:5-alpine
        name: redis
        ports:
        - containerPort: 6379

        volumeMounts:
        - name: test-redis-pvc
          mountPath: /redis-data
---
apiVersion: v1
kind: Service
metadata:
  name: test-svc

spec:
  selector:
    app: test-sts
  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379

2.3 StatefulSet 资源对象

与我们之前讨论的 Deployment 资源对象相比,StatefulSet 资源对象的定义主要有2处独特之处,一个是serviceName,一个是volumeClaimTemplates。

  • serviceName: 该字段规定了使用 DNS 访问Pod时,Pod所属的子域。形式如:$(pod 名称).$(serviceName)
  • volumeClaimTemplates: StatefulSet 资源对象内置的专门用于定义 PVC 的字段;

因为 StatefulSet 资源对象是有状态的,不存在 Pod 漂移的情况,因此可以通过域名 \$(pod 名称).\$(serviceName) 被稳定的访问。

三、StatefulSet 资源对象的使用

利用上面的Yaml 文件,我们通过如下命令直接创建 StatefulSetService 资源对象:

kubectl apply -f test-svc-sts.yaml

通过如下命令可查看 statefulSet 资源对象和 service 资源对象的状态,同时使用hostname 命令查看短格式节点名与Pod名称的关系:

# 查看节点名短格式
hostname
# 查看StatefulSet资源对象状态
kubectl get sts
# 查看Service资源对象状态
kubectl get svc
# 查看资源对象test-sts详细信息
kubectl describe test-sts
# 查看资源对象test-svc详细信息
kubectl describe test-svc
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐