数据持久化的场景包括:
1、数据存储:许多应用程序需要保存用户生成的数据,如文件、图片、日志等。通过数据持久化,可
以确保这些数据在容器销毁或重启后仍然存在。
2、数据共享:在某些情况下,多个容器或Pod可能需要访问和共享相同的数据。通过将数据存储在
持久化卷中,可以使多个容器之间共享数据,实现数据一致性和共享访问。
3、数据备份和恢复:持久化存储解决方案通常提供数据备份和恢复机制,以防止数据丢失。这对于保
护重要数据、应对故障或恢复到先前的状态非常重要。
4、数据迁移和扩展:在Kubernetes集群中,可能需要扩展应用程序到多个节点或迁移到其他集群。
通过将数据存储在持久化卷中,可以方便地将数据与应用程序一起迁移到新的环境,无需担心数据丢失。
5、数据安全:某些行业或应用程序对数据的安全性有严格的要求。持久化存储解决方案通常提供数据
加密和访问控制功能,以确保数据在传输和存储过程中的安全性。

k8s持久化存储方案-emptyDir
k8s常用的存储如下:
emptyDir
hostPath
nfs
persistentVolumeClaim
glusterfs
cephfs
configMap
secret

在Kubernetes中,EmptyDir是一种卷(Volume),它提供了一个空目录来供容器使用。EmptyDir
卷在Pod级别上创建,与Pod的生命周期绑定。EmptyDir卷在Pod被删除或重新启动时会被清空,因
此它不是持久化的存储解决方案。

EmptyDir卷的使用场景包括:
1.临时文件共享:如果多个容器需要在同一个Pod中进行临时文件共享,EmptyDir卷是一个简便
的解决方案。容器可以将文件写入EmptyDir卷,并且其他容器可以读取和修改这些文件。当Pod
被删除或重启时,EmptyDir卷中的文件会被清空。
2.共享数据:某些应用程序可能需要在容器之间共享一些中间结果或临时数据。EmptyDir卷可以
作为容器之间的临时数据交换机制。容器可以将数据写入EmptyDir卷,其他容器可以读取和处
理这些数据,从而实现数据共享和协作。
3.缓存:EmptyDir卷可以用作容器的缓存存储。某些应用程序可能需要将频繁访问的数据缓存到
本地存储中,以提高性能。EmptyDir卷提供了一个临时的、高速的存储介质来存储缓存数据,
提供快速的读取和写入操作

当在Kubernetes中使用存储卷(Volume),需要经历以下步骤:
1.定义Pod的Volume:在Pod的配置中定义一个Volume,指定它要关联到哪个存储上。可以
使用不同类型的Volume,如EmptyDir、HostPath、PersistentVolumeClaim等,具体选
择取决于需求。
2.在容器中使用Volume Mounts:在Pod的配置中,为每个容器定义Volume Mounts,将
Volume挂载到容器内部的指定路径上。这样容器就能够访问和操作Volume中的数据。
3.通过Volume实现数据持久化和共享:一旦Volume被挂载到容器中,容器就可以将数据写入
Volume或从Volume中读取数据。这使得数据能够在容器的生命周期内持久存在,并且可以被
其他容器共享和访问。



root@ubuntu0:~/k8s/volumes# cat emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-empty
spec:
  containers:
  - name: container-empty
    image: nginx:1.23
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache #挂载到容器里的目录
      name: cache-volume
  volumes:
  - emptyDir: {}   #{}表示临时存储
    name: cache-volume
root@ubuntu0:~/k8s/volumes# kubectl apply -f emptydir.yaml 
pod/pod-empty created
root@ubuntu0:~/k8s/volumes# kubectl get all -owide
NAME            READY   STATUS    RESTARTS   AGE     IP             NODE      NOMINATED NODE   READINESS GATES
pod/pod-empty   1/1     Running   0          3m26s   10.100.2.201   ubuntu1   <none>           <none>

临时目录调度到那台机器上就去那台机器上去找


