这是一个目录标题
- 一、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-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
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-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主机上目录位置
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-webserver
image: registry.k8s.io/test-webserver:latest
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
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-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: 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-rw
image: kubernetes/pause
volumeMounts:
- mountPath: "/mnt/cephfs"
name: cephfs
volumes:
- name: cephfs
cephfs:
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/cephfs
user: admin
secretFile: "/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 -arv
showmount -e
Step2 定义PV
#这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小。
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
nfs:
path: /opt/test/v1
server: master01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /opt/test/v2
server: master01
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /opt/test/v3
server: master01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
labels:
name: pv004
spec:
nfs:
path: /opt/test/v4
server: master01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /opt/test/v5
server: master01
accessModes: ["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.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
namespace: my-ns
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-pvc
namespace: my-ns
spec:
containers:
- name: myapp
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc
kubectl apply -f pod-vol-pvc.yaml
kubectl 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 nfs
exportfs -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: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-clusterrole
apiGroup: 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.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 #指定Service Account账户
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致
- name: NFS_SERVER
value: master01 #配置绑定的nfs服务器
- name: NFS_PATH
value: /opt/test2/ #配置绑定的nfs服务器目录
volumes: #申明nfs数据卷
- name: nfs-client-root
nfs:
server: master01
path: /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.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver
Step4 创建 StorageClass
负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联。
#编写配置清单文件
vim nfs-client-storageclass.yaml
apiVersion: 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.yaml
kubectl get storageclass
Step5 创建 PVC ,进行Pod 测试
创建PVC
vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc
#annotations: volume.beta.kubernetes.io/storage-class: "nfs-client-storageclass" #另一种SC配置方式
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass #关联StorageClass对象
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: test-storageclass-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
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-nfs-pvc #与PVC名称保持一致
kubectl apply -f test-pvc-pod.yaml
kubectl 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"}]}}}}'