云原生|kubernetes|持久化存储pv,pvc和StorageClass的学习(二)

简介: 云原生|kubernetes|持久化存储pv,pvc和StorageClass的学习

示例:


deploy-nginx.yaml  


此pod的挂载目录不需要提前建立,因为Ensure the file directory is created

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
        volumeMounts:
        - mountPath: /var/local/aaa
          name: mydir
        - mountPath: /var/local/aaa/1.txt
          name: myfile
      volumes:
      - name: mydir
        hostPath:
          path: /var/local/aaa
          type: DirectoryOrCreate
      - name: myfile
        hostPath:
          path: /var/local/aaa/1.txt
          type: FileOrCreate

查询该pod运行在192.168.217.17上,进入17服务器的/var/local/aaa目录下,是可以看到1.txt的

[root@slave1 aaa]# pwd
/var/local/aaa
[root@slave1 aaa]# ls
1.txt

三,local  本地存储


本地持久化存储至少需要两个文件,一个是pv文件,一个是pvc文件,当然,配置本地持久存储就是使用,也就需要部署文件了,并且还需要sc做优化,因此,至多4个文件。

大体规则如下:

  • pv需要设置node亲和,部署文件也需要设置节点亲和,两者亲和是一样的,也就是必须是选择的同一个节点。
  • 官方建议使用StorageClass,也就是sc,sc设置绑定模式为 WaitForFirstConsumer,也就是延迟绑定
  • nginx-pv.yaml   pv文件,pv必须要设置nodeSelector---节点亲和

下面的文件将StorageClass相关注释去掉就可以了,此时一个完整的使用案例就是需要4个文件了。如果保留注释,那么三个文件就可以部署了。

apiVersion: v1
kind: Namespace
metadata:
  name: web
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
  namespace: web
  labels:
    type: local
spec:
  capacity:
    storage: 3Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
#  storageClassName: local-storage
  local:
    path: "/opt/nginx/data"
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key:  kubernetes.io/hostname
          operator: In
          values:
          - k8s-node2

nginx-pvc.yaml   pvc文件


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  namespace: web
  labels:
    app: nginx-pvc
spec:
  accessModes:
  - ReadWriteOnce #此处需要和pv对应才能匹配
  resources:
    requests:
      storage: 2Gi
#  storageClassName: local-storage #此处需要和StorageClass.yaml匹配

nginx-sc.yaml sc文件


kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain

deploy-nginx.yaml 部署文件:


这里使用了两个节点亲和,保留一个就可以啦

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: web
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    volumeMounts:
    - name: nginx-persistent-storage
      mountPath: "/usr/share/nginx/html" #不需要修改,映射到镜像内部目录
  volumes:
    - name: nginx-persistent-storage
      persistentVolumeClaim:
        claimName: nginx-pvc #对应到pvc的名字
  tolerations:
  - operator: Exists
    effect: NoExecute
  nodeName: k8s-node2
  affinity:  #亲和性设置
    nodeAffinity: #申明是node亲和策略
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
        nodeSelectorTerms:
        - matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签,实际没有设置此标签,所以会匹配失败
          - key: node
            operator: In
            values: ["web","dev"]

四,nfs持久化存储属于网络存储,这个也是使用比较普遍的一个存储方式


nfs服务安装在192.168.217.18服务器上,nfs服务的安装流程如下(centos服务器为例):

所有节点都安装

yum install nfs rpcbind nfs-utils -y

在18服务器上:

[root@slave2 local]# cat /etc/exports
/data/nfs-sc  10.244.0.0/16(rw,no_root_squash,no_subtree_check) 192.168.217.16(rw,no_root_squash,no_subtree_check) 192.168.217.0/24(rw,no_root_squash,no_subtree_check) *(rw,no_root_squash,subtree_check)
systemctl enable nfs rpcbind
systemctl restart nfs rpcbind
验证:
[root@slave2 local]# showmount -e 192.168.217.18
Export list for 192.168.217.18:
/data/nfs-sc (everyone)

直接使用nfs存储部署一个nginx持久化存储:

