文章目录
- 一、StatefulSet理论知识
 
- 1、StatefulSet Pod控制器特性
 - 2、什么是有状态服务和无状态服务?
 - 3、Deployment和StatefulSet区别
 
- 二、案例:StatefulSet资源实战演示
 
- 1、创建WEB站点并验证StatefulSet特点
 - 2、StatefulSet滚动更新
 
- 三、总结
 
 
一、StatefulSet理论知识
官方中文参考文档
1、StatefulSet Pod控制器特性
StatefulSet(简写sts)也是K8S集群中的一种Pod资源管理器,与deployment Pod控制器不同的是,StatefulSet用于管理无状态程序,特性如下:
- 稳定的网络标识符:管理的Pod都拥有一个稳定的网络标识符。可以通过网络标识符进行访问。
 - 有序部署和扩展:StatefulSet会按照指定的顺序逐个部署Pod,每个Pod都有一个唯一的序号,这个序号在整个生命周期中都不会改变。在扩展时,也会按照指定的顺序逐个增加Pod。
 - 稳定的存储:每个Pod都用一个独立的持久卷存储,比如NFS。
 - 有状态服务:StatefulSet适用于有状态的服务,例如数据库、缓存等,这些服务需要稳定的网络标识符和持久化存储。
 
总之,StatefulSet提供了一种可靠的、有序的、有状态的服务部署和扩展方式,适用于需要稳定网络标识符和持久化存储的有状态服务。
2、什么是有状态服务和无状态服务?
无状态服务则是指不需要持久化存储和状态的服务,例如Web服务器、API服务器等。这些服务可以在任何节点上运行,因为它们不需要在不同节点之间共享数据,也不需要在节点故障时进行快速恢复。无状态服务可以通过水平扩展来提高性能和可用性。
有状态服务是指需要持久化存储并且需要保持状态的服务,例如数据库、缓存等。这些服务需要在不同的节点之间保持数据同步,并且需要在节点故障时能够快速恢复。
3、Deployment和StatefulSet区别
Deployment和StatefulSet是Kubernetes中常用的两种控制器,它们的主要区别如下:
- Deployment是用于管理无状态应用的控制器,而StatefulSet则是用于管理有状态应用的控制器。
 - Deployment可以创建多个Pod副本,这些Pod副本之间没有任何顺序关系,可以随意调度和替换。而StatefulSet创建的Pod副本有固定的顺序,每个Pod副本都有唯一的标识符,可以保证有状态应用的数据持久性和稳定性。
 - Deployment可以进行滚动更新,即在更新过程中保持应用的可用性。而StatefulSet的更新过程需要手动控制,需要先删除旧的Pod副本,再创建新的Pod副本,因此更新过程中会有一定的停机时间。
 - Deployment可以使用RollingUpdate策略进行滚动更新,而StatefulSet则可以使用OnDelete和RollingUpdate两种策略进行更新。
 
总之,Deployment适用于管理无状态应用,而StatefulSet适用于管理有状态应用。如果应用需要保证数据的持久性和稳定性,建议使用StatefulSet。
二、案例:StatefulSet资源实战演示
1、创建WEB站点并验证StatefulSet特点
第一步:创建名为 sts-web-svc 的SVC ,用于创建statefulset资源时需要关联service,YAML如下:
cat sts-web-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: sts-web-svc
spec:
  selector:
    app: web-nginx
  ports:
  - port: 80
    targetPort: 80
  clusterIP: None     # 设置无IP地址创建 svc 资源:
