配置一个简单的StatefulSet
RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。
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域名,这个域名的格式为:
$(podname).(headless server name)
FQDN:$(podname).(server name).namespace.svc.cluster.local
StatefulSet中每个Pod的DNS格式为statefulSetname-{0..N-1}.serviceName.namespace.svc.cluster.local,其中(用的时候只写到服务名就能通了)
1. serviceName为headless Service的名字
2. 0..N-1 为Pod所在的序号,从0开始到N-1
3. statefulSetName 为StatefulSet的名字
4. namespace为服务所在的namespace,Headless Servie和statefulSet必须在相同的namespace
5. .cluster.local 为ClusterDomain
特点:
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。删除、减少副本,不会删除相关的卷。
一个简单的nginx服务 web.yaml为例
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.2 ports: - containerPort: 80 name: web
#将上面配置文件保存为web.yaml 然后在另外起一个pod做客户端访问用,(pod命名方式上面有介绍) kubectl apply -f web.yaml kubectl get pod NAME READY STATUS RESTARTS AGE my-pod 1/1 Running 0 5m4s web-0 1/1 Running 0 19m web-1 1/1 Running 0 19m web-2 1/1 Running 0 16m kubectl exec -it my-pod -- bash curl web-0.nginx #会发现即使没有配置ip地址也能将这个解析为podip
StatefulSet扩缩容
创建:只有在上一个pod启动完成后才会开始启动下一个pod,如果上一个没有启动成功,将不会启动下一个pod
删除:相反从下往上删,在删除过程中,正在删除上面的所有pod必须是running状态,如果不是running将会暂停,直到上面的pod全部为running才会开始删
kubectl scale --replicas=2 sts web #设置StatefulSet副本数,命令
StatefulSet更新策略
滚动更新:
updateStrategy: rollingUpdate: partition: 0 type: RollingUpdate
StatefulSet更新策略和删除差不多,从下往上更新,如果更新途中上面的pod挂了,那么就会等到上面的pod running了在继续更新
OnDelete:
在设置成OnDelete时,只有在删除时候才会去更新镜像
updateStrategy: type: OnDelete #修改完毕后可以删除一个镜像然后让他自动创建,创建之后才会更新
StatefulSet灰度更新
partition: 0 #在上上面有一个这个字段,那么这个字段是什么意思呢? #就是小于这个值的pod,不更新(不包括等于)
思路:
我们在更新的时候,通过控制partition这个字段,一个一个的更新,看看结果如何。如果没问题,在继续更新下一个
StatefulSet级联更新和级联删除
级联更新和级联删除
就是删除stat时 同时删除Pod,默认的是级联删除
kubectl delete sts web
非级联删除
删除sts时 不删除Pod
kubectl delete sts web --cascade=false #非级联删除就是删除时候多加了一个选项 #删除statefulSet后,他所构建的pod就变成了孤儿,此时在删除pod就没有进程去重新构建他了