找临时目录需要先找到pod的uid
root@ubuntu0:~/k8s/volumes# kubectl get pod pod-empty -oyaml|grep uid
  uid: 524cd63d-7a20-4323-81ca-b116c9935cda
root@ubuntu0:~/k8s/volumes# 

登录调度的节点去找文件
root@ubuntu0:~/k8s/volumes# ssh ubuntu1
Last login: Sun Aug  9 10:16:43 2026 from 192.168.23.99
root@ubuntu1:~# ls /var/lib/kubelet/pods/524cd63d-7a20-4323-81ca-b116c9935cda/volumes/kubernetes.io~
kubernetes.io~empty-dir/ kubernetes.io~projected/ 
root@ubuntu1:~# ls /var/lib/kubelet/pods/524cd63d-7a20-4323-81ca-b116c9935cda/volumes/kubernetes.io~empty-dir/cache-volume/
root@ubuntu1:~# 
在临时目录创建一个文件
root@ubuntu1:~# touch /var/lib/kubelet/pods/524cd63d-7a20-4323-81ca-b116c9935cda/volumes/kubernetes.io~empty-dir/cache-volume/11
root@ubuntu1:~# 

在进入pod里面,发现里面就有了11文件
root@ubuntu0:~/k8s/volumes# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
pod-empty   1/1     Running   0          11m
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# kubectl exec -it pod-empty -- bash
root@pod-empty:/# 
root@pod-empty:/# 
root@pod-empty:/# ls /cache/
11
root@pod-empty:/# 

把pod删除了,pod就不在了
root@ubuntu0:~/k8s/volumes# kubectl delete -f emptydir.yaml 
pod "pod-empty" deleted
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# ssh ubuntu1
Last login: Sun Aug  9 10:23:59 2026 from 192.168.23.99
root@ubuntu1:~# ls /var/lib/kubelet/pods/524cd63d-7a20-4323-81ca-b116c9935cda/volumes/kubernetes.io~empty-dir/cache-volume/
ls: cannot access '/var/lib/kubelet/pods/524cd63d-7a20-4323-81ca-b116c9935cda/volumes/kubernetes.io~empty-dir/cache-volume/': No such file or directory
root@ubuntu1:~# 

k8s持久化存储方案-hostPath
hostPath是Kubernetes中的一种卷类型,它将主机节点上的文件或目录挂载到容器中。使用
hostPath,可以将主机节点上的文件系统路径直接映射到容器的文件系统中。这种方式在某些情况下非常
有用,但也需要谨慎使用,因为它具有一些潜在的限制和风险。

以下是hostPath的一些关键特点和适用场景:
1.直接访问主机文件系统:hostPath卷允许容器直接访问主机节点上的文件系统。这对于需要访
问主机节点上的特定文件或目录的应用程序非常有用。例如,某些日志收集器可能需要访问主机
上的日志文件。
2.主机依赖性:hostPath卷的挂载是与特定主机节点紧密关联的,因此在调度Pod时需要特别
注意。如果Pod被调度到另一个主机节点上,它将无法访问之前挂载的主机文件系统。
3.危险性:hostPath卷的使用需要谨慎,因为容器可以访问主机节点上的任何文件或目录,包括
敏感的系统文件。此外,如果多个Pod使用相同的hostPath卷并且并发写入同一个文件,可
能会导致冲突和数据损坏。
4.开发和测试环境:hostPath卷特别适用于开发和测试环境,因为它可以方便地将主机节点上的
文件或目录映射到容器中,从而加快开发和测试工作流程。

需要注意的是,hostPath卷并不适合生产环境中的大多数用例。在生产环境中,建议使用更可靠和
弹性的持久化存储方案,例如网络存储卷(NFS)、云提供商的块存储或对象存储等。


root@ubuntu0:~/k8s/volumes# cat hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  containers:
  - image: nginx:1.23
    imagePullPolicy: IfNotPresent
    name: test-nginx
    volumeMounts: 
    - mountPath: /test-nginx
      name: test-volume
  - image: tomcat:8.5-jre8-alpine 
    imagePullPolicy: IfNotPresent
    name: test-tomcat
    volumeMounts:
    - mountPath: /test-tomcat
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data1
      type: DirectoryOrCreate
