目录
3.使用Deployment创建NFS Provisioner
前言
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。
一、Volume卷的管理
1.emptyDir存储卷
1.1定义
当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除。
1.2实例
mkdir /opt/volumes
cd /opt/volumes
vim pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: soscscs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
#定义容器挂载内容
volumeMounts:
#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
- name: cxk
#挂载至容器中哪个目录
mountPath: /usr/share/nginx/html/
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: cxk
#在容器内定义挂载存储名称和挂载路径
mountPath: /data/
command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
#一直循环 echo 时间 2秒一次 条件会一直满足,除非date失效
#定义存储卷
volumes:
#定义存储卷名称
- name: cxk
#定义存储卷类型
emptyDir: {}
kubectl apply -f pod-emptydir.yaml
kubectl get pods -o wide
kubectl describe pod pod-emptydir
kubectl exec -it pod-emptydir -c busybox sh
cd /data/
tail -f index.html
1.3特点
- 临时性存储:
- emptyDir 提供的存储是临时的,其生命周期与所属的 Pod 相关。
- 当 Pod 被删除时,emptyDir 中的数据也会被清除,因此不适合用于持久化存储。
- Pod 内容器之间的共享:
- emptyDir 在同一个 Pod 中的所有容器之间共享,容器可以读写其中的数据。
- 创建时机:
- emptyDir 在 Pod 创建时被创建,当容器启动时,可以访问其中的空目录。
1.4用途
- 适用于需要在同一个 Pod 中的多个容器之间进行临时数据交换或共享的场景。
- 例如,可以用于容器间的缓存共享、临时文件存储等用途。
2.hostPath存储卷
2.1定义
hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失。
2.2实例
#在 node01 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'node01.cxk.com' > /data/pod/volume1/index.html
#在 node02 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'node02.cxk.com' > /data/pod/volume1/index.html
vim pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
namespace: default
spec:
containers:
- name: myapp
image: soscscs/myapp:v1
#定义容器挂载内容
volumeMounts:
#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
- name: html
#挂载至容器中哪个目录
mountPath: /usr/share/nginx/html
#读写挂载方式,默认为读写模式false,如果是false的话是可读可写操作
readOnly: false
#volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷
volumes:
#存储卷名称
- name: html
#路径,为宿主机存储路径
hostPath:
#在宿主机上目录的路径
path: /data/pod/volume1
#定义类型,这表示如果宿主机没有此目录则会自动创建
type: DirectoryOrCreate
kubectl apply -f pod-hostpath.yaml
#删除pod,再重建,验证是否依旧可以访问原来的内容
kubectl delete -f pod-hostpath.yaml
kubectl apply -f pod-hostpath.yaml
kubectl get pods -o wide
2.2特点
- 直接访问主机文件系统: HostPath存储卷允许Pod直接访问主机节点上的文件系统,提供了对主机存储的直接访问权限。
- 读写权限: Pod可以对HostPath上的文件进行读写操作,这为一些需要在容器内进行文件操作的应用提供了便利。
- 节点依赖性: Pod使用HostPath时,会依赖节点上的具体路径,这可能导致在不同节点上部署相同Pod时出现问题,因为节点之间的文件系统路径可能不同。
- 共享资源:多个Pod可以共享同一个HostPath,但要小心避免数据冲突或竞争条件。
2.3用途
- 主机文件操作: 适用于需要在Pod内进行主机文件系统操作的场景,例如读取或写入主机上的特定文件。
- 数据共享: 多个Pod可以共享同一个HostPath,这在一些需要多个Pod之间共享数据的情况下可能很有用。
- 特殊需求: 用于满足一些特殊需求,例如某些应用需要在容器内直接操作主机上的某些文件。
需要注意的是,由于HostPath存储卷的使用可能涉及到权限和安全性的考虑,一般情况下建议慎重使用,并确保在生产环境中采取适当的安全措施。
3.NFS共享存储卷
3.1定义
在Kubernetes中,NFS共享存储卷是一种常见的持久化存储解决方案,它允许多个Pod在集群中共享同一个NFS服务器上的存储空间。
- NFS介绍: NFS(Network File System)是一种基于网络的文件系统协议,允许在网络上共享文件系统资源。它使得不同的计算机之间可以像访问本地文件一样访问远程文件。
- Kubernetes中的NFS存储卷: Kubernetes提供了多种方式来使用NFS作为持久化存储卷。其中一种常见的方法是使用NFS卷插件,例如NFS CSI Driver,它能够与Kubernetes集成并提供对NFS存储的访问。
- 配置NFS存储卷: 要在Kubernetes中配置NFS存储卷,首先需要在NFS服务器上设置共享目录,并确保NFS服务器可以通过网络访问。然后,可以通过Kubernetes的PersistentVolume(PV)和PersistentVolumeClaim(PVC)对象来声明和使用NFS存储卷。
3.2特点
- 共享性: NFS存储卷允许多个Pod在集群中共享同一个NFS服务器上的存储空间。这使得多个应用程序可以访问和操作相同的数据,促进了数据共享和协作。
- 持久性: NFS存储卷提供了持久化的存储解决方案,数据存储在NFS服务器上并且在Pod重新启动或迁移时仍然可用。这对于需要长期保存数据的应用程序和服务非常有用。
- 可扩展性: NFS存储卷可以轻松地扩展以满足应用程序的需求。通过在NFS服务器上添加更多的存储空间或者增加NFS服务器的数量,可以扩展存储容量和性能。
- 灵活性: 使用NFS存储卷可以将存储与Pod分离,从而使得Pod可以在不同的节点上迁移而不会丢失数据。这种灵活性使得在Kubernetes集群中部署和管理应用程序变得更加容易。
3.3用途
- 简化管理: NFS存储卷可以通过Kubernetes的PV和PVC对象进行声明和管理,而无需手动管理存储配置。这简化了存储管理的流程,并提高了部署和维护的效率。
- 适用范围广泛: NFS存储卷适用于许多不同类型的应用程序和场景,包括数据库、文件共享、日志存储等。它提供了一种通用的存储解决方案,适用于各种不同的业务需求。
3.4实例
在stor01节点上安装nfs,并配置nfs服务
mkdir /data/volumes -p
chmod 777 /data/volumes
#使用 chmod 777 /data/volumes 命令将 /data/volumes 目录的权限设置为 777,以确保所有用户都有完全的读写权限
vim /etc/exports
/data/volumes 192.168.241.0/24(rw,no_root_squash)
#这表示将 /data/volumes 目录导出给位于子网 192.168.41.0/24 的主机,允许读写访问,并且禁用了 no_root_squash
systemctl start rpcbind
systemctl start nfs
#启动 RPC 绑定和 NFS 服务
showmount -e stor01
#检查 NFS 导出列表,确认 /data/volumes 目录已经成功导出给了 192.168.241.0/24 子网的主机。
Export list for stor01:
/data/volumes 192.168.241.0/24
#这些步骤使得在网络上可以访问并且共享 /data/volumes 目录。
#master节点操作
vim pod-nfs-vol.yaml
kind: Pod # 指定资源类型为 Pod
apiVersion: v1 # 使用 API 版本 v1
metadata:
name: pod-vol-nfs # Pod 的名称为 pod-vol-nfs
namespace: default # Pod 将被创建在 default 命名空间中
spec: # 描述 Pod 的规格(specification)
containers:
- name: myapp # 容器的名称为 myapp
image: soscscs/myapp:v1 # 容器使用的镜像为 soscscs/myapp:v1
volumeMounts: # 容器内的卷挂载设置
- name: html # 卷的名称为 html
mountPath: /usr/share/nginx/html # 容器内挂载卷的路径
volumes: # Pod 级别的卷定义
- name: html # 定义一个名为 html 的卷
nfs: # 指定卷类型为 NFS
path: /data/volumes # NFS 服务器上共享的路径
server: stor01 # NFS 服务器的主机名或 IP 地址
#此配置文件通过 NFS 卷将外部存储挂载到 Pod 中的容器上,使得容器可以访问 NFS 上的数据
kubectl apply -f pod-nfs-vol.yaml
#用来创建并查看 Kubernetes Pod 和将 pod-nfs-vol.yaml 文件中定义的 Pod 配置应用到 Kubernetes 集群中,从而创建名为 pod-vol-nfs 的 Pod,其中包含一个名为 myapp 的容器,并挂载了一个 NFS 类型的卷
kubectl get pods -o wide
#用于获取当前 Kubernetes 集群中的 Pod 列表
#在nfs服务器上创建index.html
cd /data/volumes
vim index.html
<h1> nfs test</h1>
#master节点操作
curl 10.244.2.75
<h1> nfs test</h1>
kubectl delete -f pod-nfs-vol.yaml
#删除nfs相关pod,再重新创建,可以得到数据的持久化存储
kubectl apply -f pod-nfs-vol.yaml
kubectl get pod -owide
curl 10.244.2.76
<h1> nfs test</h1>
二、PV和PVC
1.定义
PV 全称叫做 Persistent Volume,持久化存储卷。它是用来描述或者说用来定义一个存储卷的,这个通常都是由运维工程师来定义。
PVC 的全称是 Persistent Volume Claim,是持久化存储的请求。它是用来描述希望使用什么样的或者说是满足什么条件的 PV 存储。
PVC 的使用逻辑:在 Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源。
- PV(Persistent Volume)是描述或定义存储卷的工具,通常由运维工程师创建。
- PVC(Persistent Volume Claim)是对PV的请求,用于描述所需的存储条件。
PVC的逻辑是在Pod中定义一个存储卷(类型为PVC),指定大小并与相应的PV建立关系。PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PPV由存储空间创建,二者是Kubernetes抽象的存储资源。
在Kubernetes中,PV(持久卷)有两种供给方式,静态和动态。静态PV是由集群管理员手动创建的,携带着真实存储信息,但存在缺陷,因为需要手动为多个用户配置存储,可能显得繁琐。而动态PV则是当静态PV无法匹配用户的PVC(持久卷声明)时,集群会尝试动态地供给volume给PVC,更灵活地满足用户需求。
为了避免手动创建PV的繁琐,Kubernetes引入了StorageClass,用于自动创建PV模板。创建StorageClass需定义PV属性和存储插件,如Ceph。Kubernetes可根据用户PVC请求,使用对应的StorageClass调用StorageClass 声明的存储插件自动创建需要的PV并进行绑定。
PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索引检查。
2.PV和PVC之间的相互作用的生命周期
- Provisioning(配置): PV的创建阶段,可通过静态方式直接创建PV,或使用StorageClass进行动态创建。
- Binding(绑定): 将PV分配给对应的PVC。
- Using(使用): Pod通过PVC使用Volume,通过准入控制StorageProtection(1.9及以前版本为PVCProtection)可以阻止删除正在使用的PVC。
- Releasing(释放): Pod释放Volume并删除PVC。
- Recycling(回收): 回收PV,可保留PV以备下次使用,或直接从云存储中删除。
PV独立于Pod的生命周期:PV的生命周期独立于使用它的Pod的生命周期,存储的数据不会因为Pod的删除而丢失。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: "/mnt/data"
- 动态绑定:PVC会根据需求自动绑定到一个合适的PV。
- 资源请求:PVC可以请求特定的存储容量和访问模式(如ReadWriteOnce、ReadOnlyMany、ReadWriteMany)。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
3.PV的状态
- Available(可用):PV已经被创建,但尚未被绑定到任何PVC上,因此可以被任何PVC请求使用。
- Bound(已绑定):PV已经被绑定到一个PVC上,可以被挂载到一个Pod中使用。
- Released(已释放):PVC与PV之间的绑定关系已经被删除,但是PV上的数据还未被清除。此时PV处于Released状态,可以被重新绑定到另一个PVC上使用。
- Failed(失败):PV与底层存储后端的连接出现问题,或者存储后端出现了错误,导致PV无法使用。此时PV处于Failed状态。
4.PV从创建到销毁的过程
PV(Persistent Volume)从创建到销毁的过程通常包括以下几个步骤:
- 创建(Provisioning):PV可以通过两种方式创建,一种是静态创建,另一种是动态创建。静态创建是指管理员手动创建PV对象并指定其属性,如存储类型、大小等。动态创建则是通过StorageClass进行配置,当PVC请求存储资源时,根据StorageClass的定义动态创建PV。无论是静态还是动态创建,都会生成一个PV对象。状态会变成Available,等待被PVC绑定
- 绑定(Binding):PV需要与PVC进行绑定才能被使用。管理员或Kubernetes系统会将某个PV绑定到一个特定的PVC上,使其成为PVC的存储资源,状态会变成Bound,就可以被定义了相应PVC的Pod使用。
- 使用(Using):一旦PV被绑定到PVC上,Pod可以通过PVC来使用PV提供的存储资源。Pod会挂载PVC,从而访问PV中的数据,。
- 释放(Releasing):当PVC不再需要PV提供的存储资源时,管理员或Kubernetes系统会将PV与PVC之间的绑定解除,释放PV,PV的状态变成Released。这并不会立即删除PV中的数据,而是将PV标记为已释放状态。
- 回收(Recycling):在PV被释放后,根据管理员或系统配置的策略,可以选择回收PV。回收的方式可能包括保留PV以备下次使用,或者直接删除PV以释放资源。有三种回收策略,Retain、Delete和Recycle。Retain就是保留现场,K8S集群什么也不做,等待用户手动去处理PV里的数据,处理完后,再手动删除PV。Delete策略,K8S会自动删除该PV及里面的数据。Recycle方式,K8S会将PV里的数据删除,然后把PV的状态变成Available,又可以被新的PVC绑定使用。
5.回收策略
在Kubernetes中,PV(Persistent Volume)的回收策略定义了在释放PV时如何处理其底层存储资源。常见的PV回收策略包括以下几种:
- Retain(保留):当PV被释放后,底层存储资源不会被删除,而是保留在系统中。这意味着PV的数据仍然可用,但需要手动处理以释放存储资源。
- Recycle(回收):在这种策略下,PV被释放后,底层存储资源会被清空,以便下次使用。然而,这种方式存在安全性和隐私问题,因此已经不推荐使用。
- Delete(删除):PV被释放后,底层存储资源会被直接删除。这是一种自动化的清理方式,适用于不再需要PV数据的情况。
kubectl explain pv
#查看pv的定义方式
kubectl explain pv.spec
#查看pv定义的规格
accessModes有以下三种访问模型,以列表的方式存在,也就是说可以定义多个访问模式)
- ReadWriteOnce #(RWO)存储可读可写,但只支持被单个 Pod 挂载
- ReadOnlyMany #(ROX)存储可以以只读的方式被多个 Pod 挂载
- ReadWriteMany #(RWX)存储可以以读写的方式被多个 Pod 共享 注:官网
#nfs 支持全部三种;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 网络上运行 SCSI 协议的一种网络存储技术);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | × | - | - |
AzureFile | × | × | × |
CephFS | × | × | × |
Cinder | × | - | - |
FC | × | × | - |
FlexVolume | × | × | - |
GCEPersistentDisk | × | × | - |
Glusterfs | × | × | × |
HostPath | × | - | - |
iSCSI | × | × | - |
NFS | × | × | × |
RDB | × | × | - |
VsphereVolume | × | - | - |
#PV和PVC中的spec关键字段要匹配,比如存储(storage)大小、访问模式(accessModes)、存储类名称(storageClassName)
6.PV的操作
在 Kubernetes 中,PV(PersistentVolume)是集群中的一种资源,用于提供持久化存储。PV 的操作包括以下几个方面:
- 创建 PV:可以通过定义 PV 对象的 YAML 文件来创建 PV。在 YAML 文件中指定 PV 的属性,如容量、访问模式、存储类型等。
- 删除 PV:当 PV 不再需要时,可以通过删除相应的 PV 对象来释放资源。删除 PV 时需要确保相关的 PVC(PersistentVolumeClaim)已经被释放,否则删除操作可能会失败。
- 管理 PV 的状态:可以通过修改 PV 对象的属性来管理 PV 的状态,如修改容量、访问模式等。需要注意的是,某些属性(如容量)可能无法在运行时修改,需要在创建 PV 时就确定好。
- 挂载 PV 到 Pod:创建 PV 后,需要将 PV 挂载到 Pod 中以供应用程序使用。可以通过 PVC(PersistentVolumeClaim)来实现 PV 和 Pod 之间的绑定关系。
- 监控 PV 的使用情况:可以通过 Kubernetes 的监控系统或者第三方工具来监控 PV 的使用情况,包括存储容量、使用率等指标。
这些是在 Kubernetes 中对 PV 进行常见操作的一些例子。 PV 的操作可以通过命令行工具(如 kubectl)、Kubernetes API 或者管理平台(如 Kubernetes Dashboard)来进行。
关联关系
当PVC创建时,Kubernetes会在现有的PV中寻找与之匹配的存储资源。如果找到匹配的PV,PVC会绑定到该PV,之后Pod可以使用这个PVC来持久化数据。
使用流程
- 管理员创建PV:管理员定义和创建PV,指定存储容量、访问模式和存储位置等信息。
- 用户创建PVC:用户创建PVC,指定所需的存储容量和访问模式。
- Kubernetes绑定PVC到PV:Kubernetes自动将PVC与合适的PV绑定。
- Pod使用PVC:Pod通过声明PVC来使用持久化存储资源。
6.1简单举例
#创建 PV 时,通过以下 YAML 示例可以指定 PV 的基本属性
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity: #定义了 PV 的存储容量
storage: 5Gi
volumeMode: Filesystem #指定了 PV 的工作模式,可以是 Filesystem 或 Block
accessModes: #定义了 PV 的访问模式,包括 ReadWriteOnce、ReadOnlyMany 和 ReadWriteMany
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain #定义了当 PV 释放时的回收策略,可以是 Retain、Recycle 或 Delete
storageClassName: standard #指定了 PV 所属的存储类
mountOptions: #包含了挂载 PV 时使用的挂载选项
- hard
- nfsvers=4.1
nfs: #描述了 NFS 类型的 PV 的具体配置,包括 NFS 服务器地址和路径
path: /export/data
server: nfs-server.example.com
#删除 PV 时,可以使用以下命令
kubectl delete pv example-pv
#管理 PV 状态时,可以通过修改 PV 对象的 YAML 文件中的字段值来实现。例如,修改 PV 的容量
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi # 修改容量为10Gi
...
#挂载 PV 到 Pod 时,需要创建一个 PVC,并在 Pod 的 YAML 文件中引用该 PVC。例如
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: my-volume
mountPath: /mnt/data
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: example-pvc # 引用 PVC 的名称
6.2结合举例
在 Kubernetes 中,PV 的动态配置是一项重要的功能,它允许集群动态地创建和管理 PV 资源。以下是 PV 的动态配置的一般流程
- 定义存储类(StorageClass):首先,需要定义一个存储类,它描述了动态创建 PV 所需的存储属性。以下是一个存储类的示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: example.com/nfs
其中,provisioner
指定了用于动态创建 PV 的存储插件。
- 创建 PVC:接下来,创建一个 PVC,请求所需的存储资源。PVC 将使用存储类来确定如何动态地创建 PV。以下是 PVC 的示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
在这个示例中,storageClassName
指定了使用的存储类,而 resources
字段指定了 PVC 请求的存储容量。
- 动态创建 PV:当 PVC 被创建时,存储类会使用定义的插件动态创建 PV,并将其与 PVC 绑定。
- 挂载 PV 到 Pod:最后,创建 Pod,并通过 PVC 引用 PV,将其挂载到 Pod 中。以下是一个 Pod 的示例
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- mountPath: "/mnt/data"
name: my-volume
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc
在这个示例中,persistentVolumeClaim
字段引用了前面创建的 PVC。
这样,通过存储类和 PVC 的组合,Kubernetes 可以实现 PV 的动态创建和管理,使存储资源更加灵活和自动化。
6.3查看PV的定义方式
#查看pv的定义方式
kubectl explain pv
kubectl explain 命令可以用来查看 Kubernetes 资源的定义方式和字段说明。对于 PV(PersistentVolume),以下是其定义方式和字段说明:
- apiVersion:表示 Kubernetes API 的版本。对于 PV,它的 API 版本通常为 v1。
- kind:表示 Kubernetes 资源的类型。对于 PV,它的类型是 PersistentVolume。
- metadata:包含有关 PV 的元数据信息,如名称、标签等。由于 PV 是集群级别的资源,因此 PV 的 metadata 中不需要配置命名空间(namespace)。
- spec:PV 的规格(specification),定义了 PV 的属性和配置。PV 的规格包括以下属性:
- capacity:定义了 PV 的存储容量。
- volumeMode:指定了 PV 的工作模式,可以是 Filesystem 或 Block。
- accessModes:定义了 PV 的访问模式,包括 ReadWriteOnce、ReadOnlyMany 和 ReadWriteMany。
- persistentVolumeReclaimPolicy:定义了当 PV 释放时的回收策略,可以是 Retain、Recycle 或 Delete。
- storageClassName:指定了 PV 所属的存储类。
- mountOptions:包含了挂载 PV 时使用的挂载选项。
- nfs、iscsi、awsElasticBlockStore 等:描述了不同类型 PV 的具体配置。
6.4查看PV定义的规格
kubectl explain pv.spec
kubectl explain pv.spec
命令用于查看 PV 规格中的spec
字段的详细说明。以下是pv.spec
的说明- spec.nfs:用于定义 NFS 类型的存储。
- path:指定了挂载卷的路径。
- server:指定了 NFS 服务器的名称。
- spec.accessModes:定义了 PV 的访问模式,可以有以下三种模式,以列表的方式存在,允许定义多个访问模式:
- ReadWriteOnce(RWO):存储可读可写,但只支持被单个 Pod 挂载。
- ReadOnlyMany(ROX):存储可以以只读的方式被多个 Pod 挂载。
- ReadWriteMany(RWX):存储可以以读写的方式被多个 Pod 共享。
这些规格说明了 PV 中存储类型的配置以及访问模式的定义方式。PV 的 spec
字段允许定义不同类型的存储,并配置适当的访问模式以满足应用程序对持久化存储的需求。
- nfs 支持全部三种;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 网络上运行 SCSI 协议的一种网络存储技术);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。
- capacity:用于定义 PV 的存储容量。在配置中,storage 字段用于指定存储的大小,以 GiB 或者其他存储单位为单位。
- storageClassName:用于指定 PV 所属的存储类。存储类是用来定义存储资源的配置和策略,以便于 PV 和 PVC 的匹配。通过指定相同的存储类,可以确保 PVC 和 PV 之间的匹配。
- persistentVolumeReclaimPolicy:定义了 PV 释放后的回收策略,有以下几种选项:
- Retain(保留):当 PV 被释放时,将 PV 标记为 "released" 状态,数据依然保存在 PV 上,但 PV 不可用,需要手动处理数据并删除 PV。
- Delete(删除):当 PV 被释放时,将删除与 PV 相关联的后端存储资源。需要注意的是,只有某些后端存储资源(如 AWS EBS、GCE PD、Azure Disk 和 Cinder)支持此选项。
- Recycle(回收):当 PV 被释放时,将删除 PV 上的数据,相当于执行 rm -rf /thevolume/*。需要注意的是,只有某些后端存储资源(如 NFS 和 HostPath)支持此选项。
6.5查看PVC的定义方式
#查看PVC的定义方式
kubectl explain pvc
kubectl explain pvc
命令用于查看 PVC(PersistentVolumeClaim)的定义方式和字段说明。以下是 PVC 的基本字段说明:
- apiVersion:指示 Kubernetes API 的版本。对于 PVC,通常是 v1。
- kind:指明资源类型,在这个情况下是 PersistentVolumeClaim。
- metadata:包含关于 PVC 的元数据信息,如名称、命名空间、标签等。
- spec:定义了 PVC 的规格,包括请求的存储容量、访问模式等。PVC 的 spec 字段主要包含以下属性:
- accessModes:一个 PVC 请求的访问模式列表,包括 ReadWriteOnce、ReadOnlyMany 和 ReadWriteMany。
- resources:请求的资源,通常是存储资源。在 resources 下的 requests 字段中可以指定所需的存储容量。
- storageClassName:指定 PVC 要使用的 StorageClass 的名称。StorageClass 用于动态配备 PV。
- volumeName:如果要将 PVC 绑定到特定的 PV,则可以指定 PV 的名称。通常,这个字段由 Kubernetes 系统自动填充,当动态配备或者预先存在的 PV 与 PVC 匹配时。
- selector:允许指定一个标签选择器来进一步约束应该绑定到 PVC 的 PV。这可以用于选择一组特定的 PV。
PVC 是 Kubernetes 中的一种资源,它允许用户声明他们所需要的存储资源。PVC 与 PV 之间的绑定可以是动态的,也可以是静态的,取决于是否使用 StorageClass 以及如何配置 PVC 和 PV。- volumeMode:指定所请求的卷是应被格式化为文件系统还是作为原始块设备提供。可能的值包括 Filesystem 和 Block。
dataSource
:指定从现有的 PVC 或快照创建新 PVC 的数据源。这允许用户克隆现有的 PVC 或从快照创建 PVC,实现数据的复制和恢复。
PVC 的定义方式为用户与存储资源之间提供了一个抽象层,使得用户无需关心底层存储的具体实现细节,只需根据需求声明所需的存储容量和访问模式。Kubernetes 系统将负责满足这些请求,无论是通过动态地创建新的 PV 来配合 PVC,还是通过匹配现有的、未被其他 PVC 使用的 PV。
PV和PVC中的spec关键字段要匹配,比如存储(storage)大小、访问模式(accessModes)、存储类名称(storageClassName)
6.6查看PVC定义规格
kubectl explain pvc.spec
spec.accessModes:定义了 PVC 请求的访问模式,必须是 PV 的访问模式的子集。可以指定一个或多个访问模式,以满足应用程序的需求。支持的访问模式包括:
ReadWriteOnce(RWO):存储可读可写,但只支持被单个 Pod 挂载。
ReadOnlyMany(ROX):存储可以以只读的方式被多个 Pod 挂载。
ReadWriteMany(RWX):存储可以以读写的方式被多个 Pod 共享。
spec.resources.requests.storage:用于定义 PVC 请求的存储容量。在 requests 字段下的 storage 字段中指定所需的存储容量,以 GiB 或其他存储单位为单位。Kubernetes 将尝试为 PVC 分配至少指定大小的 PV。
spec.storageClassName:指定 PVC 要使用的存储类的名称。存储类定义了 PV 的属性和配置,以便与 PVC 匹配。当 PVC 没有明确指定存储类时,将使用默认的存储类。指定存储类的好处在于可以根据应用程序的需求定义不同的存储策略,例如性能、可靠性和成本等方面。
这些规格允许用户定义 PVC 所需的存储容量、访问模式和存储类,从而满足应用程序对持久化存储的需求。PV 将根据这些规格来为 PVC 提供相应的存储资源,并与 PVC 进行绑定以供应用程序使用。
三、NFS使用PV和PVC(静态)
1.配置NFS存储
mkdir v{1,2,3,4,5}
vim /etc/exports
#在 /etc/exports 文件中配置了这些目录的导出选项,允许 192.168.241.0/24 网段的主机以读写方式挂载这些目录,并且禁止了 root 用户权限限制。
/data/volumes/v1 192.168.241.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.241.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.241.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.241.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.241.0/24(rw,no_root_squash)
exportfs -arv
#通过 exportfs -arv 命令重新加载并应用了导出的设置
showmount -e
#使用 showmount -e 命令显示了可导出的目录列表
官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
2.定义PV
#这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小。
vim pv-demo.yaml
apiVersion: v1
#apiVersion: 指定了 Kubernetes API 的版本,这里使用的是 v1 版本
kind: PersistentVolume
#kind: 指定了 Kubernetes 资源的类型,这里是 PersistentVolume,表示持久卷
metadata:
#metadata: 元数据部分,包含了持久卷的名称和标签信息
name: pv001
labels:
name: pv001
spec:
#spec: 规范部分,定义了持久卷的详细配置
nfs:
#nfs: 指定了该持久卷使用 NFS 存储,包括 NFS 服务器地址和路径
path: /data/volumes/v1
server: stor01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
#accessModes: 指定了持久卷的访问模式,可以是 ReadWriteOnce(单个节点读写)、ReadOnlyMany(多个节点只读)或 ReadWriteMany(多个节点读写)
capacity:
#指定了持久卷的容量大小
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /data/volumes/v2
server: stor01
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /data/volumes/v3
server: stor01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
labels:
name: pv004
spec:
nfs:
path: /data/volumes/v4
server: stor01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /data/volumes/v5
server: stor01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
#这个文件中包含了五个不同的持久卷配置,每个持久卷都有唯一的名称和配置。这些持久卷可以被 Kubernetes 应用程序通过 PersistentVolumeClaim(持久卷声明)来请求和使用。
kubectl apply -f pv-demo.yaml
#根据 pv-demo.yaml 文件中的配置创建 PersistentVolume(持久卷)
kubectl get pv
#列出所有已经存在的 PersistentVolume,以便确认这些持久卷是否已经成功创建并且处于可用状态
3.定义PVC
#这里定义了pvc的访问模式为多路读写,该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi,此时PVC会自动去匹配多路读写且大小为2Gi的PV,匹配成功获取PVC的状态即为Bound
vim pod-vol-pvc.yaml
apiVersion: v1
#指定了 Kubernetes API 的版本,这里是 v1
kind: PersistentVolumeClaim
#资源类型,这里是 PersistentVolumeClaim,表示一个存储卷声明
metadata:
#包含资源的元数据,这里定义了 PVC 的名称为 mypvc
name: mypvc
namespace: default
spec:
#规格定义部分
accessModes: ["ReadWriteMany"]
#定义了 PVC 的访问模式,这里是 ReadWriteMany,意味着存储卷可以被多个节点同时以读写方式挂载
resources:
#定义了资源请求
requests:
#指定了存储资源的请求量,这里是 2Gi
storage: 2Gi
---
apiVersion: v1
#指定 Kubernetes API 的版本,这里也是 v1
kind: Pod
#资源类型,这里是 Pod
metadata:
#包含资源的元数据,这里定义了 Pod 的名称为 pod-vol-pvc
name: pod-vol-pvc
namespace: default
spec:
#规格定义部分,描述了 Pod 的具体配置
containers:
#容器数组,每个对象定义了一个容器的配置
- name: myapp
#容器的名称,这里是 myapp
image: soscscs/myapp:v1
#容器的镜像,这里使用的是 soscscs/myapp:v1
volumeMounts:
#定义了容器内的挂载点
- name: html
#卷的引用名称,这里是 html
mountPath: /usr/share/nginx/html
#容器内的挂载路径,这里是 /usr/share/nginx/html
volumes:
#定义了 Pod 级别的存储卷
- name: html
#卷的名称,与 volumeMounts 中的引用名称相匹配,这里是 html
persistentVolumeClaim:
#指定了卷的来源是一个 PVC
claimName: mypvc
#引用 PVC 的名称,这里是 mypvc
#这个 YAML 文件定义了两个 Kubernetes 资源:一个 PersistentVolumeClaim (PVC) 和一个 Pod,它们都配置在默认的命名空间中。这个配置允许 Pod pod-vol-pvc 通过 PVC mypvc 挂载一个持久卷到容器的 /usr/share/nginx/html 路径。
kubectl apply -f pod-vol-pvc.yaml
kubectl get pv,pvc
4.测试访问
#在nfs存储服务器上创建index.html,并写入数据,通过访问Pod进行查看,可以获取到相应的页面
cd /data/volumes/v3/
echo "welcome to use pv3" > index.html
kubectl get pods -o wide
curl 10.244.2.77
四、StorageClass实现PV和PVC的动态创建
Kubernetes 本身支持的动态 PV 创建不包括 NFS,所以需要使用外部存储卷插件分配PV。
官网:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
卷插件称为 Provisioner(存储分配器),NFS 使用的是 nfs-client,这个外部PV。
Provisioner:用于指定 Volume 插件的类型,包括内置插件(如 kubernetes.io/aws-ebs)和外部插件(如 exte卷插件会使用已经配置好的 NFS 服务器自动创建 rnal-storage 提供的 ceph.com/cephfs)。
- 内置插件:kubernetes.io/aws-ebs 是用于 AWS Elastic Block Store(EBS)的内置插件。它能够动态地创建和管理 AWS EBS 存储。
- 外部插件 : ceph.com/cephfs,这是 Ceph 文件系统的外部插件。此外,nfs-client 也是一个外部插件,用于与 NFS 服务器集成,实现动态创建 PV。
在使用外部插件时,通常需要确保已经正确配置并运行相应的存储系统,以便 Kubernetes 能够利用它们进行动态 PV 的创建和管理。
步骤如下:
- 配置 NFS 服务器,确保 NFS 服务已正确配置和运行。
- 创建 StorageClass,并将 Provisioner 设置为 nfs-client,同时指定 NFS 服务器的地址和共享路径。
- 创建 PVC,使用上述创建的 StorageClass。
- 检查 PV 是否已自动创建,系统会自动创建 PV 并与 PVC 绑定,实现动态的 NFS PV 创建。
参考链接:Kubernetes 存储类概念
1.安装并配置NFS服务
mkdir /opt/k8s
chmod 777 /opt/k8s/
vim /etc/exports
/opt/k8s 192.168.241.0/24(rw,no_root_squash,sync)
#允许192.168.41.0/24网段的主机以读写模式挂载/opt/k8s目录,并且不进行root权限转换(norootsquash),并同步写入(sync)
systemctl restart nfs
2.创建Service Account并设置规则
在Kubernetes(k8s)集群中,创建Service Account是为了管理NFS Provisioner在集群中运行时的权限。NFS Provisioner是用于动态创建Persistent Volumes(PV)和Persistent Volume Claims(PVC)的工具,通常与StorageClass一起使用。
设置nfs-client对PV、PVC和StorageClass的规则是确保NFS Provisioner在使用NFS共享存储时遵循一定的访问和权限规则。这可以包括定义NFS服务器地址、共享路径、访问权限等配置,以便Kubernetes中的应用程序能够正确地使用NFS存储。通过Service Account的设置,可以为NFS Provisioner分配适当的权限,确保其能够成功管理和提供NFS存储服务。
vim nfs-client-rbac.yaml
# 创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner # Service Account 的名称
---
# 创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-clusterrole # 集群角色的名称
rules:
- apiGroups: [""]
resources: ["persistentvolumes"] # 可操作的资源类型
verbs: ["get", "list", "watch", "create", "delete"] # 允许的操作
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
# 集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
#定义了一个名为nfs-client-provisioner-clusterrolebinding的ClusterRoleBinding,将前面定义的ClusterRole绑定到先前定义的Service Account上,以确保该Service Account拥有相应的权限
metadata:
name: nfs-client-provisioner-clusterrolebinding # 集群角色绑定的名称
subjects:
- kind: ServiceAccount
#定义了一个名为nfs-client-provisioner的Service Account,用于代表NFS Provisioner在集群中运行时的身份
name: nfs-client-provisioner # 绑定的 Service Account 的名称
namespace: default # 所在的命名空间
roleRef:
kind: ClusterRole
#定义了一个名为nfs-client-provisioner-clusterrole的ClusterRole,包含了对于Persistent Volumes(PV)、Persistent Volume Claims(PVC)、StorageClasses等资源的访问权限规则。这些规则包括获取、列出、监视、创建和删除PV、PVC,以及获取、列出、监视StorageClasses等操作。
name: nfs-client-provisioner-clusterrole # 所绑定的集群角色名称
apiGroup: rbac.authorization.k8s.io
#这段YAML文件定义了在Kubernetes中创建一个Service Account以及相关的ClusterRole和ClusterRoleBinding来管理NFS Provisioner的权限。通过这些定义,可以确保NFS Provisioner在Kubernetes集群中具有适当的权限,以管理PV、PVC和StorageClasses等资源。
kubectl apply -f nfs-client-rbac.yaml
3.使用Deployment创建NFS Provisioner
使用Kubernetes的Deployment来部署NFS Provisioner(即nfs-client)。NFS Provisioner在Kubernetes中的作用是两个方面:一是在NFS共享目录下创建挂载点(volume),二是将Persistent Volumes(PV)与NFS的挂载点建立关联,使得Kubernetes中的应用程序能够使用NFS存储。
通过Deployment创建NFS Provisioner的实例,可以确保其在集群中始终处于运行状态,并且可以根据需要进行水平扩展。这样,Kubernetes集群中的应用程序可以方便地访问和使用NFS存储,而无需手动管理PV和NFS之间的关联关系。
由于 1.20 版本启用了 selfLink,所以 k8s 1.20+ 版本通过 nfs provisioner 动态生成pv会报错,解决方法如下:
# 修改kube-apiserver.yaml文件,设置kube-apiserver的参数
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --feature-gates=RemoveSelfLink=false # 添加这一行,开启RemoveSelfLink特性
- --advertise-address=192.168.241.11 # 设置kube-apiserver的广告地址
......
# 应用kube-apiserver.yaml文件的更改
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
# 删除kube-apiserver的Pod以便更改生效
kubectl delete pods kube-apiserver -n kube-system
# 检查kube-apiserver的Pod是否重新启动
kubectl get pods -n kube-system | grep apiserver
#这段脚本是修改 kube-apiserver.yaml 文件的步骤,其中设置了 kube-apiserver 的参数,添加了 --feature-gates=RemoveSelfLink=false 开启了 RemoveSelfLink 特性,以及设置了 --advertise-address=192.168.241.11 作为 kube-apiserver 的广告地址。然后通过 kubectl apply 应用修改,通过 kubectl delete pods 删除 kube-apiserver 的 Pod 以便更改生效,最后通过 kubectl get pods 检查 kube-apiserver 的 Pod 是否重新启动。
4.创建NFS Provisioner
# 编辑nfs-client-provisioner.yaml文件,定义NFS Provisioner的Deployment
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner # 指定ServiceAccount
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest # 使用的NFS Provisioner镜像
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes # 挂载路径
env:
- name: PROVISIONER_NAME
value: nfs-storage # Provisioner的名称
- name: NFS_SERVER
value: stor01 # NFS服务器地址
- name: NFS_PATH
value: /opt/k8s # NFS共享路径
volumes:
- name: nfs-client-root
nfs:
server: stor01 # NFS服务器地址
path: /opt/k8s # NFS共享路径
#这段 YAML 文件定义了 NFS Provisioner 的 Deployment。其中包括了指定的 Replicas 数量、选择器、部署策略等。在 Pod 模板中,指定了使用的 ServiceAccount,镜像来源,以及挂载的路径等信息。此外,还定义了 NFS 服务器地址和共享路径。
kubectl apply -f nfs-client-provisioner.yaml
kubectl get pod
5.创建StorageClass
创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
创建 StorageClass 是为了定义存储的类型以及如何提供存储服务。当用户创建 PVC(PersistentVolumeClaim)时,StorageClass 可以指导 Kubernetes 如何动态地提供 PV(PersistentVolume)。关联 PV 与 PVC 是将 PVC 绑定到满足其需求的 PV 上,从而实现 PVC 对存储资源的预定工作。这通常是通过 StorageClass 中定义的配置信息来实现的,例如指定的 Provisioner、参数等。因此,当 PVC 被创建时,Kubernetes 将使用 StorageClass 中定义的规则来选择并创建 PV,并将它们关联起来,以满足 PVC 的要求。
vim nfs-client-storageclass.yaml
# 定义一个名为 nfs-client-storageclass 的 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass # StorageClass 的名称
provisioner: nfs-storage # 使用的 Provisioner 名称,需与配置文件中的 PROVISIONER_NAME 一致
parameters:
archiveOnDelete: "false" # 在删除 PVC 时是否对数据进行存档,false 表示直接删除数据
#这个 YAML 文件定义了一个名为 nfs-client-storageclass 的 StorageClass。它指定了 NFS Provisioner 的名称为 nfs-storage,这与 Provisioner 配置文件中的环境变量 PROVISIONER_NAME 要保持一致。另外,设置了参数 archiveOnDelete: "false",表示在删除 PersistentVolumeClaim (PVC) 时不会对数据进行存档,即直接删除数据。
kubectl apply -f nfs-client-storageclass.yaml
kubectl get storageclass
6.创建PVC
vim test-pvc-pod.yaml
# 定义持久卷声明(PersistentVolumeClaim),用于请求持久卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc # 持久卷声明的名称
spec:
accessModes:
- ReadWriteMany # 访问模式设置为读写多个节点
storageClassName: nfs-client-storageclass # 关联的存储类对象
resources:
requests:
storage: 1Gi # 请求的存储容量为1Gi
---
# 定义Pod,用于使用持久卷
apiVersion: v1
kind: Pod
metadata:
name: test-storageclass-pod # Pod 的名称
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-c"
args:
- "sleep 3600" # 命令参数,让容器保持运行状态
volumeMounts:
- name: nfs-pvc # 指定挂载的持久卷名称
mountPath: /mnt # 挂载路径
restartPolicy: Never # Pod 的重启策略
volumes:
- name: nfs-pvc # 定义一个名为nfs-pvc的卷
persistentVolumeClaim:
claimName: test-nfs-pvc # 引用之前定义的持久卷声明的名称
#这个 YAML 文件定义了一个 Kubernetes Pod 和一个 PersistentVolumeClaim(持久卷声明)。Pod 使用了名为 test-nfs-pvc 的持久卷声明,请求了 1Gi 的存储空间,并使用了 nfs-client-storageclass 存储类。Pod 中的容器使用了 BusyBox 镜像,并将持久卷挂载到 /mnt 路径下。 Pod 的重启策略设置为 Never,这意味着当 Pod 退出时,不会自动重启。
kubectl apply -f test-pvc-pod.yaml
kubectl get pods,pvc,pv
7.测试
#查看 NFS 服务器上是否生成对应的目录,自动创建的 PV 会以 ${namespace}-${pvcName}-${pvName} 的目录格式放到 NFS 服务器上
ls /opt/k8s/
这里看到创建了一个PV
#master进入 Pod 在挂载目录 /mnt 下写一个文件,然后查看 NFS 服务器上是否存在该文件
kubectl exec -it test-storageclass-pod sh
/ # cd /mnt
/mnt # echo "this is cxk like ctrl" > index.html
/mnt # exit
cd /opt/k8s/
cd default-test-nfs-pvc-pvc-c3343288-6140-47ee-a44a-b93591dec9bb/
cat index.html
this is cxk like ctrl
五、总结
1.Volume
- emptyDir:可以实现Pod中的容器之间共享数据,但是存储卷不能持久化数据,且会随着Pod生命周期结束而一起删除
- hostpath:可以实现持久化存储,使用node节点的目录或文件挂载到容器,但是存储空间会收到node节点单机限制,node节点故障数据会丢失,Pod会跨节点不能共享数据
- NFS:可以实现持久化存储,使用NFS将存储设备空间挂载到容器中,Pod可以跨Node节点共享数据
2.PV和PVC
- PV 持久卷(Persistent Volumes)是集群中的一块存储资源,由管理员事先创建或由动态供应机制(如StorageClass)自动创建。Kubernetes指定的存储设备空间中创建可持久化的存储的资源。
- PVC持久卷声明(Persistent Volume Claims)是用户对存储的请求或声明,是对PV存储资源请求和绑定 ,Pod通过挂载PVC来使用PV。这种方式提供了存储的抽象和解耦,使得应用无需关心具体的存储细节。
- 当Pod销毁或重建时,与之关联的PVC仍然保留,保证了数据的持久性。
3. 静态PV的使用
- 准备存储设备和共享目录
- 创建PV资源,配置存储类型、访问模式、存储的能力大小
- 创建PVC资源并且配置请求PV资源的访问模式和存储大小,绑定PV,PVC和PV是一对一的绑定关系
- PV访问模式中必须支持PVC请求访问模式
- 请求的存储空间优先选择相等存储大小的PV资源,如果没有会选择大于请求的存储大小的PV资源
- 创建Pod资源 存储类设置PersistenVolumeClaim 在容器配置存储挂载
4. StorageClass——动态存储
- 存储类定义了存储的“类”,用于动态供应PV。管理员可以根据不同的需求(如性能、成本)定义多个存储类。
- 用户在创建PVC时可以选择一个存储类,Kubernetes会自动匹配并创建合适的PV。
- 对于存储资源,虽然不像CPU和内存那样频繁地设置请求和限制,但在使用PV/PVC时,可以通过设置存储容量的大小来间接限制使用量。
- 在Pod的YAML定义中,可以通过volumeMounts来指定容器如何挂载卷,以及是否需要设置读写权限等。
- Pod中的存储卷可以配置访问模式(如只读、读写)来确保数据的安全性。
- 对于敏感数据,推荐使用Secrets或ConfigMaps,并注意权限控制。
5.动态创建PV的过程
- 准备NFS共享服务器和共享目录
- 创建sa服务账号,进行RBAC(角色)资源操作权限的授权
- 创建NFS-Client-Provisioner 存储插件(以Pod形式运行的)配置中关联sa服务账号,使我们存储插件获得相关资源的权限(操作权限)
- 创建StorageClass资源,配置中光存储插件的名称配置
以上过程一劳永逸,以后只需创建PVC即可
- 创建PVC资源,配置中关联StorageClass的资源的名称,此时会在NFS服务器上生成相关的PV的共享目录,目录名${namespace}${PVCname}${PVname}格式命名
- 创建Pod资源存储类型,设置成PersistentVolumeClain,在容器中配置存储挂载即可