资源调度 —— StatefulSet(针对部署的有状态应用)
三、StatefulSet(针对部署的有状态应用)
有状态很依赖本地文件、网络资源等。不像无状态应用想扩容就扩容。
一)功能
1、创建
kubectl create -f web.yaml
# 查看 service 和 statefulset => sts
kubectl get service nginx
kubectl get statefulset web
# 查看 PVC 信息
kubectl get pvc
# 查看创建的 pod,这些 pod 是有序的
kubectl get pods -l app=nginx
# 查看这些 pod 的 dns
# 运行一个 pod,基础镜像为 busybox 工具包,利用里面的 nslookup 可以看到 dns 信息
kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
nslookup web-0.nginx
2、扩容缩容
# 扩容
kubectl scale statefulset web --replicas=5
# 缩容
kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
3、镜像更新
# 镜像更新(目前还不支持直接更新 image,需要 patch 来间接实现)
kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'
a、RollingUpdate
StatefulSet 也可以采用滚动更新策略,同样是修改 pod template 属性后会触发更新,但是由于 pod 是有序的,在 StatefulSet 中更新时是基于 pod 的顺序倒序更新的,可以实现灰度发布
灰度发布(金丝雀发布)
目标:将项目上线后产生问题的影响,尽量降到最低
利用滚动更新中的 partition 属性,可以实现简易的灰度发布的效果
例如我们有 5 个 pod,如果当前 partition 设置为 3,那么此时滚动更新时,只会更新那些 序号 >= 3 的 pod
利用该机制,我们可以通过控制 partition 的值,来决定只更新其中一部分 pod,确认没有问题后再主键增大更新的 pod 数量,最终实现全部 pod 更新
spec:
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
b、OnDelete
只有在 pod 被删除时会进行更新操作,也就是删除后再新生成的副本会使用新的配置。
5、删除
# 删除 StatefulSet 和 Headless Service
# 级联删除:删除 statefulset 时会同时删除 pods
kubectl delete statefulset web
# 非级联删除:删除 statefulset 时不会删除 pods,删除 sts 后,pods 就没人管了,此时再删除 pod 不会重建的
kubectl delete sts web --cascade=false
# 删除 service
kubectl delete service nginx
6、删除 pvc
# StatefulSet删除后PVC还会保留着,数据不再使用的话也需要删除
$ kubectl delete pvc www-web-0 www-web-1
7、其它
# busybox 只是一个工具
kubectl run -it --image busybox dns-test --restart=Never --rm /bin/sh
# 通过 域名 完整的 映射路径
nslookup web-0.nginx
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.169.171 web-0.nginx.default.svc.cluster.local
二)配置文件
---
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 # StatefulSet 类型的资源
metadata:
name: web # StatefulSet 对象的名称
spec:
serviceName: "nginx" # 使用哪个 service 来管理 dns
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports: # 容器内部要暴露的端口
- containerPort: 80 # 具体暴露的端口号
name: web # 该端口配置的名字
volumeMounts: # 加载数据卷
- name: www # 指定加载哪个数据卷
mountPath: /usr/share/nginx/html # 加载到容器中的哪个目录
volumeClaimTemplates: # 数据卷模板
- metadata: # 数据卷描述
name: www # 数据卷的名称
annotations: # 数据卷的注解
volume.alpha.kubernetes.io/storage-class: anything
spec: # 数据卷的规约
accessModes: [ "ReadWriteOnce" ] # 访问模式
resources:
requests:
storage: 1Gi # 需要1个G的存储资源