root@ubuntu0:~/k8s/volumes# kubectl apply -f hostpath.yaml 
pod/test-hostpath created
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# 
root@ubuntu0:~/k8s/volumes# kubectl get pod -owid
error: unable to match a printer suitable for the output format "wid", allowed formats are: custom-columns,custom-columns-file,go-template,go-template-file,json,jsonpath,jsonpath-as-json,jsonpath-file,name,template,templatefile,wide,yaml
root@ubuntu0:~/k8s/volumes# kubectl get pod -owide
NAME            READY   STATUS    RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
test-hostpath   2/2     Running   0          7s    10.100.2.202   ubuntu1   <none>           <none>
root@ubuntu0:~/k8s/volumes# 

他调度到ubuntu1   上,此时ubuntu1就有这个目录
root@ubuntu1:~# ls /data1/
root@ubuntu1:~# 
创建数据
root@ubuntu1:~# touch /data1/111
进入到容器里面发现就有了
root@ubuntu0:~/k8s/volumes# kubectl exec -it test-hostpath -c test-tomcat -- bash
bash-4.4# 
bash-4.4# 
bash-4.4# ls /
.dockerenv   dev/         home/        media/       opt/         root/        sbin/        sys/         tmp/         var/         
bin/         etc/         lib/         mnt/         proc/        run/         srv/         test-tomcat/ usr/         
bash-4.4# ls /test-tomcat/
111
bash-4.4# 

hostpath存储卷缺点:
单节点
pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失

在这里插入图片描述

k8s持久化存储方案-NFS

NFS(Network File System)是一种网络文件系统协议,它允许不同计算机之间共享文件和目录。
在Kubernetes(k8s)中,NFS是一种常见的持久化存储方案,用于将网络共享的存储卷挂载到容器中。

下面是NFS的基本介绍和常见应用场景:
1.基本原理:NFS允许将存储资源(文件或目录)通过网络共享给其他计算机。NFS服务器将存
储资源公开为共享,并将其挂载到客户端计算机上。客户端可以像访问本地文件系统一样访问这
些共享资源。
2.持久化存储方案:在Kubernetes中,NFS可以作为持久化存储方案使用。它可以提供可靠的
存储,并在容器被重新调度到不同的节点时保持数据的一致性。
3.分布式访问:NFS允许多个客户端同时访问共享资源。这使得它非常适合那些需要多个容器或
Pod共享数据的场景,例如数据库系统或分布式文件共享。
4.跨平台兼容性:NFS是一种跨平台的文件系统协议,支持在不同操作系统之间进行文件共享。这
使得它成为在混合操作系统集群中实现持久化存储的理想选择。
5.灵活性:NFS提供了对存储资源的灵活访问和管理。管理员可以根据需求创建和配置NFS服务
器,设置共享权限以及实施访问控制策略。
6.备份和恢复:NFS具备备份和恢复数据的能力。通过使用备份工具和策略,可以对NFS共享的
数据进行定期备份,以防止数据丢失或损坏。


常见的应用场景包括:
•数据库持久化:NFS可用于挂载数据库文件,确保数据库的持久性和数据一致性,并提供跨多个
数据库节点的共享访问。
•分布式文件共享:多个容器或Pod可以通过挂载相同的NFS共享来实现文件共享和协作,如
共享配置文件、日志目录等。
•文件存储和共享:NFS可以用作共享存储,供团队成员或应用程序之间共享文件,便于协作和数
据交换。

总结起来,NFS是一种在Kubernetes中常用的持久化存储方案,可以提供可靠的存储和跨多个容
器或Pod的文件共享。它具有跨平台兼容性、灵活性和备份恢复能力等






