StatefulSet为每个有状态实例提供稳定的专属存储
StatefulSet在创建pod时,也需要创建持久卷声明,StatefulSet可以拥有一个或多个卷声明模版,这些持久卷声明会在创建pod前创建出来,绑定到一个pod实例上
持久卷的创建和删除
扩容StatefulSet增加一个副本数时,会创建两个或更多的api对象(一个pod和与之关联的一个或多个持久卷声明)。但缩容时,只会删除一个pod,而留下之前创建的声明。因为有状态的pod是用来运行有状态应用是,所以其在数据卷上存储的数据非常重要。在StatefulSet缩容时删除这个声明将是灾难性的。
因为缩容StatefulSet时会保留持久卷声明,所以在随后的扩容操作中,新的pod实例会使用绑定在持久卷上的相同声明和其上的数据
StatefulSet的保障
StatefulSet的行为与Replicaset或ReplicationController是不一样的,StatefulSet不仅拥有稳定的标记和独立的存储,还有其他一些保障,如kubernetes必须保证两个拥有相同标记和绑定相同持久卷声明的有状态的pod实例不会同时运行。一个StatefulSet必须保证有状态的pod实例的at-most-one语义。也就是说一个StatefulSet必须在准确确认一个pod不再运作后,才能去创建它的替换pod。
使用StatefulSet
1)创建应用和容器镜像
2)通过StatefulSet部署应用
为了部署应用,需要创建两个(或三个)不同类型对象:
- 存储数据文件的持久卷
- StatefulSet必须的一个控制Service
- StatefulSet本身
创建三个持久化存储卷yaml文件:persistent-volumes-gcepd.yaml
kind:List
apiVersion:v1
items:
-apiVersion:v1
kind:PersistentVolume
metadata:
name:pv-a
spec:
capacity:
storage:1Mi
accessModes:
-ReadWriteOnce
persistentVolumeReclaimPolicyRecycle
gcePersistentDisk:
pdName:pv-4
fsType:nfs4
-apiVersion:v1
kind:PersistentVolume
metadata:
name:pv-b
......
上一节通过一个yaml文件中添加三个横杠(- - -)来区分定义多个资源,这节可以通过list对象,把各个资源作为list对象的各个项目。
创建service yaml文件:kubia-service-headless.yaml
apiVersion:v1
kind:Service
metadata:
name:kubia
spec:
clusterIP:none
selector:
app:kubia
ports:
-name:http
port:80
创建StatefulSet详单yaml文件kubia-StatefulSet.yaml
apiVersion:apps/v1beta1
kind:StatefulSet
metadata:
name:kubia
spec:
serviceName:kubia
replicas:2
template:
metadata:
labels:
app:kubia
spec:
containers:
-name:kubia
image:luksa/kubia-pet
ports:
-name:http
containerPort:8080
volumeMounts:
-name:data
mountPath:/var/data
volumeClainTemplates:
-metadata:
name:data
spec:
resources:
requests:
storage:1Mi
accessModes:
-ReadWriteOnce
创建StatefulSet,命令行:
$kubectl create -f kubia-statefulset.yaml
备注:使用StatefulSet配置去创建pod,每次仅仅创建单个pod,第二个posld会在第一个pod运行并处于就绪状态后创建,这个与ReplicaSet和ReplicationController不同
检查生成的有状态的pod
$kubectl get po kubia-0 -o yaml
检查生成的持久卷声明
$kubectl get pvc
删除一个有状态的pod来检查重新调度的pod是否关联了相同的存储
$kubectl delete po kubia-0
$kubectl get po
扩缩容StatefulSet
缩容一个StatefulSet然后在完成后再扩容它,与删除一个pod后让StatefulSet立马重新创建他的表现没有区别。需要注意:缩容一个StatefulSet只会删除对应的pod,留下卸载后的持久卷声明。
缩容/扩容都是逐步进行的,与StatefulSet最初被创建时会创建各自pod一样。当缩容超过一个实例的时候,会首先删除拥有最高索引值的pod。只有当这个pod被完全终止后,才会开始删除拥有次高索引值的pod