kubectl apply -f sts-web-svc.yaml查看创建的 svc 资源,如下图可以看到创建的svc并没有分配IP地址:
kubectl get svc sts-web-svc![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mh2GSqBh-1687429873545)(D:\MD归档文档\IMG\image-20230622124156022.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_statefulset](https://file.cfanz.cn/uploads/png/2023/06/24/10/7849NYCR80.png)
第二步:创建statefulset资源
cat sts-web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sts-web
  namespace: default
spec:
  serviceName: sts-web-svc  # 关联SVC资源
  replicas: 2               # 副本数
  selector:
    matchLabels:            # 关联具有app=web-nginx标签的Pod
      app: web-nginx
  volumeClaimTemplates:        # 卷申请模板 
  - metadata:
      name: www                # 卷申请模板名称
    spec:
      accessModes: ["ReadWriteOnce"] # 访问模式
      storageClassName: nfs          # 指定供应商,前提是需要存在此供应商
      resources:
        requests:
          storage: 1Gi               # 存储大小1G
  template:
    metadata:
      labels:
        app: web-nginx
    spec:
      containers:
      - name: web-nginx
        image: nginx:1.18.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www             # 指定卷申请模板名称
          mountPath: /usr/share/nginx/html
        startupProbe:           # 启动探测
          tcpSocket:
            port: 80执行 YAML :
kubectl apply -f sts-web.yaml第三步:特点测试
1、Pod都有一个唯一的序号:如下图Pod名字有序
kubectl get pods -l app=web-nginx -o wide![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEhdYVet-1687429873546)(D:\MD归档文档\IMG\image-20230622170004961.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_docker_02](https://file.cfanz.cn/uploads/png/2023/06/24/10/R7L4J3NKd7.png)
删除 sts-web-0,Pod后自动创建出来的Pod名称不会改变
kubectl delete pod sts-web-0![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZR18brWr-1687429873547)(D:\MD归档文档\IMG\image-20230622172250665.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_POD有状态管理器_03](https://file.cfanz.cn/uploads/png/2023/06/24/10/D3271CC35F.png)
2、Pod独立持久卷存储:查看PVC,自动生成两个PVC,相互隔离
kubectl get pvc -l app=web-nginx
ls /data/nfs_pro|grep default-www-sts-web-*![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lCl6BCXF-1687429873547)(D:\MD归档文档\IMG\image-20230622170316050.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_运维_04](https://file.cfanz.cn/uploads/png/2023/06/24/10/857RKVUE5f.png)
3、稳定的网络标识符:我们使用busybox运行Pod,nslookup进行解析
kubectl run busybox --image docker.io/library/busybox:1.28 --rm -it busybox -- sh![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JAVuvfgk-1687429873547)(D:\MD归档文档\IMG\image-20230622171854741.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_POD有状态管理器_05](https://file.cfanz.cn/uploads/png/2023/06/24/10/e7Q180Q553.png)
2、StatefulSet滚动更新
滚动更新使用 spec.updateStrategy 字段定义,目前statefulset支持两种更新策略如下:
- RollingUpdate:滚动更新
 - OnDelete:不会自动更新,手动删除Pod后进行更新
 
下面演示滚动更新:
第一步:创建并执行statefulset资源
cat web-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80
  clusterIP: None创建statefulset,使用nginx:1.18 镜像
cat web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  namespace: default
spec:
  serviceName: web
  replicas: 5   
  selector:
    matchLabels:           
      app: web
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 0 # 最多不可用Pod,0表示2个Pod可用 
      partition: 2      # 只更新序号大于等于partition值的Pod
  volumeClaimTemplates:       
  - metadata:
      name: web               
    spec:
      accessModes: ["ReadWriteOnce"] 
      storageClassName: nfs          
      resources:
        requests:
          storage: 1Gi               
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:1.18.0    # 使用1.18.0版本镜像
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: web           
          mountPath: /usr/share/nginx/html执行YAML文件
kubectl apply -f web-svc.yaml
kubectl apply -f web.yaml第二步:更新使用 nginx:latest 镜像
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwAHriLC-1687429873547)(D:\MD归档文档\IMG\image-20230622182033324.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_docker_06](https://file.cfanz.cn/uploads/png/2023/06/24/10/697E22NeJG.png)
重新YAML 一下:
kubectl apply -f web.yaml验证:由于我们partition: 2 所以Pod不会全部更新,只会更新序号大于2的Pod,包括2
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7VHSbpv-1687429873548)(D:\MD归档文档\IMG\image-20230622182419919.png)] 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解_kubernetes_07](https://file.cfanz.cn/uploads/png/2023/06/24/10/N7O3d2I297.png)
三、总结
- statefulset管理的Pod名称是有序的,删除指定Pod后自动创建的Pod名称不会改变。
 - statefulset创建时必须指定server名称,如果server没有IP地址,则会对server进行DNS解析,找到对应的Pod域名。
 - statefulset具有volumeclaimtemplate卷管理模板,创建出来的Pod都具有独立卷,相互没有影响。
 - statefulset创建出来的Pod,拥有独立域名,我们在指定访问Pod资源时,可以使用域名指定,IP会发生改变,但是域名不会(域名组成:Pod名称svc名称.svc名称空间.svc.cluster.local)
 
                