1、搭建nfs服务
以k8s的控制节点作为NFS服务端
root@ubuntu0:~/k8s/volumes# apt install  nfs-server
2.创建NFS需要的共享目录
root@ubuntu0:~#  mkdir /data/volumes-pv
3.配置nfs共享服务器上的/data/volumes目录
root@ubuntu0:~# cat /etc/exports 
# /etc/exports: the access control list for filesystems which may be exported
#		to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/data/volumes *(rw,no_root_squash) 
#no_root_squash:用户具有根目录的完全管理访问权限

启动nfs
root@ubuntu0:~# exportfs -arv
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volumes".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [2]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volume_test/v1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [3]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volume_test/v2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [4]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/nfs_pro".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [5]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/jenkins/v1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [6]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/jenkins/v2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exporting *:/data/jenkins/v2
exporting *:/data/jenkins/v1
exporting *:/data/nfs_pro
exporting *:/data/volume_test/v2
exporting *:/data/volume_test/v1
exporting *:/data/volumes
root@ubuntu0:~# 

查看共享的目录
root@ubuntu1:~# showmount -e 192.168.23.99
Export list for 192.168.23.99:
/data/jenkins/v2     *
/data/jenkins/v1     *
/data/nfs_pro        *
/data/volume_test/v2 *
/data/volume_test/v1 *
/data/volumes        *

查看是否能挂载上
root@ubuntu1:~# mkdir /data2
root@ubuntu1:~# mount -t nfs 192.168.23.99:/data/volumes /data2
root@ubuntu1:~# 
root@ubuntu1:~# 
root@ubuntu1:~# df -h|grep data2
192.168.23.99:/data/volumes         48G   26G   19G  58% /data2
root@ubuntu1:~# 

卸载
 umount /data2/

#创建Pod,挂载NFS共享出来的目录
root@ubuntu0:~/k8s/volumes# cat nfs.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-nfs-volume
spec:
  containers:
  - name: test-nfs
    image: nginx:1.23
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      protocol: TCP
    volumeMounts:
    - name: nfs-volumes
      mountPath: /usr/share/nginx/html   #nfs目录
  volumes:
  - name: nfs-volumes
    nfs:
      path: /data/volumes
      server: 192.168.23.99
root@ubuntu0:~/k8s/volumes# kubectl apply -f nfs.yaml 
pod/test-nfs-volume created
root@ubuntu0:~/k8s/volumes# kubectl get pod -owide
NAME              READY   STATUS    RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
test-hostpath     2/2     Running   0          27h   10.100.2.202   ubuntu1   <none>           <none>
test-nfs-volume   1/1     Running   0          5s    10.100.2.204   ubuntu1   <none>           <none>

往宿主机写一点东西
root@ubuntu0:/data/volumes# 
root@ubuntu0:/data/volumes# cat /data/volumes/index.html 
hhhh
test-nfs-volume   1/1     Running   0          5s    10.100.2.204   ubuntu1   <none>           <none>

进入容器查看
root@ubuntu0:~/k8s/volumes# kubectl exec -it test-nfs-volume -- bash
root@test-nfs-volume:/# cd /usr/share/nginx/html/
root@test-nfs-volume:/usr/share/nginx/html# ls
index.html
访问测试
root@ubuntu0:/data/volumes# curl 10.100.2.204
hhhh
root@ubuntu0:/data/volumes# 

查看容器内的挂载
root@ubuntu0:/data/volumes# kubectl exec -it test-nfs-volume -- bash
root@test-nfs-volume:/# df -h
Filesystem                         Size  Used Avail Use% Mounted on
overlay                             48G   17G   29G  37% /
tmpfs                               64M     0   64M   0% /dev
/dev/mapper/ubuntu--vg-ubuntu--lv   48G   17G   29G  37% /etc/hosts
shm                                 64M     0   64M   0% /dev/shm
192.168.23.99:/data/volumes         48G   26G   20G  58% /usr/share/nginx/html
tmpfs                              8.9G   12K  8.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                              4.5G     0  4.5G   0% /proc/acpi
tmpfs                              4.5G     0  4.5G   0% /proc/scsi
tmpfs                              4.5G     0  4.5G   0% /sys/firmware


