【云原生-Kurbernetes篇】K8s的存储卷/数据卷+PV与PVC
这是一个目录标题
- 一、Kurbernetes中的存储卷
- 1.1 为什么需要存储卷?
- 1.2 存储卷概述
- 1.2.1 简介
- 1.2.2 volume字段
- 1.3 常用的存储卷类型
- 1.3.1 emptyDir(临时存储卷)
- 1.3.2 hostPath(节点存储卷)
- 1.3.3 nfs
- 1.3.4 cephfs
- 二、持久数据卷——PV和PVC
- 2.1 概念
- 2.2 PV的生命周期和状态
- 2.3 访问模式 (Access Modes) 和回收策略 (Reclaim Policy)
- 三、静态创建PV
- 3.1 创建思路
- 3.2 创建实例:NFS使用PV和PVC
- Step1 配置nfs存储
- Step2 定义PV
- Step3 定义PVC
- Step4 访问测试
- 四、动态创建PV
- 4.1 创建思路
- 4.2 StorageClass的概念
- 4.3 Provisioner的概念
- 4.4 实例:NFS 的动态 PV 创建
- Step1 在master01节点上安装nfs,并配置nfs服务
- Step2 创建 Service Account
- Step3 使用 Deployment 创建 NFS Provisioner
- 补充:报错解决方法
- Step4 创建 StorageClass
- Step5 创建 PVC ,进行Pod 测试
- 五、小结
- 5.1 PV、PVC的概念和状态
- 5.2 静态和动态创建PV的思路
一、Kurbernetes中的存储卷
1.1 为什么需要存储卷?
容器部署过程中一般有以下三种数据:
• 启动时需要的初始数据:例如配置文件 (init container)
• 启动过程中产生的临时数据:该临时数据需要多个容器间共享
• 启动过程中产生的持久化数据:例如MySQL的data目录 (业务数据–很重要)
而容器中的文件在磁盘上是临时存放的,这给容器中运行比较重要的应用程序带来一些问题
问题1: 数据持久化问题,当容器升级或者崩溃时,kubelet会重建容器,容器内文件会丢失。
问题2: 数据共享问题,一个Pod中运行多个容器并需要共享文件。
Kubernetes中的数据卷(Volume),也可以称为存储卷,能够解决这两个问题。
1.2 存储卷概述
1.2.1 简介
存储卷是用于持久化存储容器中数据的一种机制,可以提供容器内持久化存储的能力,使容器可以在不同的生命周期中保留数据。
数据卷与容器相互独立,并且具有自己的生命周期。
当容器被销毁或重启时,数据卷的内容仍然保持不变,从而确保了容器内数据的持久性(解决了问题1)。
数据卷可以与一个或多个容器进行绑定,使它们可以共享数据(解决了问题2)。
1.2.2 volume字段
Kubernetes中的Volume提供了在容器中挂载外部存储的能力
Pod需要设置卷来源(volume
)和挂载点(volumeMounts
)两个信息后才可以使用相应的Volume。
kubectl explain pod.spec.volumes
常用字段名 | 描述 |
---|---|
name | 指定数据卷的名称,用于标识该数据卷 |
<不同类型的数据卷> | Kubernetes 支持不同类型的数据卷,如 NFS、GCE Persistent Disk、AWS EBS等,用于满足特定的存储需求 |
kubectl explain pod.spec.containers.volumeMounts
常用字段名 | 描述 |
---|---|
name | 指定要挂载的数据卷的名称 |
mountPath | 指定挂载点的路径,即将数据卷挂载到容器内的哪个目录 |
readOnly | 指定挂载点是否为只读模式。如果设置为 true ,则容器只能读取挂载的数据,不能写入 |
1.3 常用的存储卷类型
1.3.1 emptyDir(临时存储卷)
简介
emptyDir
卷可实现Pod中的容器之间共享目录数据,但没有持久化数据的能力,存储卷会随着Pod生命周期结束而一起删除。
emptyDir`的一些用途
- 缓存空间,例如基于磁盘的归并排序。
- 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
- 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
字段
kubectl explain pod.spec.volumes.emptyDir
emptyDir.medium
字段用于控制 emptyDir
卷的存储位置,有两个值:Memory
和Default
。
值 | 描述 |
---|---|
Memory | 表示将 emptyDir 卷存储在主机的内存中数据只存在于 Pod 的生命周期内,并且不会被持久化到磁盘上 |
Default | 表示将 emptyDir 卷存储在主机的磁盘中数据会在 Pod 重新启动时保留,但不会在节点之间持久化 |
emptyDir.sizeLimit
字段用于来限制卷的容量大小,但是不会自动调整底层存储的大小。
因此,如果设置的大小限制超过节点上的可用磁盘空间,可能会导致 Pod 失败启动或运行时出现错误。
emptyDir 配置示例
apiVersion: v1
kind: Pod
metadata:name: test-pd
spec:containers:- image: registry.k8s.io/test-webservername: test-containervolumeMounts:- mountPath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir:sizeLimit: 500Mi
1.3.2 hostPath(节点存储卷)
hostPath
卷将node节点上的目录/文件挂载到Pod容器的指定目录上。
有持久化数据的能力,但只能在单个node节点上持久化数据,不能实现跨node节点的Pod共享数据
hostPath卷配置示例
apiVersion: v1
kind: Pod
metadata:name: test-pd
spec:containers:- image: registry.k8s.io/test-webservername: test-containervolumeMounts:- mountPath: /test-pdname: test-volumevolumes:- name: test-volumehostPath:# 宿主机上目录位置path: /data# 此字段为可选type: Directory
支持的 type
值如下:
取值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。 |
Directory | 在给定路径上必须存在的目录。 |
FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。 |
File | 在给定路径上必须存在的文件。 |
Socket | 在给定路径上必须存在的 UNIX 套接字。 |
CharDevice | 在给定路径上必须存在的字符设备。 |
BlockDevice | 在给定路径上必须存在的块设备。 |
补充:FileOrCreate模式
FileOrCreate
模式不会负责创建文件的父目录。
如果欲挂载的文件的父目录不存在,Pod 启动会失败。
为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载,如 FileOrCreate
配置所示。
apiVersion: v1
kind: Pod
metadata:name: test-webserver
spec:containers:- name: test-webserverimage: registry.k8s.io/test-webserver:latestvolumeMounts:- mountPath: /var/local/aaaname: mydir- mountPath: /var/local/aaa/1.txtname: myfilevolumes:- name: mydirhostPath:# 确保文件所在目录成功创建。path: /var/local/aaatype: DirectoryOrCreate- name: myfilehostPath:path: /var/local/aaa/1.txttype: FileOrCreate
1.3.3 nfs
nfs
卷使用nfs服务将存储卷挂载到Pod容器的指定目录上。
有持久化数据的能力,且也能实现跨node节点的Pod共享数据。
nfs卷的配置示例
apiVersion: v1
kind: Pod
metadata:name: test-pd
spec:containers:- image: registry.k8s.io/test-webservername: test-containervolumeMounts:- mountPath: /my-nfs-dataname: test-volumevolumes:- name: test-volumenfs:server: my-nfs-server.example.compath: /my-nfs-volumereadOnly: true
注意:不能在 Pod spec 中指定 NFS 挂载可选项。
可以选择设置服务端的挂载可选项,或者使用 /etc/nfsmount.conf。
此外,还可以通过允许设置挂载可选项的持久卷挂载 NFS 卷。
1.3.4 cephfs
cephfs
卷允许将现存的 CephFS 卷挂载到 Pod 中。
cephfs
卷可以被预先填充数据,且这些数据可以在 Pod 之间共享,同一 cephfs
卷可同时被多个挂载。
apiVersion: v1
kind: Pod
metadata:name: cephfs
spec:containers:- name: cephfs-rwimage: kubernetes/pausevolumeMounts:- mountPath: "/mnt/cephfs"name: cephfsvolumes:- name: cephfscephfs:monitors:- 10.16.154.78:6789- 10.16.154.82:6789- 10.16.154.83:6789# by default the path is /, but you can override and mount a specific path of the filesystem by using the path attribute# path: /some/path/in/side/cephfsuser: adminsecretFile: "/etc/ceph/admin.secret"readOnly: true
二、持久数据卷——PV和PVC
2.1 概念
持久卷(PersistentVolume,PV):K8S在指定的存储设备空间中逻辑划分创建出来的可持久化的存储资源对象。
持久卷声明(PersistentVolumeClaim,PVC):对PV存储资源对象的请求和绑定,也是Pod能够挂载使用的一种存储卷类型。
2.2 PV的生命周期和状态
生命周期
#PV和PVC之间的相互作用遵循这个生命周期
Provisioning(配置)---> Binding(绑定)---> Using(使用)---> Releasing(释放) ---> Recycling(回收)
生命周期 | 描述 |
---|---|
Provisioning | PV 的创建,可以直接创建 PV(静态方式),也可以使用StorageClass 动态创建 |
Binding | 将 PV 分配给 PVC |
Using | Pod 通过 PVC 使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC |
Releasing | Pod 释放 Volume 并删除 PVC |
Reclaiming | 回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除 |
状态
PV的状态 | 描述 |
---|---|
Available(可用) | 表示为可用状态,PV已经被创建出来了,但是还未被PVC绑定 |
Bound(已绑定) | 表示PV已经被PVC绑定了,PV与PVC是一对一的绑定关系 |
Released(已释放) | 表示PVC被删除了,但是PV还没被回收 |
Failed(失败) | 表示PV被自动回收失败 |
2.3 访问模式 (Access Modes) 和回收策略 (Reclaim Policy)
访问模式
存储卷在挂载到宿主机系统上时,可以设置不同的访问模式 (Access Modes)。
支持的访问模式 | 描述 |
---|---|
ReadWriteOnce (RWO) | 读写权限,并且只能被单个Node挂载 |
ReadOnlyMany (ROX) | 只读权限,允许被多个Node挂载 |
ReadWriteMany(RWX) | 读写权限,允许被多个Node挂载 |
回收策略
通过PV定义中的persistentVolumeReclaimPolicy字段
进行设置。
回收策略 | 描述 |
---|---|
Retain(保留) | 保留数据,需要手工处理 |
Recycle(回收) | 简单清除文件的操作(例如运行rm -rf /thevolume/*命令),只有 NFS 和 HostPath 两种类型的 PV支持 Recycle 策略 |
Delete(删除) | 与PV相连的后端存储完成Volume的删除操作,AWSElasticBlockStore、 GCEPersistentDis、 AzureDisk和Cinder类型的PV支持 Delete策略 |
三、静态创建PV
3.1 创建思路
1)准备好存储设备和共享目录;
2)准备yaml配置文件创建PV资源,设置 存储类型、访问模式(RWO RWX ROX RWOP)、 空间大小、回收策略(Retain Delete Recycle) 、storageClassName
等;
3)准备yaml配置文件创建PVC资源,设置 访问模式(必要条件,必须是PV能支持的访问模式)、空间大小(默认就近选择大于等于指定大小的PV) 、storageClassName
等来绑定PV;
4)创建Pod资源挂载PVC存储卷,设置存储卷类型为 persistentVolumeClaim
,并在容器配置中定义存储卷挂载点目录。
3.2 创建实例:NFS使用PV和PVC
Step1 配置nfs存储
#创建共享目录
mkdir /opt/test
cd /opt/test
mkdir v{1,2,3,4,5}
#定义多个共享目录和对应的访问权限
vim /etc/exports/opt/test/v1 192.168.2.0/24(rw,no_root_squash)
/opt/test/v2 192.168.2.0/24(rw,no_root_squash)
/opt/test/v3 192.168.2.0/24(rw,no_root_squash)
/opt/test/v4 192.168.2.0/24(rw,no_root_squash)
/opt/test/v5 192.168.2.0/24(rw,no_root_squash)
#重新加载共享目录,应用修改
exportfs -arvshowmount -e
Step2 定义PV
#这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小。
vim pv-demo.yamlapiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /opt/test/v1server: master01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv002labels:name: pv002
spec:nfs:path: /opt/test/v2server: master01accessModes: ["ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv003labels:name: pv003
spec:nfs:path: /opt/test/v3server: master01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv004labels:name: pv004
spec:nfs:path: /opt/test/v4server: master01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv005labels:name: pv005
spec:nfs:path: /opt/test/v5server: master01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 5Gi
kubectl apply -f pv-demo.yaml -n my-ns
kubectl get pv -n my-ns
Step3 定义PVC
这里定义了pvc的访问模式为多路读写,该访问模式必须在前面pv定义的访问模式之中。
定义PVC申请的大小为2Gi,此时PVC会自动去匹配多路读写且大小为2Gi的PV,匹配成功获取PVC的状态即为Bound
。
vim pod-vol-pvc.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mypvcnamespace: my-ns
spec:accessModes: ["ReadWriteMany"]resources:requests:storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:name: pod-vol-pvcnamespace: my-ns
spec:containers:- name: myappimage: nginxvolumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:claimName: mypvc
kubectl apply -f pod-vol-pvc.yamlkubectl get pv
kubectl get pvc
Step4 访问测试
在存储服务器上创建index.html,并写入数据,通过访问Pod进行查看,可以获取到相应的页面。
#创建测试页面
cd /opt/test/v3/
echo "welcome to use pv3" > index.html
kubectl get pods -o wide -n my-ns
#访问测试
firefox http://10.244.2.82
四、动态创建PV
4.1 创建思路
1)准备好存储设备和共享目录;
2)如果是外置存储卷插件,需要先创建serviceaccount账户(Pod使用的账户)和做RBAC授权(创建角色授予相关资源对象的操作权限,再将账户与角色进行绑定),使sa账户具有对PV PVC StorageClass等资源的操作权限;
3)准备yaml配置文件创建外置存储卷插件的Pod,设置sa账户作为Pod的用户,并设置相关的环境变量(比如存储卷插件名称);
4)创建StorageClass(简称SC)资源,provisioner自动设置为存储卷插件名称 ;
以上操作是一劳永逸的,之后只需要创建PVC资源时引用StorageClass就可以自动调用存储卷插件动态创建PV资源了
5)准备yaml配置文件创建PVC资源,设置 访问模式、空间大小 storageClassName指定SC资源名称等来动态创建PV资源并绑定PV;
6)创建Pod资源挂载PVC存储卷,设置存储卷类型为 persistentVolumeClaim ,并在容器配置中定义存储卷挂载点目录。
4.2 StorageClass的概念
官方文档:存储类 | Kubernetes
简介
存储类(Storage Class) 是 Kubernetes 中用于定义持久卷(Persistent Volume)的类型和行为的对象。
它定义了动态分配的存储和卷的属性,并指定如何创建和管理这些存储资源。
关于默认的StorageClass
当一个 PVC 没有指定 storageClassName
时,会使用默认的 StorageClass。
集群中只能有一个默认的 StorageClass。
如果不小心设置了多个默认的 StorageClass, 当 PVC 动态配置时,将使用最新设置的默认 StorageClass。
关于字段
每个 StorageClass 都包含 provisioner
、parameters
和 reclaimPolicy
字段, 这些字段会在 StorageClass 需要动态制备 PersistentVolume 时会使用到。
功能
1)提供动态卷配置:存储类可以与动态卷配置程序(比如 CSI 驱动程序)集成,以便在创建 PVC(Persistent Volume Claim)时自动创建相应的 PV(Persistent Volume)。
2)指定卷的参数: 存储类可以定义卷的各种参数和配置选项,如访问模式、卷大小、复制策略等。
3)支持动态卷生命周期管理: 存储类可以定义如何动态创建、扩容和销毁卷,以及何时回收 PV 等。
4.3 Provisioner的概念
Provisioner(存储分配器): 卷插件,用于指定 Volume 插件的类型,包括内置插件(如 kubernetes.io/aws-ebs)和外部插件(如 external-storage 提供的 ceph.com/cephfs)。
详见:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
Kubernetes 本身支持的动态 PV 创建不包括 NFS,所以需要使用外部存储卷插件分配PV。
4.4 实例:NFS 的动态 PV 创建
搭建 StorageClass + nfs-client-provisioner ,实现 NFS 的动态 PV 创建
Step1 在master01节点上安装nfs,并配置nfs服务
#创建共享目录
mkdir /opt/test2
chmod 777 /opt/test2/#添加权限
vim /etc/exports
/opt/test2 192.168.2.0/24(rw,no_root_squash,sync)
#重启NFS服务
systemctl restart nfsexportfs -var
showmount -e
Step2 创建 Service Account
Service Account 用来管理 NFS Provisioner
在 k8s 集群中运行的权限,设置nfs-client
对 PV
、PVC
、StorageClass
等的规则。
#编写配置清单文件
vim nfs-client-rbac.yaml#创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner
---
#创建集群角色
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
metadata:name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-clusterroleapiGroup: rbac.authorization.k8s.io
##配置清单文件详解##
用于创建一个 Service Account 账户和相关的 Role、RoleBinding,用于管理 NFS Provisioner 在 Kubernetes 集群中的权限。首先,创建了一个 Service Account 账户,命名为 "nfs-client-provisioner"然后,创建了一个 Cluster Role,命名为 "nfs-client-provisioner-clusterrole"。
该角色定义了一组权限规则,包括对持久卷(persistentvolume)的获取、列表、监视、创建和删除操作,对持久卷声明(persistentvolumeclaim)的获取、列表、监视和更新操作,对存储类(storageclass)的获取、列表和监视操作,对事件(events)和端点(endpoints)的获取、列表、监视、创建、更新等操作。最后,创建了一个 Cluster Role Binding,将上述角色与之前创建的 Service Account 进行绑定,并将其绑定到默认命名空间(namespace)中。
kubectl apply -f nfs-client-rbac.yaml
#Service Account "nfs-client-provisioner" 具备了管理 NFS Provisioner 所需的权限。
Step3 使用 Deployment 创建 NFS Provisioner
NFS Provisioner(即 nfs-client),有两个功能
1)在 NFS 共享目录下创建挂载点(volume),另一个则是将 PV 与 NFS 的挂载点建立关联。
编写资源配置清单文件
#编写配置清单文件
vim nfs-client-provisioner.yamlkind: Deployment
apiVersion: apps/v1
metadata:name: nfs-client-provisioner
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisioner #指定Service Account账户containers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-storage #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致- name: NFS_SERVERvalue: master01 #配置绑定的nfs服务器- name: NFS_PATHvalue: /opt/test2/ #配置绑定的nfs服务器目录volumes: #申明nfs数据卷- name: nfs-client-rootnfs:server: master01path: /opt/test2/
创建
kubectl apply -f nfs-client-provisioner.yaml kubectl get po
补充:报错解决方法
#由于 1.20 版本启用了 selfLink,所以 k8s 1.20+ 版本通过 nfs provisioner 动态生成pv会报错,解决方法如下:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false #添加这一行- --advertise-address=192.168.2.100
.....
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yamlkubectl delete pods kube-apiserver -n kube-systemkubectl get pods -n kube-system | grep apiserver
Step4 创建 StorageClass
负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联。
#编写配置清单文件
vim nfs-client-storageclass.yamlapiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
provisioner: nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:archiveOnDelete: "false" #false表示在删除PVC时不会对数据目录进行打包存档,即删除数据;为ture时就会自动对数据目录进行打包存档,存档文件以archived开头
#声明式创建
kubectl apply -f nfs-client-storageclass.yamlkubectl get storageclass
Step5 创建 PVC ,进行Pod 测试
创建PVC
vim test-pvc-pod.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-nfs-pvc#annotations: volume.beta.kubernetes.io/storage-class: "nfs-client-storageclass" #另一种SC配置方式
spec:accessModes:- ReadWriteManystorageClassName: nfs-client-storageclass #关联StorageClass对象resources:requests:storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:name: test-storageclass-pod
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"args:- "sleep 3600"volumeMounts:- name: nfs-pvcmountPath: /mntrestartPolicy: Nevervolumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-nfs-pvc #与PVC名称保持一致
kubectl apply -f test-pvc-pod.yamlkubectl get pvc
查看 NFS 服务器上是否生成对应的目录
自动创建的 PV 会以 ${namespace}-${pvcName}-${pvName}
的目录格式放到 NFS 服务器上。
ls /opt/test2
Pod测试
测试思路: 进入 Pod 在挂载目录 /mnt 下写一个文件,然后查看 NFS 服务器上是否存在该文件。
#进入Pod,创建测试文件
kubectl exec -it test-storageclass-pod sh/ # cd /mnt/
/mnt # echo 'this is test file' > test.txt
#进入到目录
cd /opt/test2/default-test-nfs-pvc-pvc-7a63142b-a4b4-4f07-966c-828ca60bbdcb
五、小结
5.1 PV、PVC的概念和状态
概念
PV: K8S在指定的存储设备空间中逻辑划分创建出来的可持久化的存储资源对象。
PVC: 对PV存储资源对象的请求和绑定,也是Pod能够挂载使用的一种存储卷类型。
创建方式简介
手动根据PV资源的yaml配置文件创建静态PV。
根据PVC的配置通过StorageClass(简称SC)资源调用存储卷插件创建动态PV。
PV的4种状态
PV的状态 | 描述 |
---|---|
Available(可用) | 表示为可用状态,PV已经被创建出来了,但是还未被PVC绑定 |
Bound(已绑定) | 表示PV已经被PVC绑定了,PV与PVC是一对一的绑定关系 |
Released(已释放) | 表示PVC被删除了,但是PV还没被回收 |
Failed(失败) | 表示PV被自动回收失败 |
5.2 静态和动态创建PV的思路
创建使用静态PV
1)准备好存储设备和共享目录;
2)准备yaml配置文件创建PV资源,设置 存储类型、访问模式(RWO RWX ROX RWOP)、 空间大小、回收策略(Retain Delete Recycle) 、storageClassName
等;
3)准备yaml配置文件创建PVC资源,设置 访问模式(必要条件,必须是PV能支持的访问模式)、空间大小(默认就近选择大于等于指定大小的PV) 、storageClassName
等来绑定PV;
4)创建Pod资源挂载PVC存储卷,设置存储卷类型为 persistentVolumeClaim
,并在容器配置中定义存储卷挂载点目录。
创建使用动态PV
1)准备好存储设备和共享目录;
2)如果是外置存储卷插件,需要先创建serviceaccount账户(Pod使用的账户)和做RBAC授权(创建角色授予相关资源对象的操作权限,再将账户与角色进行绑定),使sa账户具有对PV PVC StorageClass等资源的操作权限;
3)准备yaml配置文件创建外置存储卷插件的Pod,设置sa账户作为Pod的用户,并设置相关的环境变量(比如存储卷插件名称);
4)创建StorageClass(简称SC)资源,provisioner自动设置为存储卷插件名称 ;
以上操作是一劳永逸的,之后只需要创建PVC资源时引用StorageClass就可以自动调用存储卷插件动态创建PV资源了
5)准备yaml配置文件创建PVC资源,设置 访问模式、空间大小 storageClassName指定SC资源名称等来动态创建PV资源并绑定PV;
6)创建Pod资源挂载PVC存储卷,设置存储卷类型为 persistentVolumeClaim ,并在容器配置中定义存储卷挂载点目录。
通过陈述式管理资源配置的方式 修改或添加资源对象的配置
kubectl patch <资源类型> <资源名称> -p '{"第一层字段": {"第二层字段": {....}}}'kubectl patch deployment deploy-test -p '{"spec": {"replicas": 0}}'
kubectl patch deployment deploy-test -p '{"spec": {"template": {"spec": {"containers": [{"name": "myapp", "image": "soscscs/myapp:v1"}]}}}}'
创建使用动态PV
1)准备好存储设备和共享目录;
2)如果是外置存储卷插件,需要先创建serviceaccount账户(Pod使用的账户)和做RBAC授权(创建角色授予相关资源对象的操作权限,再将账户与角色进行绑定),使sa账户具有对PV PVC StorageClass等资源的操作权限;
3)准备yaml配置文件创建外置存储卷插件的Pod,设置sa账户作为Pod的用户,并设置相关的环境变量(比如存储卷插件名称);
4)创建StorageClass(简称SC)资源,provisioner自动设置为存储卷插件名称 ;
以上操作是一劳永逸的,之后只需要创建PVC资源时引用StorageClass就可以自动调用存储卷插件动态创建PV资源了
5)准备yaml配置文件创建PVC资源,设置 访问模式、空间大小 storageClassName指定SC资源名称等来动态创建PV资源并绑定PV;
6)创建Pod资源挂载PVC存储卷,设置存储卷类型为 persistentVolumeClaim ,并在容器配置中定义存储卷挂载点目录。
通过陈述式管理资源配置的方式 修改或添加资源对象的配置
kubectl patch <资源类型> <资源名称> -p '{"第一层字段": {"第二层字段": {....}}}'kubectl patch deployment deploy-test -p '{"spec": {"replicas": 0}}'
kubectl patch deployment deploy-test -p '{"spec": {"template": {"spec": {"containers": [{"name": "myapp", "image": "soscscs/myapp:v1"}]}}}}'
相关文章:

【云原生-Kurbernetes篇】K8s的存储卷/数据卷+PV与PVC
这是一个目录标题 一、Kurbernetes中的存储卷1.1 为什么需要存储卷?1.2 存储卷概述1.2.1 简介1.2.2 volume字段 1.3 常用的存储卷类型1.3.1 emptyDir(临时存储卷)1.3.2 hostPath(节点存储卷)1.3.3 nfs1.3.4 cephfs 二、…...

二层、三层交换机之间到底有什么区别?
简单地说 二层交换机,没有充当三层网关角色的能力(Capability)。三层交换机,首先也是二层交换机。但是,它有一个额外的能力(Capability),软件配置一下,可以充当三层网关…...

【论文阅读】2736. 最大和查询-2023.11.17
题目: 2736. 最大和查询 给你两个长度为 n 、下标从 0 开始的整数数组 nums1 和 nums2 ,另给你一个下标从 1 开始的二维数组 queries ,其中 queries[i] [xi, yi] 。 对于第 i 个查询,在所有满足 nums1[j] > xi 且 nums2[j]…...
2. zk集群部署
简介 上一篇文章我们已经把环境准备好了,jdk也配置好了,下面我们开始把zk部署起来 hadoop环境准备 创建zk用户 useradd zk -d /home/zk echo "1q1w1e1r" | passwd --stdin zk上传zk包 拷贝zk包到/home/zk目录,这里的zk版本为 3.6.3 scp…...

抖音快手判断性别、年龄自动关注脚本,按键精灵开源代码!
这个是支持抖音和快手两个平台的,可以进入对方主页然后判断对方年龄和性别,符合条件的关注,不符合条件的跳过下一个ID,所以比较精准,当然你可以二次开发加入更多的平台,小红书之类的,仅供学习&a…...

IDEA软件使用步骤
1.IDEA概述 IDEA全称InelliJ IDEA,是用于java语言开发的集成环境,它是业界公认的目前用于Java程序开发最好的工具。 集成环境:把代码编写,编译,执行,调试扽过多种功能综合到一起的开发工具。 下载:https…...

设计模式-11-模板模式
经典的设计模式有23种,但是常用的设计模式一般情况下不会到一半,我们就针对一些常用的设计模式进行一些详细的讲解和分析,方便大家更加容易理解和使用设计模式。 1-什么是模板模式 模板模式,全称是模板方法设计模式,英…...

【技术分享】EIGRP stub实验
【赠送】IT技术视频教程,白拿不谢!思科、华为、红帽、数据库、云计算等等https://xmws-it.blog.csdn.net/article/details/117297837?spm1001.2014.3001.5502【微/信/公/众/号:厦门微思网络】 拓扑图: R1配置: route…...
Python 爬虫 AES DES加密反爬
当你遇到需要处理 AES 或 DES 加密的反爬虫机制时,Python 可以通过使用相应的库来解决这类问题。首先,我们需要理解 AES 和 DES 加密是什么: AES (Advanced Encryption Standard):一种广泛使用的对称加密算法,它使用相…...

(论文阅读30/100)Convolutional Pose Machines
30.文献阅读笔记CPMs 简介 题目 Convolutional Pose Machines 作者 Shih-En Wei, Varun Ramakrishna, Takeo Kanade, and Yaser Sheikh, CVPR, 2016. 原文链接 https://arxiv.org/pdf/1602.00134.pdf 关键词 Convolutional Pose Machines(CPMs)…...

vue3实现数据大屏内数据向上滚动,鼠标进入停止滚动 vue3+Vue3SeamlessScroll
1.效果图 2.npm下载依赖及main.js文件配置 npm install vue3-seamless-scroll --saveimport vue3SeamlessScroll from vue3-seamless-scroll;app.use(vue3SeamlessScroll) 3.html代码 <!-- scrollFlag为true时再渲染,vue3只要涉及到传值子页面需要加flag判断,否…...
WPF显示3D图形
C# 中的 WPF (Windows Presentation Foundation) 支持显示3D图形。WPF 使用 DirectX 作为底层图形引擎,这意味着它可以处理包括3D图形在内的复杂渲染任务。 在 WPF 中,你可以使用一些内置的类和控件来创建和显示3D对象。这包括 Viewport3D, Camera, Mod…...

Xrdp+Cpolar实现远程访问Linux Kali桌面
XrdpCpolar实现远程访问Linux Kali桌面 文章目录 XrdpCpolar实现远程访问Linux Kali桌面前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于…...
赚钱
《赚钱》 作者/罗光记 赚钱劳身影未安, 岁月匆匆易逝难。 银钱到手笑颜开, 酒醉灯昏影独寒。 花前月下欢声起, 万金财富待来年。 诗酒飘香梦中笑, 人生何求更多钱。...
Django command执行脚本
python web项目中经常会使用到脚本,一般来说有两种很简单的方法,一种是直接python function,另一种就是 django 自定义command。 对比常规脚本 这里举个简单的例子,比如初始化数据、文件名称为initialize_data.py (1…...

GLSL: Shader cannot be patched for instancing.
最近在 unity 里碰到了这么一个错误,只有这么点信息,让人看着挺懵逼的,后来发现,是因为 unity 的 terrain 组件在设置里勾了 Draw Instanced 选项导致的,感觉应该是 unity 的 bug。 因为错出在 2021,2022就…...

Django测试环境搭建及ORM查询(创建外键|跨表查询|双下划线查询 )
文章目录 一、表查询数据准备及测试环境搭建模型层前期准备测试环境搭建代码演示 二、ORM操作相关方法三、ORM常见的查询关键字四、ORM底层SQL语句五、双下划线查询数据查询(双下划线)双下划线小训练Django ORM __双下划线细解 六、ORM外键字段创建基础表…...
css 设置网页最小字体为12px
谷歌浏览器默认最小字体为12px,但保不准万一有一天谷歌取消这个默认设置,或者一些人在设置中改了最小字体,为了防止万一,故系统设置了最小字体,主要利用了min和var的特性 :root {--responsive-font-size-primary: max…...
Failed to restart networking.service: Unit networking.service not found.
虚拟机Vmware中的Ubuntu20.0没有网络,ifconfig命令没有IP 如果在VMware中运行的Ubuntu 20.04虚拟机没有网络,并且ifconfig命令没有显示IP地址,你可以采取以下几个步骤来诊断和解决问题: 确认虚拟机网络设置: 确保虚拟机的网络适配器是开启的,并且配置正确。确认是否选择…...

基于单片机设计的水平仪(STC589C52+MPU6050)
一、前言 【1】项目背景 水平仪是一种常见的测量工具,用于检测物体或设备的水平姿态。在许多应用中,如建筑、制造和航空等领域,保持设备的水平姿态是非常重要的。为了实现实时的水平检测和显示,基于单片机设计的水平仪是一个常见…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...