【K8S】Kubernetes 中有状态的资源对象——StatefulSet
现在基本上很多服务中的应用都是有状态的,比如MySQL数据库、Redis等,因为其中的数据在不断地变化,所以这些应用每个时刻都处于一个不同的状态。或者一个系统中存在多个不同的应用,这些应用存在一定的依赖关系。例如一个博客服务,该服务中包含了Redis缓存和MySQL数据库,我们在启动时需要先启动 MySQL数据库,Redis缓存,再去启动博客应用。Kubernetes 未这种存在状态的应用专门设计
Kubernetes 中有状态的资源对象——StatefulSet
一、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 文件,我们通过如下命令直接创建 StatefulSet
和 Service
资源对象:
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
更多推荐
所有评论(0)