k8s StorageClass 存储类
文章目录
- 一、概述
- 1、StorageClass 对象定义
- 2、StorageClass YAML 示例
- 二、StorageClass 字段
- 1、provisioner(存储制备器)
- 1.1、内置制备器
- 1.2、第三方制备器
- 2、reclaimPolicy(回收策略)
- 3、allowVolumeExpansion(允许卷扩展)
- 4、mountOptions(挂载选项)
- 5、volumeBindingMode(卷绑定模式)
- 5.1、Immediate
- 5.2、WaitForFirstConsumer
- 6、allowedTopologies(允许的拓扑结构)
- 6.1、示例
- 7、parameters(存储参数)
- 7.1、示例
- 7.2、存储参数(AWSElasticBlockStore)
- 8、设置默认的 StorageClass(storageclass.kubernetes.io/is-default-class)
- 8.1、示例
- 8.2、修改已有的 StorageClass
- 8.2.1、将存在的 SC 设置为默认
- 8.2.2、将存在的 SC 设置为非默认
- 三、实例 -- 使用 NFS 类型的 StorageClass 动态创建 PV
- 1、配置 NFS 服务端
- 1.1、master 节点安装 nfs-utils 包
- 1.2、master 节点创建共享目录
- 1.3、编辑/etc/exports文件
- 1.4、应用新的导出设置
- 1.5、重启并设置 NFS 开机自启
- 1.6、检查 NFS 共享
- 2、配置 NFS 客户端
- 2.1、安装 nfs-utils 包
- 2.2、创建目录挂载 NFS 共享
- 2.2.1、卸载错误的挂载点
- 2.3、重启并设置 NFS 开机自启
- 2.4、系统启动自动挂载 NFS 共享(非必要)
- 2.5、查看挂载状态
- 3、创建存储类
- 4、创建 RBAC 权限
- 5、创建 provisioner
- 6、创建 PVC
- 7、观察 PV 是否动态创建
- 8、创建使用同一 PVC 的多个 Pod
- 9、向共享存储写入数据
- 10、从另一个 Pod 读取数据
- 11、查看 nfs 服务端与客户端的共享目录
- 11.1、PV 目录创建的流程
- 11.2、PV 目录的结构
- 12、修改 NFS 服务器共享目录内容查看容器内部变化
- 四、实例 -- 动态创建 PVC 和 PV
- 1、创建 Headless Service
- 2、创建 StatefulSet
- 3、观察 Pod状态
- 4、观察到 PVC 与 PV 已经动态创建并相互绑定了
- 5、每一个 Pod 都会通过绑定 PVC 获取一块独立的 PV
一、概述
集群级别资源,StorageClass 是 Kubernetes 中的一种资源对象,它定义了创建 Persistent Volume (PV) 的策略和方法。StorageClass 主要用于实现 PV 的动态供应,这意味着当用户创建了一个 Persistent Volume Claim (PVC) 时,Kubernetes 会根据所指定的 StorageClass 自动创建一个符合要求的 PV 并将其绑定到 PVC 上
StorageClass
作为对存储资源的抽象定义,对用户设置的 PVC
申请屏蔽后端存储的细节,一方面减少了用户对于存储资源细节的关注,另一方面减轻了管理员手工管理 PV
的工作,由系统自动完成 PV
的创建和绑定,实现动态的资源供应。基于 StorageClass
的动态资源供应模式将逐步成为云平台的标准存储管理模式。
1、StorageClass 对象定义
StorageClass 资源对象的定义主要包括:名称、后端存储的提供者 (provisioner)、后端存储的相关参数配置(parameters)和回收策略(reclaimPolicy)、卷绑定模式(volumeBindingMode)
StorageClass 的名称很重要,将在创建 PVC 时引用,管理员应该准确命名具有不同存储特性的 StorageClass。
StorageClass 一旦被创建,则无法修改,如需更改,则只能删除原 StorageClass 资源对象并重新创建。
2、StorageClass YAML 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:# 存储类的名称,用户在 PVC 中引用name: example-storage-classstorageclass.kubernetes.io/is-default-class: "true" # 设置为默认的 StorageClass
# 动态制备器的名称,需要与已安装的制备器匹配
provisioner: kubernetes.io/aws-ebs # 例子中使用的是 AWS EBS 制备器
# reclaimPolicy 定义了当 PVC 被删除时,PV 应该如何处理
reclaimPolicy: Delete # 可选值为 Retain 或 Delete
# 允许卷扩展
allowVolumeExpansion: true # 可选值为 true 或 false
# 定义了卷绑定到 Pod 的模式
volumeBindingMode: Immediate # 可选值为 Immediate 或 WaitForFirstConsumer
# 定义了存储系统需要的参数,这些参数会传递给制备器
parameters:# 存储类型,根据制备器和存储系统的要求设置type: gp2 # AWS EBS 的例子,对于其他系统可能有不同的值# 存储 IOPS 性能,某些存储系统可能需要这个参数iopsPerGB: "10" # 例子,具体值根据需求和制备器支持设置# 存储的最小 IOPS 值,某些存储系统可能需要这个参数minimumIOPS: "1000" # 例子,具体值根据需求和制备器支持设置# 存储的最大 IOPS 值,某些存储系统可能需要这个参数maximumIOPS: "20000" # 例子,具体值根据需求和制备器支持设置# 存储的加密选项,某些存储系统可能支持加密encrypted: "true" # 例子,具体值根据需求和制备器支持设置# 存储的区域,对于跨区域存储系统可能需要这个参数availabilityZone: "us-east-1a" # 例子,具体值根据制备器和存储系统的要求设置# 存储的性能等级,某些存储系统可能提供不同的性能等级performance: "high" # 例子,具体值根据制备器和存储系统的要求设置
# 定义了挂载选项,这些选项会在 PV 被挂载到节点时使用
mountOptions:- debug # 例子,具体值根据需求设置,可能包括 "debug", "defaults", "ro" 等# - other-option # 可以添加额外的挂载选项
# 允许的拓扑约束,定义了存储可以被哪些节点访问
allowedTopologies:- matchLabelExpressions:- key: topology.kubernetes.io/regionvalues:- us-east-1- key: topology.kubernetes.io/zonevalues:- us-east-1a
二、StorageClass 字段
1、provisioner(存储制备器)
provisioner 指定了用于动态创建 PersistentVolume (PV) 的制备器(Provisioner)。制备器是一个插件,它负责在后端存储系统中根据 PersistentVolumeClaim (PVC) 的请求来创建存储资源,不同的存储插件支持不同的存储后端和服务提供商。当 PVC 被创建并且与之关联的 StorageClass 指定了一个制备器时,Kubernetes 会调用这个制备器来自动创建相应的 PV。
卷插件 | 内置制备器 | 配置示例 |
---|---|---|
AWSElasticBlockStore | √ | AWS EBS |
AzureFile | √ | Azure文件(已弃用) |
AzureDisk | √ | Azure Disk |
CephFS | - | - |
Cinder | √ | Open Stack Cinder |
FC | - | - |
FlexVolume | - | - |
GCEPersistentDisk | √ | gcePD |
Glusterfs | √ | GlusterFS |
iSCSI | - | - |
Local | - | Local |
NFS | - | NFS |
PortworxVolume | √ | portworx-volume |
RBD | √ | ceph-rbd |
VsphereVolume | √ | Vsphere |
1.1、内置制备器
Kubernetes 内置支持的 Provisioner 的命名都以 “kubernetes.io/” 开头
- kubernetes.io/aws-ebs:用于在 AWS 上创建 Elastic Block Store (EBS) 卷。
- kubernetes.io/azure-disk:用于在 Azure 上创建磁盘。
- kubernetes.io/gce-pd:用于在 Google Cloud Platform (GCP) 上创建持久磁盘。
- kubernetes.io/cinder:用于在 OpenStack 上创建 Cinder 卷。
1.2、第三方制备器
为了符合 StorageClass 的用法,自定义 Provisioner 需要符合存储卷的开发规范,外部存储供应商的作者对代码、提供方式、运行方式、存储插件(包括Flex)等具有完全的自由控制权。
代码仓库 kubernetes-sigs/sig-storage-lib-external-provisioner 包含一个用于为外部制备器编写功能实现的类库。你可以访问代码仓库 kubernetes-sigs/sig-storage-lib-external-provisioner 了解外部驱动列表。
例如,对NFS类型,Kubernetes没有提供内部的Provisioner,但可以使用外部的Provisioner。也有许多第三方存储提供商自行提供外部的Provisioner。
2、reclaimPolicy(回收策略)
通过动态资源供应模式创建的PV将继承在StorageClass资源对象上设置的回收策略,配置字段名称为“reclaimPolicy“,可以设置的选项包括Delete(删除)和 Retain(保留)。
- 如果StorageClass没有指定reclaimPolicy,则默认值为Delete。
- 对于管理员手工创建的仍被StorageClass管理的PV,将使用创建PV时设置的资源回收策略。
3、allowVolumeExpansion(允许卷扩展)
PV 可以被配置为允许扩容,当 StorageClass 资源对象的 allowVolumeExpansion字段被设置为true时,将允许用户通过编辑PVC的存储空间自动完成PV的扩容。
下表描述了支持存储扩容的Volume类型和要求的Kubernetes最低版本:
支持存储扩容的 Volume 类型 | Kubernetes 最低版本 |
---|---|
gcePersistentDisk | 1.11 |
awsElasticBlock Store | 1.11 |
Cinder | 1.11 |
glusterfs | 1.11 |
RBD | 1.11 |
Azure File | 1.11 |
Azure Disk | 1.11 |
Portworx | 1.13 |
FlexVolume | 1.14(Alpha) |
CSI | 1.16(Beta) |
此功能仅可用于扩容卷,不能用于缩小卷。
4、mountOptions(挂载选项)
通过StorageClass资源对象的mountOptions字段,系统将为动态创建的PV设置挂载选项。
并不是所有 PV类型都支持挂载选项,如果 PV不支持但 StorageClass 设置了该字段,则 PV将会创建失败。另外,系统不会对挂载选项进行验证,如果设置了错误的选项,则容器在挂载存储时将直接失败。
5、volumeBindingMode(卷绑定模式)
StorageClass 资源对象的 volumeBindingMode 字段设置用于控制何时将 PVC 与动态创建的 PV 绑定。
目前支持的绑定模式包括: Immediate 和 WaitForFirstConsumer。
5.1、Immediate
存储绑定模式的默认值为 Immediate,表示当一个PersistentVolumeClaim (PVC)创建出来时,就动态创建PV并进行PVC与PV的绑定操作。
需要注意的是,对于拓扑受限 (Topology-limited) 或无法从全部Node访问的后端存储,将在不了解Pod调度需求的情况下完成PV的绑定操作,这可能会导致某些Pod无法完成调度。
5.2、WaitForFirstConsumer
WaitForFirstConsumer绑定模式表示PVC与PV的绑定操作延迟到第一个使用 PVC的Pod创建出来时再进行。
系统将根据Pod的调度需求,在Pod所在的Node上创建PV,这些调度需求可以通过以下条件(不限于)进行设置:
-
Pod对资源的需求
-
Node Selector
-
Pod亲和性和反亲和性设置
-
Taint和Toleration设置
目前支持 WaitForFirstConsumer 绑定模式的存储卷包括:
- AWSElasticBlockStore
- AzureDisk
- GCEPersistentDisk.
另外,有些存储插件通过预先创建好的PV绑定支持WaitForFirstConsumer模式,比如:
- AWSElasticBlockStore
- AzureDisk
- GCEPersistentDisk
- Local
6、allowedTopologies(允许的拓扑结构)
在使用WaitForFirstConsumer模式的环境中,如果仍然希望基于特定拓扑信息(Topology)进行PV绑定操作,则在StorageClass的定义中还可以通过 allowedTopologies字段进行设置。
6.1、示例
下面的例子通过 matchLabelExpressions 设置目标 Node 的标签选择条件 (zone=us-central1-a或 us-central1-b) PV 将在满足这些条件的 Node 上允许创建
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: standard
provisioner: kubernetes.io/example
parameters:type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:- key: topology.kubernetes.io/zonevalues:- us-central-1a- us-central-1b
7、parameters(存储参数)
后端存储资源提供者的参数设置,不同的 Provisioner 可能提供不同的参数设置。某些参数可以不显示设定,Provisioner 将使用其默认值。
目前 StorageClass 资源对象支持设置的存储参数最多为 512个,全部 key 和 value 所占的空间不能超过 256KiB。
7.1、示例
下面举常见存储提供商(Provisioner)提供的 StorageClass 存储参数示例(以AWSElasticBlockStore存储卷为例子):
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:csi.storage.k8s.io/fstype: xfstype: io1iopsPerGB: "50"encrypted: "true"
allowedTopologies:
- matchLabelExpressions:- key: topology.ebs.csi.aws.com/zonevalues:- us-east-2c
7.2、存储参数(AWSElasticBlockStore)
AWS EBS 存储参数
-
type (必需)
- 定义 EBS 卷的存储类型(默认值gp3)。例如:
- gp2:通用目的 SSD
- io1:提供高 IOPS 的 SSD
- io2:适用于需要大量 IOPS 的应用程序的新一代 SSD
- st1:通过 HDD 存储优化的卷
- sc1:通过冷 HDD 存储优化的卷
- 定义 EBS 卷的存储类型(默认值gp3)。例如:
-
iopsPerGB (可选,仅当 type 为 io1 或 io2 时有效)
- 定义每个 GiB 提供的 IOPS 数量。
- 例如,如果 type 为 io1 并且 iopsPerGB 设置为 10,则 100 GiB 的卷将提供 1000 IOPS。
-
iops (可选,仅当 type 为 io1 时有效)
- 直接定义卷的 IOPS 总数。例如,iops: “1000” 表示卷将提供 1000 IOPS。
-
throughput (可选,仅当 type 为 st1 时有效)
- 定义卷的吞吐量,以 MiB/s 为单位。例如,throughput: “500” 表示卷的吞吐量为 500 MiB/s。
-
encrypted (可选)
- 布尔值,指示是否应该加密 EBS 卷。例如,encrypted: “true”。
-
kmsKeyId (可选)
- 指定用于加密 EBS 卷的 KMS 密钥 ID。例如,kmsKeyId: “arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab”。
-
fsType (可选)
- 定义文件系统类型。例如,fsType: “ext4”。
-
volumeSize (可选)
- 定义请求的卷大小(以 GiB 为单位)。例如,volumeSize: “100” 表示请求 100 GiB 的卷。
-
availabilityZone (可选)
- 定义 EBS 卷应该创建在哪个可用区。例如,availabilityZone: “us-west-2a”。
-
multiAttachEnabled (可选)
- 布尔值,指示是否启用多附加。例如,multiAttachEnabled: “true” 允许卷同时附加到多个实例。
-
snapshotId (可选)
- 定义用于创建 EBS 卷的快照 ID。例如,snapshotId: “snap-0123456789abcdef0”。
-
tags (可选)
-
定义一组键值对,用于标记 EBS 卷。例如:
-
tags:- key: "project"value: "myproject"- key: "owner"value: "myteam"
-
8、设置默认的 StorageClass(storageclass.kubernetes.io/is-default-class)
在创建 SC 的 YAML 文件时,需要在 metadata 部分添加一个注解,以标记该 SC 为默认。
8.1、示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: low-latencyannotations:storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi-driver.example-vendor.example
reclaimPolicy: Retain # 默认值是 Delete
allowVolumeExpansion: true
mountOptions:- discard # 这可能会在块存储层启用 UNMAP/TRIM
volumeBindingMode: WaitForFirstConsumer
parameters:guaranteedReadWriteLatency: "true" # 这是服务提供商特定的
8.2、修改已有的 StorageClass
8.2.1、将存在的 SC 设置为默认
kubectl patch storageclass <sc-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
8.2.2、将存在的 SC 设置为非默认
kubectl patch storageclass <sc-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
如果你在集群中的多个 StorageClass 上将 storageclass.kubernetes.io/is-default-class 注解设置为 true,然后创建一个未设置 storageClassName 的 PersistentVolumeClaim (PVC), Kubernetes 将使用最近创建的默认 StorageClass。
三、实例 – 使用 NFS 类型的 StorageClass 动态创建 PV
角色 | 主机名 | ip地址 |
---|---|---|
nfs 服务端 + master 节点 | k8s-master1 | 192.168.112.10 |
nfs 客户端 + node 节点 | k8s-node1 | 192.168.112.20 |
nfs 客户端 + node 节点 | k8s-node2 | 192.168.112.30 |
1、配置 NFS 服务端
1.1、master 节点安装 nfs-utils 包
yum install -y nfs-utils
1.2、master 节点创建共享目录
mkdir -pv /data/nfs
1.3、编辑/etc/exports文件
echo "/data/nfs 192.168.112.0/24(rw,sync,no_root_squash)" > /etc/exports
1.4、应用新的导出设置
exportfs -arv
1.5、重启并设置 NFS 开机自启
systemctl restart nfs && systemctl enable nfs
1.6、检查 NFS 共享
showmount -e localhost
2、配置 NFS 客户端
所有 node 节点
2.1、安装 nfs-utils 包
yum install -y nfs-utils
2.2、创建目录挂载 NFS 共享
mkdir -pv /mnt/nfsmount -t nfs 192.168.112.10:/data/nfs /mnt/nfs
2.2.1、卸载错误的挂载点
如果在执行 mount -t nfs
命令时出现了错误,比如使用了错误的参数或者路径,你可以通过卸载当前的挂载点然后再重新挂载来修正错误。
-
确认当前的挂载状态
-
使用
mount
命令查看当前的所有挂载情况,找到错误挂载的条目。 -
mount
-
-
卸载错误的挂载点
-
# 知道错误的挂载点 sudo umount /mnt/nfs
-
# 知道 nfs 服务端 IP 地址和共享目录路径 sudo umount 192.168.112.10:/data/nfs
-
-
卸载时遇到设备/文件正在使用中
-
umount -f /mnt/nfs
-
强制卸载可能会导致数据丢失,因此只有在确定没有数据写入的情况下才这样做。
-
2.3、重启并设置 NFS 开机自启
systemctl restart nfs && systemctl enable nfs
2.4、系统启动自动挂载 NFS 共享(非必要)
echo '192.168.112.10:/data/nfs /mnt/nfs nfs defaults 0 0' >> /etc/fstab
2.5、查看挂载状态
mount | grep 192.168.112.10
3、创建存储类
cat >> nfs-storage.yaml << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-storagenamespace: defaultlabels:environment: test
provisioner: fuseim.pri/ifs
reclaimPolicy: Retain
volumeBindingMode: Immediate
EOF
kubectl apply -f nfs-storage.yaml
4、创建 RBAC 权限
cat >> rbac.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisionernamespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runner
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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: run-nfs-client-provisioner
subjects:- kind: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisionernamespace: default
rules:- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisionernamespace: default
subjects:- kind: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f rbac.yaml
5、创建 provisioner
部署 NFS Client Provisioner,这是一个 Kubernetes 外部存储插件,用于动态创建 NFS PV。
cat >> nfs-provisioner.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisionernamespace: default
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0volumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: fuseim.pri/ifs # 这里必须要填写storageclass中的PROVISIONER名称信息一致- name: NFS_SERVERvalue: 192.168.112.10 # 指定NFS服务器的IP地址- name: NFS_PATHvalue: /data/nfs # 指定NFS服务器中的共享挂载目录volumes:- name: nfs-client-root # 定义持久化卷的名称,必须要上面volumeMounts挂载的名称一致nfs:server: 192.168.112.10 # 指定NFS所在的IP地址path: /data/nfs # 指定NFS服务器中的共享挂载目录
EOF
kubectl apply -f nfs-provisioner.yaml
6、创建 PVC
cat >> nfs-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nginx-pvcnamespace: defaultlabels:environment: testapp: nginx
spec:storageClassName: nfs-storageaccessModes:- ReadWriteManyresources:requests:storage: 5Mi
EOF
kubectl apply -f nfs-pvc.yaml
7、观察 PV 是否动态创建
kubectl get pvc,pv,sc
发现使用 NFS Client Provisioner 可以动态创建 pv 并与 PVC 绑定处于 Bound 状态
8、创建使用同一 PVC 的多个 Pod
cat >> nfs-pod1.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: nfs-pod1
spec:containers:- name: container1image: nginx:1.16.0volumeMounts:- name: shared-datamountPath: /usr/share/nginx/htmlvolumes:- name: shared-datapersistentVolumeClaim:claimName: nginx-pvc
EOF
cat >> nfs-pod2.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: nfs-pod2
spec:containers:- name: container2image: nginx:1.16.0volumeMounts:- name: shared-datamountPath: /usr/share/nginx/htmlvolumes:- name: shared-datapersistentVolumeClaim:claimName: nginx-pvc
EOF
kubectl apply -f nfs-pod1.yaml -f nfs-pod2.yaml
9、向共享存储写入数据
kubectl exec -it nfs-pod1 -- /bin/bash
echo "hello from nfs-pod1" > /usr/share/nginx/html/index.html
exit
10、从另一个 Pod 读取数据
kubectl exec -it nfs-pod2 -- /bin/bash
cat /usr/share/nginx/html/index.html
exit
11、查看 nfs 服务端与客户端的共享目录
tree /data/nfs
tree /mnt/nfs
这个新出现的目录(PV 目录) default-nginx-pvc-pvc-c8a8b825-1577-4f76-ba1f-a1302941b333 用于映射 PersistentVolume (PV) 到 NFS 服务器上的具体路径
11.1、PV 目录创建的流程
- 创建 PVC:
- 当你创建 PVC 时,Kubernetes 会根据 StorageClass 自动创建 PV。
- Provisioner 创建 PV:
- Provisioner 会在 NFS 服务器上的共享目录下创建一个新目录,目录名称包含了 PVC 的名称和 UUID。
- 挂载到 Pod:
- 创建的 PV 会被挂载到 Pod 中指定的路径。
11.2、PV 目录的结构
/<共享目录>/<命名空间>-<PVC名称>-<PV名称>
- 共享目录:
- 这是你在 NFS 服务器上创建并共享出去的目录,比如 nfs 服务端的 /data/nfs 以及 nfs 客户端的 /mnt/nfs
- 命名空间:
- 这是 Kubernetes 中的一个逻辑分组,用于隔离不同的应用程序和服务。PVC 所属的命名空间名称。
- PVC 名称:
- 这是在 Kubernetes 中创建的 PersistentVolumeClaim 的名称。
- PV 名称:
- 这是根据 PVC 动态创建出来的 PersistentVolume 的名称,通常是一个带有 UUID 的字符串。
kubectl get pvc nginx-pvc -o custom-columns='PVC-NAMESPACE:.metadata.namespace,PVC-NAME:.metadata.name'kubectl get pv pvc-c8a8b825-1577-4f76-ba1f-a1302941b333 -o custom-columns='PV-NAME:.metadata.name'
12、修改 NFS 服务器共享目录内容查看容器内部变化
可以发现也是同步更新的
cd /data/nfs/default-nginx-pvc-pvc-c8a8b825-1577-4f76-ba1f-a1302941b333echo "hello from nfs-server" > index.htmlkubectl get pods -o widecurl 10.244.1.3curl 10.244.2.8
四、实例 – 动态创建 PVC 和 PV
1、创建 Headless Service
cat >> nginx-headless.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: nginx-headlesslabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx
EOF
kubectl apply -f nginx-headless.yamlkubectl get svc -l app=nginx -o wide
2、创建 StatefulSet
cat >> sts.yaml << EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:serviceName: "nginx"replicas: 5selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.16.0ports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates: # 通过模板化方式绑定- metadata:name: www # 指定pvc的名字annotations:volume.beta.kubernetes.io/storage-class: "nfs-storage" # 只指定了storageClassspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 5Mi
EOF
kubectl apply -f sts.yaml
3、观察 Pod状态
由于是 statefulset 控制器所以 pod 是按顺序创建的
kubectl get pods -l app=nginx -w
4、观察到 PVC 与 PV 已经动态创建并相互绑定了
kubectl get pvc -l 'app=nginx,environment!=test'
kubectl get pv | grep -v "default/nginx-pvc"
5、每一个 Pod 都会通过绑定 PVC 获取一块独立的 PV
kubectl get pod web-0 -o custom-columns='PVC-NAME:.spec.volumes[*].persistentVolumeClaim.claimName'kubectl get pod web-1 -o custom-columns='PVC-NAME:.spec.volumes[*].persistentVolumeClaim.claimName'kubectl get pod web-2 -o custom-columns='PVC-NAME:.spec.volumes[*].persistentVolumeClaim.claimName'kubectl get pod web-3 -o custom-columns='PVC-NAME:.spec.volumes[*].persistentVolumeClaim.claimName'kubectl get pod web-4 -o custom-columns='PVC-NAME:.spec.volumes[*].persistentVolumeClaim.claimName'
相关文章:

