自己建的网站可以用笔记本做服务器吗,wordpress主题 德国,做网站编辑需要学什么,宁国网站开发TOC
1 为什么需要StatefulSet
常规的应用通常使用Deployment#xff0c;如果需要在所有机器上部署则使用DaemonSet#xff0c;但是有这样一类应用#xff0c;它们在运行时需要存储一些数据#xff0c;并且当Pod在其它节点上重建时也希望这些数据能够在重建后的Pod上获取TOC
1 为什么需要StatefulSet
常规的应用通常使用Deployment如果需要在所有机器上部署则使用DaemonSet但是有这样一类应用它们在运行时需要存储一些数据并且当Pod在其它节点上重建时也希望这些数据能够在重建后的Pod上获取毕竟没有哪个运维希望Pod重建后数据却丢失了。
对于Deployment和DaemonSet来说它们创建的Pod是一模一样的如果将PV关联到Pod的PVC这两种资源都无法对多个Pod的PVC进行区分因此对于这种场景最基本的需求就是每个Pod可以设置不同的PVC同时Pod在重建时最好主机名等也一样因为多个存储之间需要进行数据同步所有的Pod都需要知道其他Pod的主机名如果Pod的名称变化了其他Pod的配置都需要调整。
因此对于这类应用至少有两个需求
每个Pod可以使用不同的PVC绑定到不同的PVPod重建后Pod名称和主机名不变
这就要使用到StatefulSet简称sts。
2 StatefulSet的Yaml的关键字段
与Deployment相比StatefulSet有几个比较特别的字段
sts.spec.podManagementPolicyPod被创建和删除的顺序可选的值有OrderedReady按照0N-1的顺序创建Pod按照N-1~0的顺序删除Pod、Parallel并行创建和删除Podsts.spec.serviceNameStatefulSet关联的服务名sts.spec.updateStrategy.rollingUpdate.partition分区滚动更新sts.spec.volumeClaimTemplatesPVC模板也就是说这里不是单个PVC而是一个模板会根据Pod的数量创建对应的PVC
这里借用一本书里面的例子的镜像luksa/kubia-pet它运行一个nodejs应用监听容器的8080端口当发送POST请求时会将数据写入本地的/var/data/kubia.txt当发送GET请求时会从本地的/var/data/kubia.txt获取数据。
下面是用docker run启动该镜像后的使用方式 可以发现在保存数据时会打印Pod的主机名而在读取数据时会打印读取数据的Pod的主机名以及写入的数据。
用以下的yaml创建StatefulSet以及对应的Service
apiVersion: v1
kind: Service
metadata:name: kubia-svc
spec:clusterIP: Noneselector:app: kubiaports:- name: httptargetPort: 8080port: 80---apiVersion: apps/v1
kind: StatefulSet
metadata:name: kubialabels:app: kubia
spec:selector:matchLabels:app: kubiaserviceName: kubia-svcreplicas: 3template:metadata:labels:app: kubiaspec:containers:- name: kubia-ctrimage: luksa/kubia-petports:- name: httpcontainerPort: 8080volumeMounts:- name: datamountPath: /var/datavolumeClaimTemplates:- metadata:name: dataspec:resources:requests:storage: 1MiaccessModes:- ReadWriteOnce可以发现
Pod名称跟Pod中的主机名相同都是StatefulSet资源名称和一个索引号这里给定的replicas是3因此索引号就是0~2创建了3个Pod的同时也创建了3个PVC和PVkubia-0这个Pod绑定的PVC是data-kubia-0开始的data就是PVC模板中的名称
然后再创建一个nginx的Pod就可以在nginx的Pod上访问服务 在原来服务的DNS前面再加一个Pod名称就可以直接解析到对应的Pod然后就可以直接访问对应的Pod而且访问者可以认为无论目标Pod是重启还是重建目标Pod都是同一个主机名和域名没有变化、存储也没有变化PVC在关联PV后只要PV不被删除就会一致关联由于Pod名称没有变化因此同一个PVC还是会关联到同一个Pod。如果需要这些Pod组成集群那么每个主机的名称是可以预期且不变的。
在Pod启动过程中也会发现3个Pod中一定是kubia-0最先启动kubia-2最后启动同时只有kubia-0正常运行了才会继续创建kubia-1而删除StatefulSet过程中一定是kubia-2最先删除kubia-0最后删除。
与Deployment类似StatefulSet也可以使用kubectl scale进行扩容和缩容与启动和删除过程类似当扩容时一定是从当前最大的序号的下一个序号的Pod开始创建例如现在就会从kubia-3开始创建当缩容时一定是从当前最大的序号的Pod开始删除例如现在就会从kubia-2开始删除。
3 扩缩容失败的处理
在扩容过程中如果Pod运行异常则可以直接进行重建或者调度到其他机器上重建。
在缩容过程中StatefulSet需要保证运行的Pod状态都是正常的。如果Pod运行异常则缩容过程会阻塞因为kubernetes无法判断Pod异常状态到底是瞬时状态还是永久性状态如果是永久性状态需要解决该问题才能继续推进缩容操作如果此时继续推进缩容操作那么运行的Pod数量可能跟实际期望的不同如果是瞬时状态 通常过一会儿就会恢复。总的来说就是只有当Pod运行正常时才进行扩缩容操作。
4 分区滚动更新
ds.spec.updateStrategy.rollingUpdate可以设置Pod的最大超过数量和最大不可用的数量但是在sts.spec.updateStrategy.rollingUpdate则用于设置分区滚动更新1.24版本也提供了最大不可用数的设置。
分区滚动更新就是分段更新将StatefulSet的所有Pod分成两部分在进行更新时一部分更新另一部分不更新因此设置分区就是设置一个索引位置也就是sts.spec.updateStrategy.rollingUpdate.partition当该值为n时索引值大于或者等于n的Pod才会被更新小于n的Pod不会被更新。而且当小于n的Pod重建时还是会用旧的配置进行重建。
分区滚动更新的主要使用场景就是实现金丝雀部署也就是新老版本需要同时运行运行过程中可以通过观察新版本的监控指标判断是否继续进行升级。
5 总结
对于需要持久化数据的应用或者需要多Pod构成集群的应用可以使用StatefulSet进行部署每个Pod的主机名和域名在Pod重建后保持不变也会绑定到同一个PV存储这就使得Pod在异常重建或者漂移后可以认为还是同一个Pod这就满足了“有状态服务”的需求。