k8s-存储-pv和pvc和StatefulSet

本文深入解析Kubernetes中的存储概念PV和PVC,以及StatefulSet的特性和使用场景。涵盖PV和PVC的绑定机制、访问类型、回收策略,StatefulSet的部署、扩展顺序及稳定持久化存储的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

k8s-存储-pv和pvc和StatefulSet

一 概念

1.1 pv

PersistentVolume (PV)

是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统

1.2 pvc

PersistentVolumeClaim (PVC)

是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或 只读多次模式挂载)

  • 作用:

PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用

1.3 pv和pvc绑定

master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦 PV 和 PVC 绑定后, PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟PV 绑定是一对一的映射

1.4 pv访问类型

PersistentVolume 可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式

ReadWriteOnce——该卷可以被单个节点以读/写模式挂载

ReadOnlyMany——该卷可以被多个节点以只读模式挂载

ReadWriteMany——该卷可以被多个节点以读/写模式挂载

在命令行中,访问模式缩写为:

RWO - ReadWriteOnce

ROX - ReadOnlyMany

RWX - ReadWriteMany

1.5 pvc回收策略

Retain(保留)——手动回收

Recycle(回收)——基本擦除( rm -rf /thevolume/* )

Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)

将被删除当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略

1.6 pvc的状态

Available(可用)——一块空闲资源还没有被任何声明绑定

Bound(已绑定)——卷已经被声明绑定

Released(已释放)——声明被删除,但是资源还未被集群重新声明

Failed(失败)——该卷的自动回收失败

1.7 创建pv和pvc

  • 安装nfs

注意 你的node节点也都需要安装nfs-utils,为了挂载

yum install -y nfs-common nfs-utils rpcbind
mkdir /nfs{1..3}
chmod 666 /nfs{1..3}
chown nfsnobody /nfs{1..3}

[root@k8s-master01 pv]# cat /etc/exports
/nfs1 *(rw,no_root_squash,no_all_squash,sync)
/nfs2 *(rw,no_root_squash,no_all_squash,sync)
/nfs3 *(rw,no_root_squash,no_all_squash,sync)

systemctl start rpcbind
systemctl start nfs
  • 创建pv

[root@k8s-master01 pv]# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv1 #pv名字
spec:
  capacity:
    storage: 10Gi
  accessModes: # 访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle #回收模式
  storageClassName: nfs #卷的名字
  nfs:
    path: /nfs1 #挂载宿主机目录
    server: 192.168.1.210 # nfsip
---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv2
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: hu
  nfs:
    path: /nfs2
    server: 192.168.1.210
---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv3
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs3
    server: 192.168.1.210

查看pv

  • 创建pvc

[root@k8s-master01 pv]# cat pod.yaml 
# 创建无头服务
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
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: wangyanglinux/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec: #必须满足下面两个,pod才会绑定到pv上面
      accessModes: [ "ReadWriteOnce" ] #读取模式
      storageClassName: "nfs" #绑定pv名字为nfs
      resources:
        requests:
          storage: 1Gi

然后查看绑定结果,发现只有一个pod绑定成功,因为另外两pc不满足条件

然后我们再次测试,把另外两个pv也改成跟nfspv1 相同的配置,你会发现三个pod都已经启动了

然后3个pv也都绑定了

然后在查看pvc

然后分别访问三个pod,在node节点上面,需要去宿主机的,nfs1,nfs2,nfs3,三个目录添加index.html文件

即使你删除一个pod,他的ip地址变了,然后你再次访问,数据发现还是不会丢失的

二 StatefulSet

2.1 statefulset特性

  • 匹配 Pod name ( 网络标识 ) 的模式为:$(statefulset名称)-$(序号),比如上面的示例:web-0,web-1,web-2

  • StatefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为: $(podname).(headless servername),也就意味着服务间是通过Pod域名来通信而非Pod IP,因为当Pod所在Node发生故障时, Pod 会被飘移到其它 Node 上,Pod IP 会发生变化,但是 Pod 域名不会有变化

验证:登录其中一个pod,然后ping ,容器名.svc名字

  • StatefulSet 使用 Headless 服务来控制 Pod 的域名,这个域名的 FQDN 为:$(servicename).$(namespace).svc.cluster.local,其中,“cluster.local” 指的是集群的域名根据 volumeClaimTemplates,为每个 Pod 创建一个 pvc,pvc 的命名则匹配模式:(volumeClaimTemplates.name)-(pod_name),比如上面的volumeMounts.name=www, Podname=web-[0-2],因此创建出来的 PVC 是 www-web-0、www-web-1、www-web-2

验证:10.244.2.9是k8s内部的dns,nginx是svc的名字,default是命名空间的名字

  • 删除 Pod 不会删除其 pvc,手动删除 pvc 将自动释放 pv

2.2 查看 statefulset

2.3 Statefulset的启停顺序

  • 有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。

  • 有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。

  • 有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。

2.4 StatefulSet使用场景

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现。

  • 稳定的网络标识符,即 Pod 重新调度后其 PodName 和 HostName 不变。

  • 有序部署,有序扩展,基于 init containers 来实现。

  • 有序收缩。

三 如何彻底删除pv

1 首先删除对应的pod和svc,然后删除pvc,

kubectl delete -f pod.yaml

kubectl delete pvc --all

如果还是删除不掉,需要直接编辑pv,删除掉红框里面的4行

kubectl edit pv nfspv3

然后你会发现你的pv就都释放掉资源了

pv,pvc,pod直接的关系

<think>好的,我现在需要回答用户关于KubernetesStatefulSet的作用的问题。首先,我应该回忆一下StatefulSet的基本概念,以及它与Deployment的区别。用户之前问过关于IngressService的问题,可能对基础资源有一定了解,现在需要深入StatefulSet。 首先,StatefulSet是用于管理有状态应用的控制器。与Deployment不同,StatefulSet为每个Pod提供稳定的标识符,比如有序的命名稳定的网络标识。这适用于需要持久化存储、稳定网络标识或有序部署扩展的应用,比如数据库、消息队列等。 接下来,我需要明确StatefulSet的几个关键特性: 1. **稳定的网络标识**:每个Pod有固定的主机名,格式为<statefulset-name>-<ordinal-index>,并且可以通过Headless Service来解析其他Pod的地址。 2. **有序部署扩展**:Pod按顺序创建删除,比如在扩容时,会从0到N-1依次创建;缩容时则相反,从N-1到0删除。这对于主从架构的应用很重要,确保主节点先运行。 3. **持久化存储**:使用VolumeClaimTemplate为每个Pod分配独立的持久卷(PV),即使Pod被重新调度,数据也能保留。每个Pod的存储卷不会与其他Pod共享,适合需要独立存储的场景。 4. **稳定的持久化标识符**:Pod名称存储卷在重新调度后保持不变,确保数据一致性服务发现。 然后,我需要考虑用户可能的实际应用场景。例如,运行MySQL主从复制、MongoDB副本集或Elasticsearch集群,这些都需要稳定的网络标识持久化存储。用户可能想知道为什么不能用Deployment来管理这些应用,这时候需要对比两者的区别,强调StatefulSet在稳定标识有序管理方面的优势。 还需要注意StatefulSet的典型配置,比如如何定义Service、VolumeClaimTemplate,以及扩缩容的行为。可能用户会问到Headless Service的作用,这时候需要解释它如何实现DNS解析,使得每个Pod有唯一的DNS记录,便于应用内部通信。 此外,应该提到StatefulSet的局限性,比如相比Deployment,管理起来更复杂,需要处理数据备份恢复,适用于特定场景而不是所有应用。 最后,组织回答结构,先总述作用,再分点详细说明每个特性,并结合实际例子配置示例,帮助用户更好地理解。确保语言简洁明了,避免过多技术术语,必要时提供YAML示例片段,但用户可能不需要完整的配置,所以点到为止即可。</think>以下是KubernetesStatefulSet核心作用的详细解析: --- ### **StatefulSet定位** 专为管理**有状态应用**设计的控制器,适用于需要**持久化存储、稳定网络标识、有序部署/扩展**的场景(如数据库、消息队列、分布式存储系统)。 --- ### **与Deployment的核心区别** | 特性 | Deployment | StatefulSet | |--------------------|---------------------|------------------------| | Pod标识 | 随机哈希(无固定名称) | 固定有序名称(如web-0,web-1) | | 存储绑定 | 共享存储或无状态 | 独立持久化存储PVC模板) | | 网络标识 | 随机IP | 稳定DNS子域名 | | 扩缩容顺序 | 并行操作 | 严格顺序(0→N扩容,N→0缩容) | | 适用场景 | 无状态服务(如Web应用) | 有状态服务(如MySQL集群) | --- ### **四大核心功能** #### **1. 稳定网络标识** - **Pod命名规则**:`<StatefulSet名称>-<序号>`(如`mysql-0`, `mysql-1`) - **DNS解析**:通过Headless Service(无ClusterIP的Service)提供DNS记录: ``` # Pod专属域名格式 <pod-name>.<svc-name>.<namespace>.svc.cluster.local # 示例 mysql-0.mysql-svc.default.svc.cluster.local ``` *实现应用内部通过固定域名互相访问* #### **2. 持久化存储绑定** - **VolumeClaimTemplate**:自动为每个Pod创建独立的PVC/PV ```yaml apiVersion: apps/v1 kind: StatefulSet spec: volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi ``` *每个Pod挂载独立存储(如mysql-0的数据卷与mysql-1完全隔离)* #### **3. 有序生命周期管理** - **扩容时**:严格按0→1→2顺序创建新Pod并等待前一个Pod进入Ready状态 - **缩容时**:按相反顺序(2→1→0)终止Pod - **滚动更新策略**:支持`OnDelete`或`Partitioned`更新,避免全量同时更新 #### **4. 状态持久性保证** - Pod重建后保持相同名称、网络标识存储绑定 - 存储卷生命周期与Pod解耦,删除StatefulSetPVC默认保留 --- ### **典型应用场景** 1. **数据库集群**(如MySQL主从复制、MongoDB副本集) ```yaml # MongoDB StatefulSet片段示例 kind: StatefulSet metadata: name: mongodb spec: serviceName: "mongodb-svc" # 关联Headless Service replicas: 3 template: spec: containers: - name: mongodb image: mongo:4.4 command: ["mongod", "--replSet", "rs0"] ``` 2. **分布式存储系统**(如Cassandra、Elasticsearch) *依赖稳定的成员身份识别数据分片存储* 3. **消息队列系统**(如Kafka、RabbitMQ集群) *需要持久化消息存储节点固定寻址* --- ### **配置要点** 1. **必须关联Headless Service** ```yaml apiVersion: v1 kind: Service metadata: name: mysql-svc spec: clusterIP: None # Headless Service标识 ports: - port: 3306 selector: app: mysql ``` 2. **存储类(StorageClass)预配** *确保集群已配置动态存储供应(如AWS EBS、GCP PD)* 3. **初始化脚本处理** *复杂集群(如MySQL主从)需通过Init Container配置节点关系* --- ### **操作示例** ```bash # 查看Pod有序状态 kubectl get pods -l app=mysql # 扩容操作(从3→5个节点) kubectl scale statefulset mysql --replicas=5 # 访问特定Pod kubectl exec -it mysql-2 -- mysql -uroot -p ``` --- ### **注意事项** - 删除StatefulSet时默认**不会删除关联的PVC**(需手动清理) - 避免直接通过裸Pod修改StatefulSet管理的Pod - 有状态应用的故障恢复通常需要结合备份/恢复方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值