pv、pvc
K8sPV是什么?
PersistentVolume(PV):PV是集群中的存储资源,可以是物理存储设备、网络存储或云存储等。
PV独立于Pod存在,它们是集群级别的资源,由集群管理员进行配置和管理。PV具有持久性,即使Pod
被删除,PV中的数据也会保留。PV定义了存储的容量、访问模式和其他属性。

PersistentVolumeClaim(PVC):PVC是Pod对PV的申请,它表示Pod需要一定的存储资源来
满足其持久化存储需求。PVC在Pod和PV之间建立了一个抽象层,使得Pod无需关心底层存储的具体
细节。PVC定义了Pod对存储的需求,包括存储容量、访问模式等。



K8sPVC和PV工作原理
当创建一个PersistentVolume(PV)和PersistentVolumeClaim(PVC)时,它们之间的相互作
用和工作原理如下:
1.PV的供应方式:
•静态配置:集群管理员预先创建PV对象,包含了实际存储资源的详细信息。这些PV
存在于Kubernetes API中,供用户使用。
•动态配置:当静态PV无法匹配用户的PVC时,Kubernetes可以尝试为PVC动态地
配置PV。这基于StorageClasses,PVC必须请求存储类,并且管理员必须创建和配
置该类以进行动态配置。

2.绑定:
•用户创建PVC并指定所需的存储资源和访问模式。
•在找到可用的PV之前,PVC保持未绑定状态。

3.使用:
•首先,存储管理员创建PV,并将其划分为多个存储卷。
•用户在创建Pod之前创建PVC,并指定所需的PV大小和访问模式。
•创建PVC后,可以将其作为存储卷使用,并在Pod定义中引用该PVC。
•PV和PVC是一对一的关系。一旦PV被某个PVC绑定,其他PVC就不能使用它。
•如果没有合适的PV可用,PVC将处于挂起状态,直到有一个合适的PV可用为止。


4.回收策略:
•当删除使用PVC作为存储卷的Pod时,PVC与PV的绑定将解除。
•PV有不同的回收策略可供选择:
•Retain(保留):删除PVC后,PV保留,并且数据仍然存在。PV不会被绑
定到其他PVC上,可以再次使用。
•Recycle(回收,不推荐):删除PVC后,PV会被清空数据并准备重新使用。
这个回收策略在Kubernetes 1.15版本后被废弃。
•Delete(删除):删除PVC后,PV也会从Kubernetes中移除,并且相关
的存储资源也会被删除。


创建目录
root@ubuntu0:/data/volumes#  mkdir /data/volume_test/v{1,2} -p
root@ubuntu0:/data/volumes# cat /etc/exports      
# /etc/exports: the access control list for filesystems which may be exported
#		to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/data/volumes *(rw,no_root_squash) 
/data/volume_test/v1 *(rw,no_root_squash) 
/data/volume_test/v2 *(rw,no_root_squash) 

让配置生效
root@ubuntu0:/data/volumes# exportfs -arv
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volumes".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [2]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volume_test/v1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [3]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volume_test/v2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [4]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/nfs_pro".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [5]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/jenkins/v1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [6]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/jenkins/v2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exporting *:/data/jenkins/v2
exporting *:/data/jenkins/v1
exporting *:/data/nfs_pro
exporting *:/data/volume_test/v2
exporting *:/data/volume_test/v1
exporting *:/data/volumes



#查看定义nfs类型的pv需要的字段
root@ubuntu0:/data/volumes#  kubectl explain pv.spec.nfs
KIND:     PersistentVolume
VERSION:  v1

RESOURCE: nfs <Object>

DESCRIPTION:
     NFS represents an NFS mount on the host. Provisioned by an admin. More
     info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

     Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do
     not support ownership management or SELinux relabeling.

FIELDS:
   path	<string> -required-
     Path that is exported by the NFS server. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#nfs

   readOnly	<boolean>
     ReadOnly here will force the NFS export to be mounted with read-only
     permissions. Defaults to false. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#nfs

   server	<string> -required-
     Server is the hostname or IP address of the NFS server. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#nfs




