前言:
kubernetes有很多的控制器,比如 replicasets(简称rs),replicationcontrollers(简称rc),Deployment(简称deploy),DaemonSets(简称ds),StateFulSets(简称sts),那么,rs,rc是基本的pod控制器,这个就不说了,底层控制器,和deploy深度绑定。deploy和ds相对其它的控制器来说就非常常用了,基本的部署工作都是由这两个控制器完成,而sts由于它的自身特点导致它的使用范围不是特别的宽,但也是一个极为重要的控制器,需要我们能够熟练使用此控制器。
StateFulSets的基本概念:
StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:
FQDN:$(podname).(headless server name).namespace.svc.cluster.local
StateFulSets的构成方式:
pod部署清单,部署方式指定为StateFulSets;
Headless Service:用来定义Pod网络标识( DNS domain);(这个无头service的作用是可以体现StateFulSet控制器的稳定的网络特性,不是非必须的,可用可不用)
volumeClaimTemplates :存储卷申请模板,创建PVC,指定pvc名称大小,将自动创建pvc,且pvc必须由存储类供应(这个是体现StateFulSet控制器的稳定的存储特性,不是非必须的,可用可不用)
StateFulSets的特点:
Pod一致性:包含次序(启动、停止次序)、网络一致性。此一致性与Pod相关,与被调度到哪个node节点无关;
稳定的次序:对于N个副本的StatefulSet,每个Pod都在[0,N)的范围内分配一个数字序号,且是唯一的;
稳定的网络:Pod的hostname模式为( s t a t e f u l s e t 名 称 ) − (statefulset名称)-(statefulset名称)−(序号);
稳定的存储:通过VolumeClaimTemplate为每个Pod创建一个PV。删除、减少副本,不会删除相关的卷。
OK,以上是StateFulSets的基本介绍,下面就由两个部署实例来说明如何使用StateFulSets控制器并说明它的具体特点。
在正式的使用StateFulSets方式部署之前,建议先部署一个nfs-client-provisioner插件,使得集群内部能够动态的分配pv,nfs-client-provisioner插件部署见我的博客:
kubernetes学习之持久化存储StorageClass(4)_晚风_END的博客-CSDN博客
一,StateFulSets方式部署nginx
首先,确认我的nfs插件已经安装好了,也就是动态存储插件可用了:
StorageClass的名称是managed-nfs-storage
[root@k8s-master nfs]# k get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate true 6h9m
部署使用StateFulSet控制器的nginx的清单文件:
cat << EOF > nginx-sts.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: web namespace: web spec: selector: matchLabels: app: nginx #必须匹配 .spec.template.metadata.labels serviceName: "nginx" #声明它属于哪个Headless Service. replicas: 3 #副本数 template: metadata: labels: app: nginx # 必须配置 .spec.selector.matchLabels spec: terminationGracePeriodSeconds: 10 containers: - name: nginx image: nginx:1.20 ports: - containerPort: 80 name: web volumeMounts: - name: nginx-pvc mountPath: /usr/share/nginx/html volumeClaimTemplates: #可看作pvc的模板 - metadata: name: nginx-pvc spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "managed-nfs-storage" #存储类名,改为集群中已存在的 resources: requests: storage: 1Gi EOF
无头service:
cat << EOF > nginx-svc.yaml apiVersion: v1 kind: Service metadata: name: nginx namespace: web labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx EOF
查看pod的情况(注意,这些pod的名称是web+递增的数字组成的,如果扩容名称按顺序增加,那么一个稳定的pod名称的意义在于集群内的DNS将会有一个稳定的解析,pod无论怎么改变):
[root@k8s-master nfs-sc]# k get po -n web -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 6s 10.244.0.7 k8s-master <none> <none> web-1 1/1 Running 0 5s 10.244.2.9 k8s-node2 <none> <none> web-2 1/1 Running 0 3s 10.244.1.7 k8s-node1 <none> <none>
查看pv和pvc的情况:
[root@k8s-master nfs-sc]# k get pv,pvc -n web NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-a7b73ac0-d881-4c96-9fdb-e8d71f60d848 1Gi RWO Delete Bound web/nginx-pvc-web-1 managed-nfs-storage 40m persistentvolume/pvc-dabd8050-77f6-4655-8434-dac2f9a077eb 1Gi RWO Delete Bound web/nginx-pvc-web-2 managed-nfs-storage 40m persistentvolume/pvc-eb159490-353c-4aea-9412-10056a29911d 1Gi RWO Delete Bound web/nginx-pvc-web-0 managed-nfs-storage 40m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/nginx-pvc-web-0 Bound pvc-eb159490-353c-4aea-9412-10056a29911d 1Gi RWO managed-nfs-storage 40m persistentvolumeclaim/nginx-pvc-web-1 Bound pvc-a7b73ac0-d881-4c96-9fdb-e8d71f60d848 1Gi RWO managed-nfs-storage 40m persistentvolumeclaim/nginx-pvc-web-2 Bound pvc-dabd8050-77f6-4655-8434-dac2f9a077eb 1Gi RWO managed-nfs-storage 40m
查看service的情况:
[root@k8s-master nfs-sc]# k get svc -n web NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP None <none> 80/TCP 42m
此时,进入nfs的存储目录可以看到有三个文件夹,以pod名称开始:
[root@k8s-master nfs-sc]# ls web-nginx-pvc-web-* web-nginx-pvc-web-0-pvc-eb159490-353c-4aea-9412-10056a29911d: web-nginx-pvc-web-1-pvc-a7b73ac0-d881-4c96-9fdb-e8d71f60d848: web-nginx-pvc-web-2-pvc-dabd8050-77f6-4655-8434-dac2f9a077eb
在每个目录下建立nginx的首页测试文件:
[root@k8s-master nfs-sc]# echo "wo shi web-0" >web-nginx-pvc-web-0-pvc-eb159490-353c-4aea-9412-10056a29911d/index.html [root@k8s-master nfs-sc]# echo "wo shi web-1" >web-nginx-pvc-web-1-pvc-a7b73ac0-d881-4c96-9fdb-e8d71f60d848/index.html [root@k8s-master nfs-sc]# echo "wo shi web-2" >web-nginx-pvc-web-2-pvc-dabd8050-77f6-4655-8434-dac2f9a077eb/index.html
查看pod的IP:
[root@k8s-master nfs-sc]# k get po -n web -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 34m 10.244.1.6 k8s-node1 <none> <none> web-1 1/1 Running 0 34m 10.244.2.8 k8s-node2 <none> <none> web-2 1/1 Running 0 34m 10.244.0.6 k8s-master <none> <none>