nfs存储卷可以将现有的nfs-server上的存储空间挂载到Pod中使用。当删除Pod时,nfs存储卷的内容会被保留,卷仅是被卸载而不是删除。而且NFS是文件系统级共享服务,支持被多个Pod挂载使用。定义NFS存储卷时支持嵌套使用3个字段:
server:NFS Server的地址或域名
path:NFS Server共享的目录
readOnly:是否以只读方式挂载,默认false

部署示例:


deploy-nginx-volume-demo.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: volume-nfs-demo
  namespace: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: volume-nfs-demo
  template:
    metadata:
      labels:
        app: volume-nfs-demo
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nfs-volume
          mountPath: /usr/share/nginx/html/mysite
      volumes:
      - name: nfs-volume
        nfs:
         server: 192.168.217.18
         path: /data/nfs-s

测试:

在18服务器上建立测试文件

[root@slave2 nfs-sc]# echo "192.168.217.18" >index.html
[root@slave2 nfs-sc]# pwd
/data/nfs-sc

回到集群,查看是否正确挂载:

[root@master nginx]# k exec -it volume-nfs-demo-6dd859c5fc-8ntzs -n web -- /bin/bash
root@volume-nfs-demo-6dd859c5fc-8ntzs:/# curl localhost/mysite/
192.168.217.18

OK,利用nfs网络存储实现数据持久化我们已经可以比较简单的实现了,但问题也比较多,这么一个持久化存储需要我们自己来维护,磁盘限额,挂载方式,回收策略等等还是需要人工处理,这未免不太合适了,并且可能集群内不会只使用一种存储资源,可能会使用ceph,iscsi等等其他的各种存储资源,因此在k8s中,给我们提供了一个新的对象资源,叫做PV,不同的PV会对应到不用的存储资源,这样我们在部署pod的时候直接调用集群内部的pv,即可完成对存储资源的使用,但是呢,直接调用PV的话,有个问题就是,这个pv是否满足我们的需求,因为我们可能需要的是存储能力比较大存储资源,所以这个时候需要一个一个去对比pv,这样很耗费资源,这个时候又引入了我们的pvc。我们在创建pod的时候会附带一个PVC的请求,PVC的请求相当于就是去寻找一个合适的pv,进行绑定,这样我们的pod就会使用到这个pv了。也就是说让我们的pvc去寻找pv,而不是我们的pod资源去寻找。

注:pv和pvc并不是一一对应的,pvc和pv是一一对应的关系,这个不要搞错了(这个需要反复强调)。

nfs服务结合pv和pvc的应用

PV和PVC介绍


PV是由k8s集群管理员在全局级别配置的存储卷,它通过支持的存储卷插件及给定的配置参数关联到指定存储系统的存储空间,这个的存储空间可能是ceph rbd-image、nfs共享的目录和cephfs文件系统等等,也就是说PV的数据最终是保存在后端的存储系统上的。PV将存储系统上的存储空间抽象为集群级别的API资源,由管理员负责创建维护。

将PV提供的存储空间用于Pod对象存储卷时,用户需要先在namespace中创建PVC资源声明需要的存储空间大小和访问模式等属性,接下来PV控制器会选择合适的PV与PVC进行绑定。随后,在Pod资源中通过persistenVolumeCliam卷插件指定要使用的PVC对象就可以使用这个PVC绑定的PV的存储空间。

总结来说,PV和PVC就是在用户和存储系统之间添加的一个中间层,管理员事先定义好PV,用户通过PVC声明要使用的存储特性来绑定符合条件的最佳PV,从而实现了用户和存储系统之间的解耦,用户不需要了解存储系统的具体使用方式,只需要定义PVC就可以。

相关概念(pv,pvc):


1、PersistentVolume (PV)

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


