资源调度 —— 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的存储资源
posted @ 2023-10-13 14:42  yifanSJ  阅读(38)  评论(0编辑  收藏  举报