root@ubuntu0:~/k8s/pv# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: v1
  labels:
    app: v1
spec:
  capacity:
    storage: 1Gi #pv的存储空间容量
  accessModes: ["ReadWriteOnce"]
  nfs:
    path: /data/volume_test/v1 #把nfs的存储空间创建成pv
    server: 192.168.23.99
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: v2
  labels:
    app: v2
spec:
  capacity:
    storage: 2Gi
  accessModes: ["ReadWriteMany"]
  nfs:
    path: /data/volume_test/v2 
    server: 192.168.23.99

root@ubuntu0:~/k8s/pv# kubectl apply -f pv.yaml 
persistentvolume/v1 created
persistentvolume/v2 created
root@ubuntu0:~/k8s/pv# 
root@ubuntu0:~/k8s/pv# 
root@ubuntu0:~/k8s/pv# kubectl get pv --show-labels
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   LABELS
v1     1Gi        RWO            Retain           Available                                   7s    app=v1
v2     2Gi        RWX            Retain           Available                                   7s    app=v2


创建pvc
root@ubuntu0:~/k8s/pv# cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  selector:
    matchLabels:
      app: v2   #根据标签和策略去找
  accessModes: ["ReadWriteMany"]  #策略必须和pv的保持一致
  resources:
    requests:
      storage: 2Gi
root@ubuntu0:~/k8s/pv# kubectl apply -f pvc.yaml 
persistentvolumeclaim/my-pvc created
root@ubuntu0:~/k8s/pv# kubectl get pv.pvc
error: the server doesn't have a resource type "pv"
root@ubuntu0:~/k8s/pv# kubectl get pv,pvc
NAME                  CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/v1   1Gi        RWO            Retain           Available                                            68s
persistentvolume/v2   2Gi        RWX            Retain           Bound       default/my-pvc                           68s

NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/my-pvc   Bound    v2       2Gi        RWX                           10s
root@ubuntu0:~/k8s/pv# 

编写pod,把pvc挂载到pod里面
root@ubuntu0:~/k8s/pv# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-pvc
spec:
  containers:
  - name: nginx
    image: nginx:1.23
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: nginx-html
      mountPath: /usr/share/nginx/html/  #容器内部的目录
  volumes:
  - name: nginx-html
    persistentVolumeClaim:
      claimName: my-pvc   #pvc的名称
root@ubuntu0:~/k8s/pv# kubectl apply -f pod.yaml 
pod/pod-pvc created
root@ubuntu0:~/k8s/pv# 
root@ubuntu0:~/k8s/pv# 
root@ubuntu0:~/k8s/pv# kubectl get pod -owide
NAME              READY   STATUS    RESTARTS   AGE    IP             NODE      NOMINATED NODE   READINESS GATES
pod-pvc           1/1     Running   0          11s    10.100.2.205   ubuntu1   <none>           <none>
test-hostpath     2/2     Running   0          2d4h   10.100.2.202   ubuntu1   <none>           <none>
test-nfs-volume   1/1     Running   0          24h    10.100.2.204   ubuntu1   <none>           <none>


在共享目录创建
root@ubuntu0:~/k8s/pv# ls /data/volume_test/v2/index.html
ls: cannot access '/data/volume_test/v2/index.html': No such file or directory
root@ubuntu0:~/k8s/pv# ls /data/volume_test/v2/config/   
gitlab-secrets.json       ssh_host_ecdsa_key        ssh_host_ed25519_key      ssh_host_rsa_key          trusted-certs/            
gitlab.rb                 ssh_host_ecdsa_key.pub    ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub      
root@ubuntu0:~/k8s/pv# ls /data/volume_test/v2/config/
gitlab-secrets.json  ssh_host_ecdsa_key      ssh_host_ed25519_key      ssh_host_rsa_key      trusted-certs
gitlab.rb            ssh_host_ecdsa_key.pub  ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub
root@ubuntu0:~/k8s/pv# 
进入容器查看 
root@ubuntu0:~/k8s/pv# kubectl exec -it pod-pvc -- bash
root@pod-pvc:/# ls /usr/share/nginx/html/
config
root@pod-pvc:/# ls /usr/share/nginx/html/config/
gitlab-secrets.json       ssh_host_ecdsa_key        ssh_host_ed25519_key      ssh_host_rsa_key          trusted-certs/            
gitlab.rb                 ssh_host_ecdsa_key.pub    ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub      