2、PersistentVolumeClaim (PVC)

       PVC 的全称是PersistentVolumeClaim(持久化卷声明),PVC 是用户存储的一种声明,PVC 和 Pod 比较类似,Pod 消耗的是节点,PVC 消耗的是 PV 资源,Pod 可以请求 CPU 和内存,而 PVC 可以请求特定的存储空间和访问模式,例如,可以以读/写一次或 只读多次模式挂载。对于真正使用存储的用户不需要关心底层的存储实现细节,只需要直接使用 PVC 即可。也就是我们集群中会有一个个的PV,可以被直接挂在到某个pod,也可以被PVC绑定,然后挂载到某个pod。


3、静态 pv

       集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于 Kubernetes API 中,可用于消费。


4、动态PV

       当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试动态地为 PVC 创建卷。此配置基于 StorageClasses :PVC 必须请求 [存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为 "" 可以有效地禁用其动态配置。


       要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的DefaultStorageClass [准入控制器]。例如,通过确保 DefaultStorageClass 位于 API server 组件的 --admission-control 标志,使用逗号分隔的有序值列表中,可以完成此操作。


5、绑定PV

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


6、持久化卷声明的保护

       PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失。意思就是我们的PV被我们的PVC绑定的时候,某一天我们的pod被删除之后,这个PVC依然会存在我们的系统之中,并且这个PVC依然会跟我们的PV有一个绑定关系,主要是为了防止我们的pod出现丢失之后,PVC被删除了,数据就会丢失,这个肯定是合理的。


       当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用。


7、访问模式

       PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为 对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器 上以只读的方式导出。每个 PV 卷都会获得自身的访问模式集合,描述的是 特定 PV 卷的能力


在命令行接口(CLI)中,访问模式也使用以下缩写形式:


RWO - ReadWriteOnce

ROX - ReadOnlyMany

RWX - ReadWriteMany

RWOP - ReadWriteOncePod

8、PVC 状态

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

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

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

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


9,


PV资源的spec字段可以嵌套使用下面这些字段:


<volume-plugin> <Object>:具体存储卷插件配置,用来指定PV关联的存储设备,和Pod直接通过存储卷插件定义卷的参数一致

accessModes <[]string>:指定PV的访问模式,目前支持

capacity <map[string]string>:指定PV的容量

mountOptions <[]string>:挂载选项

nodeAffinity <Object>:节点亲和性,用于限制能访问该PV的节点

persistentVolumeReclaimPolicy <string>:当前PV的回收策略

volumeMode <string>:该PV的卷模型,用于指定此存储卷是被格式化为文件系统使用还是直接作为裸格式块设备使用,默认为Filesystem

storageClassName <string>:此PV所属的存储类名称,默认为空,不属于任何存储类


10,

PVC隶属于名称空间级别,定义PVC时可以通过访问模式、标签选择器、PV名称和存储资源需求限制多个匹配方式来筛选PV。其中访问模式和资源需求限制是重要的筛选标准。PVC的spec字段支持嵌套使用下面这些字段:

accessModes <[]string>:PVC的访问模式,可用值必须和PV的访问模式一致

resources <Object>:声明PVC要使用存储空间的需求和限制

dataSource <Object>:用于从指定的数据源恢复该PVC卷,目前支持从卷快照或已存在的PVC恢复

selector <Object>:标签选择器,用于筛选PV

storageClassName <string>:该PVC隶属的存储类

volumeMode <string>:卷模型,用于指定此存储卷是被格式化为文件系统使用还是直接使用裸格式的块设备;默认为Filesystem

volumeName <string>:直接指定要绑定的PV资源名称

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
10月前
|
存储 Kubernetes 安全
k8s存储类型:emptyDir、hostPath、nfs、pvc及存储类storageclass的静态/动态创建pv
Kubernetes提供了多种存储类型,满足不同的应用需求。`emptyDir`和 `hostPath`适用于临时和宿主机存储需求,`nfs`适用于共享存储,`PersistentVolumeClaim`和 `StorageClass`实现了持久存储的灵活管理。通过理解和配置这些存储类型,可以有效提升Kubernetes集群的存储管理能力。
503 13
|
11月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
439 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
12月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
12月前
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
282 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
417 16
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
1月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
437 0
|
7月前
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。
|
4月前
|
运维 监控 Cloud Native
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
102 1

热门文章

最新文章