【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解

文章目录

    • 一、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-nginxports:- port: 80targetPort: 80clusterIP: 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)]

第二步:创建statefulset资源

cat sts-web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: sts-webnamespace: default
spec:serviceName: sts-web-svc  # 关联SVC资源replicas: 2               # 副本数selector:matchLabels:            # 关联具有app=web-nginx标签的Podapp: web-nginxvolumeClaimTemplates:        # 卷申请模板 - metadata:name: www                # 卷申请模板名称spec:accessModes: ["ReadWriteOnce"] # 访问模式storageClassName: nfs          # 指定供应商,前提是需要存在此供应商resources:requests:storage: 1Gi               # 存储大小1Gtemplate:metadata:labels:app: web-nginxspec:containers:- name: web-nginximage: nginx:1.18.0imagePullPolicy: IfNotPresentports:- containerPort: 80name: webvolumeMounts:- name: www             # 指定卷申请模板名称mountPath: /usr/share/nginx/htmlstartupProbe:           # 启动探测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)]

删除 sts-web-0,Pod后自动创建出来的Pod名称不会改变

kubectl delete pod sts-web-0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZR18brWr-1687429873547)(D:\MD归档文档\IMG\image-20230622172250665.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)]

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)]

2、StatefulSet滚动更新

滚动更新使用 spec.updateStrategy 字段定义,目前statefulset支持两种更新策略如下:

  • RollingUpdate:滚动更新
  • OnDelete:不会自动更新,手动删除Pod后进行更新

下面演示滚动更新:

第一步:创建并执行statefulset资源

cat web-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:name: web
spec:selector:app: webports:- port: 80targetPort: 80clusterIP: None

创建statefulset,使用nginx:1.18 镜像

cat web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: webnamespace: default
spec:serviceName: webreplicas: 5   selector:matchLabels:           app: webupdateStrategy:rollingUpdate:maxUnavailable: 0 # 最多不可用Pod,0表示2个Pod可用 partition: 2      # 只更新序号大于等于partition值的PodvolumeClaimTemplates:       - metadata:name: web               spec:accessModes: ["ReadWriteOnce"] storageClassName: nfs          resources:requests:storage: 1Gi               template:metadata:labels:app: webspec:containers:- name: webimage: nginx:1.18.0    # 使用1.18.0版本镜像imagePullPolicy: IfNotPresentports:- containerPort: 80name: webvolumeMounts:- 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)]

重新YAML 一下:

kubectl apply -f web.yaml

验证:由于我们partition: 2 所以Pod不会全部更新,只会更新序号大于2的Pod,包括2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7VHSbpv-1687429873548)(D:\MD归档文档\IMG\image-20230622182419919.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)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部