k8s StorageClass 存储类
文章目录 一、概述1、StorageClass 对象定义2、StorageClass YAML 示例 二、StorageClass 字段1、provisioner(存储制备器)1.1、内置制备器1.2、第三方制备器 2、reclaimPolicy(回收策略)3、allowVolumeExpansion(允许…...

3D Slicer医学图像全自动AI分割组合拳-MONAIAuto3DSeg扩展
3D Slicer医学图像全自动AI分割组合拳-MONAIAuto3DSeg扩展 1 官网下载最新3D Slicer image computing platform | 3D Slicer 版本5.7 2 安装torch依赖包: 2.1 进入安装目录C:\Users\wangzhenlin\AppData\Local\slicer.org\Slicer 5.7.0-2024-09-21\bin࿰…...

分布式光伏的发电监控
国拥有丰富的清洁可再生能源资源储量,积极开发利用可再生能源,为解决当前化石能源短缺与环境污染严重的燃眉之急提供了有效途径[1]。但是可再生能源的利用和开发,可再生能源技术的发展和推广以及可再生能源资源对环境保护的正向影响ÿ…...

微信小程序----日期时间选择器(自定义时间精确到分秒)
目录 页面效果 代码实现 注意事项 页面效果 代码实现 js Component({/*** 组件的属性列表*/properties: {pickerShow: {type: Boolean,},config: Object,},/*** 组件的初始数据*/data: {pickerReady: false,// pickerShow:true// limitStartTime: new Date().getTime()-…...

3D生成技术再创新高:VAST发布Tripo 2.0,提升AI 3D生成新高度
随着《黑神话悟空》的爆火,3D游戏背后的AI 3D生成技术也逐渐受到更多的关注。虽然3D大模型的热度相较于语言模型和视频生成技术稍逊一筹,但全球的3D大模型玩家们却从未放慢脚步。无论是a16z支持的Yellow,还是李飞飞创立的World Labsÿ…...
ONNX Runtime学习之InferenceSession模块
ONNXRuntime库学习之InferenceSession(模块) 一、简介 onnxruntime.InferenceSession 是 ONNX Runtime 中用于加载和运行 ONNX 模型的核心模块。它提供了一种灵活的方式来在多种硬件设备(如 CPU、GPU)上执行 ONNX 模型推理。通过 InferenceSession&…...
【TS】TypeScript内置条件类型-ReturnType
ReturnType 在TypeScript中,ReturnType 是一个内置的条件类型(Conditional Type),它用于获取一个函数返回值的类型。这个工具类型非常有用,特别是当你需要引用某个函数的返回类型,但又不想直接写出那个具体…...

【c语言数据结构】超详细!模拟实现双向链表(初始化、销毁、头删、尾删、头插、尾插、指定位置插入与删除、查找数据、判断链表是否为空)
特点: 结构:指向前一结点指针数据指向后一结点指针由于循环,尾结点的下一结点next指向头结点(哨兵结点)空的双向链表只有自循环的哨兵结点(头结点) 模拟实现双向链表 LIST.h #define _CRT_…...

第十四届蓝桥杯嵌入式国赛
一. 前言 本篇博客主要讲述十四届蓝桥杯嵌入式的国赛题目,包括STM32CubeMx的相关配置以及相关功能实现代码以及我在做题过程中所遇到的一些问题和总结收获。如果有兴趣的伙伴还可以去做做其它届的真题,可去 蓝桥云课 上搜索历届真题即可。 二. 题目概述 …...
(k8s)kubernetes集群基于Containerd部署
资源列表 基础环境 一、基础环境准备 1.1、关闭Swap分区 1.2、添加hosts解析 1.3、桥接的IPv4流量传递给iptables的链 二、准备Containerd容器运行时 2.1、安装Containerd 2.2、配置Containerd 2.3、启动Containerd 三、部署Kubernetes集群 3.1、安装Kubeadm工具 3.2、…...

python内置模块pathlib.Path类操作目录和文件
python自带的pathlib模块提供了很多路径相关的功能,而pathlib.Path 是pathlib 模块中的一个核心类,它代表了文件系统中的一个路径,实现功能比如创建、删除、移动文件,读取和写入文件内容,遍历目录等。 Path 类跟os.pa…...

react开发环境搭建
文章目录 准备工作创建 React 项目使用 create-react-app 创建 React 项目使用 Vite 创建 React 项目启动项目效果安装出现的情况 react项目文件讲解1. 项目根目录2. 其他可能的目录和文件3. 配置文件 准备工作 Node.js 安装方法: 方式一:使用 NVM 安装…...
python 逻辑语句简记
什么语言都少不了逻辑处理语句的使用,python的逻辑处理语句有自身的使用特点,稍稍总结记录一下 一、断言 assert 条件 条件触发,程序执行中断 二、条件语句 if 条件: 执行内容 三、循环语句 while 条件: 循环体…...

8.进销存系统(基于springboot的进销存系统)
目录 1.系统的受众说明 2.开发技术与环境配置 2.1 SpringBoot框架 2.2 Java语言简介 2.3 MySQL环境配置 2.4 idea介绍 2.5 mysql数据库介绍 2.6 B/S架构 3.系统分析与设计 3.1 可行性分析 3.1.1 技术可行性 3.1.2 操作可行性 3.1.3经济可行性 3.4.1 数据库…...
深入理解主键回显:提升数据操作效率与准确性
在软件开发的世界中,主键回显是一个常常被提及但又容易被忽视其重要性的概念。今天,我们就来深入探讨一下主键回显的奥秘。 一、什么是主键回显? 在数据库设计中,主键是用于唯一标识表中每一行记录的字段。而主键回显࿰…...

springboot+阿里云物联网教程
需求背景 最近有一个项目,需要用到阿里云物联网,不是MQ。发现使用原来EMQX的代码去连接阿里云MQTT直接报错,试了很多种方案都不行。最终还是把错误分析和教程都整理一下。 需要注意的是,阿里云物联网平台和MQ不一样。方向别走偏了。 概念描述 EMQX和阿里云MQTT有什么区别…...

QT Creator cmake 自定义项目结构, 编译输出目录指定
1. 目的 将不同的源文件放到不同的目录下进行管理, 如下: build: 编译输出目录 include: 头文件目录 rsources: 资源文件目录 src: cpp文件目录 2. 创建完cmake工程后修改CMakeLists.txt 配置 注 : 这里头文件目录是include, 所以在includ…...
lunar无第三方依赖的公历、农历、法定节假日...日历工具库
文章目录 介绍maven示例示例(前后端)网址文档 介绍 lunar是一款无第三方依赖的公历(阳历)、农历(阴历、老黄历)、道历、佛历工具,支持星座、儒略日、干支、生肖、节气、节日、彭祖百忌、吉神(喜神/福神/财神/阳贵神/阴贵神)方位、胎神方位、…...

(全网最细)ELF文件详解
ELF文件是什么 ELF文件是一种对象文件格式。ELF文件的全程是(Executeable and Linking Format,可执行可链接格式)。ELF文件格式主要有三种: 可重定向文件。可重定向文件就是可以用于和其他对象文件链接来创建一个可执行或者可分…...

Leetcode面试经典150题-39.组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...