15、k8s控制器Statefulset

1、Statefulset控制器

StatefulSet是k8s中的一种控制器(Controller),用于管理有状态应用程序的部署。与Deployment控制器不同,StatefulSet为每个Pod实例分配了一个唯一的标识符,并确保这些标识符在Pod重新创建时保持不变。这为有状态应用程序提供了一些关键的功能和保证,例如稳定的网络标识符、有序的部署和扩展以及持久化存储。

1.1 唯一标识符

每个StatefulSet管理的Pod实例都被分配了一个唯一的标识符,通常是一个整数索引。这个标识符可以用于在网络中唯一地标识每个Pod实例。

1.2 稳定的网络标识符

StatefulSet中的每个Pod实例都有一个稳定的网络标识符,通常是一个DNS名称。这使得其他应用程序可以通过名称轻松地访问特定的Pod实例,而不需要关注其具体的IP地址变化。

1.3 有序的部署和扩展

StatefulSet控制器确保Pod实例按照定义的顺序逐个启动和关闭。这对于依赖先前实例状态的应用程序非常重要。此外,扩展StatefulSet时,新的Pod实例也会按照指定的顺序逐个创建。

1.4 持久化存储

StatefulSet允许每个Pod实例关联一个持久化卷(Persistent Volume),这使得有状态应用程序可以在Pod重新创建时保留其数据。这为应用程序提供了持久化存储的能力,使得数据不会丢失或重置。

1.5 StatefulSet VS Deployment

对比维度 Deployment StatefulSet
适用场景 无状态应用 有状态应用
Pod 身份 无稳定身份,副本可互换 每个 Pod 有稳定唯一身份,按序号 ordinal 标识
Pod 名称 <deployment>-<rs-hash>-<random> <statefulset>-0、<statefulset>-1、...
网络标识 无稳定 per-Pod DNS,通常通过 Service 负载均衡 通常配合 Headless Service,提供稳定 DNS,如 <pod>.<svc>.<ns>.svc.cluster.local
Service 普通 Service 即可 通常需要 Headless Service;也可额外用普通 Service 做统一入口
存储 无 volumeClaimTemplates,多副本通常共享 PVC 或不用持久化 通过 volumeClaimTemplates 为每个 Pod 创建独立 PVC,PVC 与 ordinal 绑定
PVC 生命周期 取决于手动创建和保留策略 删除 StatefulSet 默认保留 PVC,需手动清理
启动顺序 无保证,可并行启动 默认 OrderedReady:0 → N-1,等待前一个 Ready
停止/缩容顺序 无保证,可并行删除 默认 N-1 → 0,按逆序删除
扩缩容 任意并行扩缩 默认按序扩缩;可配置 podManagementPolicy: Parallel
更新策略 RollingUpdate(支持 maxSurge/maxUnavailable)或 Recreate RollingUpdate(支持 partition,默认逆序)或 OnDelete
更新顺序 可不按序,多副本可能同时更新 默认逆序,通常逐个更新并等待 Ready
版本与回滚 通过 ReplicaSet 管理版本,回滚方便 通过 ControllerRevision 管理版本,支持历史/回滚,但通常按序执行
服务发现 Service 统一入口,Pod 一般不单独寻址 每个 Pod 可通过稳定 DNS 单独寻址,也可用普通 Service 统一入口
管理对象 Deployment → ReplicaSet → Pod StatefulSet → Pod
删除 Pod 后 重建随机名称的新 Pod 重建同名、同 ordinal 的 Pod
典型场景 Web 前端、API、无状态微服务 MySQL、PostgreSQL、Redis Cluster、Kafka、ZooKeeper、etcd 等

一句话总结:无状态、副本可互换选 Deployment;有状态、需要稳定身份/独立存储/顺序启动选 StatefulSet。

2、部署StatefulSet

bash 复制代码
# 创建statefulset.yaml
vi statefulset.yaml
# 填入以下内容
apiVersion: v1                                      # API 版本,Service 使用 v1
kind: Service                                       # 资源类型:Service
metadata:                                           # 元数据
  name: nginx                                       # Service 名称
  labels:                                           # Service 标签
    app: nginx                                      # 标签 app=nginx
spec:                                               # Service 规格
  ports:                                            # Service 端口定义
    - port: 80                                      # 暴露端口 80
      name: web                                     # 端口名称 web
  clusterIP: None                                   # 无头 Service,不分配 ClusterIP
  selector:                                         # Pod 选择器
    app: nginx                                      # 选择 app=nginx 的 Pod
---                                                 # YAML 文档分隔符
apiVersion: apps/v1                                 # StatefulSet 的 API 版本
kind: StatefulSet                                   # 资源类型:StatefulSet
metadata:                                           # 元数据
  name: web                                         # StatefulSet 名称
spec:                                               # StatefulSet 规格
  selector:                                         # Pod 选择器
    matchLabels:                                    # 匹配标签
      app: nginx                                    # 匹配 app=nginx
  serviceName: "nginx"                              # 关联的 Headless Service 名称
  replicas: 2                                       # Pod 副本数
  template:                                         # Pod 模板
    metadata:                                       # Pod 元数据
      labels:                                       # Pod 标签
        app: nginx                                  # Pod 标签 app=nginx
    spec:                                           # Pod 规格
      containers:                                   # 容器列表
        - name: nginx                               # 容器名称
          image: nginx                              # 容器镜像
          imagePullPolicy: IfNotPresent             # 镜像拉取策略
          ports:                                    # 容器端口定义
            - containerPort: 80                     # 容器监听端口 80
              name: web                             # 容器端口名称 web
bash 复制代码
# 启动statefulset
kubectl apply -f statefulset.yaml
# 查看statefulset
kubectl get statefulset
# 查看pod
kubectl get pod
bash 复制代码
#使用kubectlrun运行一个提供nslookup命令的容器的,通过对pod主机名执行nslookup,可以检查它们在集群内部的DNS地址

kubectl run busybox --image docker.io/library/busybox:latest --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh

# 进入容器后执行
nslookup web-0.nginx.default.svc.cluster.local


nslookup nginx.default.svc.cluster.local

3、Statefulset管理pod:扩容、缩容、更新

如果我们觉得两个副本太少了,想要增加,只需要修改配置文件statefulset.yaml里的replicas的值即可,原来replicas: 2,现在变成replicaset: 3,如果要缩容也是修改这个值即可,修改之后,执行如下命令更新:

bash 复制代码
kubectl apply -f statefulset.yaml

如果要实现对pod更新则修改statefulset.yaml

相关推荐
Eminem891 小时前
17、k8s配置管理中心configmap
k8s
Eminem893 小时前
16、k8s控制器Daemnonset
k8s
深蓝电商API18 小时前
Docker+K8s部署爬虫:从单机到集群的完整路线
爬虫·docker·k8s
运维开发那些事20 小时前
推理集群稳定性最佳实践
k8s·gpu算力
meijinmeng3 天前
将 Kubernetes 部署扩展到多个Region区域:GitOps 参考架构
k8s·cicd
张洛闻Eren3 天前
Ansible【第二课】:实施 Ansible Playbook
linux·运维·服务器·云原生·kubernetes·k8s·ansible
紫神9 天前
DDS 通信技术说明
网络·云原生·容器·k8s·dds·弱网
Eminem8914 天前
14、k8s持久化存储
k8s
上火的金鱼妹16 天前
higress网关访问+ 模型访问的安全策略管控
k8s·higress·ai网关