storageclass
Kubernetes提供了StorageClass来自动创建PV,以减轻管理员的维护成本。以下是关于
Kubernetes PV、PVC和StorageClass的更新内容:
PV(PersistentVolume)是Kubernetes中的持久化存储资源,而PVC(PersistentVolumeClaim)
是Pod对PV的申请。传统的PV和PVC模式需要管理员预先创建PV,然后将其与PVC进行一对一的
绑定。这种方式在大规模部署中可能导致管理复杂性和维护成本的增加。


为了解决这个问题,Kubernetes引入了StorageClass机制。StorageClass是一种动态创建PV的模板。
集群管理员可以创建多个StorageClass,每个StorageClass定义了存储的类型、访问模式和其他属性。

当用户创建一个PVC并指定StorageClass时,Kubernetes会自动根据该StorageClass创建一个PV,
并将其与PVC进行绑定。这样,管理员无需手动创建PV,而是根据StorageClass的定义,动态生成PV
来满足用户的存储需求。


StorageClass提供了以下好处:
1.简化管理:StorageClass允许管理员创建一组可重用的存储配置模板,而无需为每个PVC手动
创建和管理PV。这降低了管理成本和复杂性。
2.动态供应:使用StorageClass,管理员可以根据需求动态创建PV,从而自动为PVC提供存储
资源。这种动态供应的机制使得存储的分配更加灵活和自动化。
3.可选性和灵活性:StorageClass允许管理员根据存储的不同特性和需求创建不同的
StorageClass。用户可以根据自己的需求选择合适的StorageClass,并使用相应的存储资源。

总之,StorageClass是Kubernetes中用于自动创建PV的机制。它简化了PV和PVC的管理,并
提供了动态供应的能力,以适应不同的存储需求。这样,管理员可以更轻松地管理存储资源,而用户则可
以更方便地申请和使用存储卷。


查看storageclass资源
root@ubuntu0:~/k8s/pv#  kubectl explain storageclass
KIND:     StorageClass
VERSION:  storage.k8s.io/v1

DESCRIPTION:
     StorageClass describes the parameters for a class of storage for which
     PersistentVolumes can be dynamically provisioned.

     StorageClasses are non-namespaced; the name of the storage class according
     to etcd is in ObjectMeta.Name.

FIELDS:
   allowVolumeExpansion	<boolean>
     AllowVolumeExpansion shows whether the storage class allow volume expand

   allowedTopologies	<[]Object>
     Restrict the node topologies where volumes can be dynamically provisioned.
     Each volume plugin defines its own supported topology specifications. An
     empty TopologySelectorTerm list means there is no topology restriction.
     This field is only honored by servers that enable the VolumeScheduling
     feature.

   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   mountOptions	<[]string>
     Dynamically provisioned PersistentVolumes of this storage class are created
     with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the
     PVs will simply fail if one is invalid.

   parameters	<map[string]string>
     Parameters holds the parameters for the provisioner that should create
     volumes of this storage class.

   provisioner	<string> -required-
     Provisioner indicates the type of the provisioner.

provisioner:供应商,storageclass需要有一个供应者,用来确定我们使用什么样的存储来创建
pv,常见的provisioner如下
allowVolumeExpansion:允许卷扩展,PersistentVolume可以配置成可扩展。将此功能设置为true时,允许用户通过编辑相应的PVC对象来调整卷大小。当基础存储类的allowVolumeExpansion
字段设置为true时,以下类型的卷支持卷扩展。



存储制备器 
每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。
https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

在这里插入图片描述
在这里插入图片描述





更多推荐