k8s持久化存储
k8s中的常见存储类型
为什么要做数据持久化?
k8s中的pod的生命周期是短暂,当pod被删除时数据也会随之删除。当我们的数据不重要是也就无所谓了,但是生产环境中,我们的数据都是十分重要的,不能随意删除。
为了解决这个问题,我们需要再k8s中做数据持久化。数据持久化是将数据保存到持久化的存储介质上,以便pod删除被创建或者迁移到其它节点时仍然可用。
数据持久化的场景包括:
1、数据存储:许多应用程序需要保存用户生成的数据,如文件、图片、日志等。通过数据持久化,可以确保这些数据在容器销毁或重启后仍然存在。
2、数据共享:在某些情况下,多个容器或 Pod 可能需要访问和共享相同的数据。通过将数据存储在持久化卷中,可以使多个容器之间共享数据,实现数据一致性和共享访问。
3、数据备份和恢复:持久化存储解决方案通常提供数据备份和恢复机制,以防止数据丢失。这对于保护重要数据、应对故障或恢复到先前的状态非常重要。
4、数据迁移和扩展:在 Kubernetes 集群中,可能需要扩展应用程序到多个节点或迁移到其他集群。通过将数据存储在持久化卷中,可以方便地将数据与应用程序一起迁移到新的环境,无需担心数据丢失。
5、数据安全:某些行业或应用程序对数据的安全性有严格的要求。持久化存储解决方案通常提供数据 加密和访问控制功能,以确保数据在传输和存储过程中的安全性。
k8s 持久化存储方案-emptyDir(临时)
[root@k8s-slave1 ~]# kubectl explain pods.spec.volumes
KIND: Pod
VERSION: v1
RESOURCE: volumes <[]Object>
DESCRIPTION:
List of volumes that can be mounted by containers belonging to the pod.
More info: https://kubernetes.io/docs/concepts/storage/volumes
Volume represents a named volume in a pod that may be accessed by any
container in the pod.
FIELDS:
awsElasticBlockStore <Object>
awsElasticBlockStore represents an AWS Disk resource that is attached to a
kubelet's host machine and then exposed to the pod. More info:
https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
azureDisk <Object>
azureDisk represents an Azure Data Disk mount on the host and bind mount to
the pod.
azureFile <Object>
azureFile represents an Azure File Service mount on the host and bind mount
to the pod.
cephfs <Object>
cephFS represents a Ceph FS mount on the host that shares a pod's lifetime
cinder <Object>
cinder represents a cinder volume attached and mounted on kubelets host
machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
configMap <Object>
configMap represents a configMap that should populate this volume
csi <Object>
csi (Container Storage Interface) represents ephemeral storage that is
handled by certain external CSI drivers (Beta feature).
downwardAPI <Object>
downwardAPI represents downward API about the pod that should populate this
volume
emptyDir <Object>
emptyDir represents a temporary directory that shares a pod's lifetime.
More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
ephemeral <Object>
ephemeral represents a volume that is handled by a cluster storage driver.
The volume's lifecycle is tied to the pod that defines it - it will be
created before the pod starts, and deleted when the pod is removed.
Use this if: a) the volume is only needed while the pod runs, b) features
of normal volumes like restoring from snapshot or capacity tracking are
needed, c) the storage driver is specified through a storage class, and d)
the storage driver supports dynamic volume provisioning through a
PersistentVolumeClaim (see EphemeralVolumeSource for more information on
the connection between this volume type and PersistentVolumeClaim).
Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes
that persist for longer than the lifecycle of an individual pod.
Use CSI for light-weight local ephemeral volumes if the CSI driver is meant
to be used that way - see the documentation of the driver for more
information.
A pod can use both types of ephemeral volumes and persistent volumes at the
same time.
fc <Object>
fc represents a Fibre Channel resource that is attached to a kubelet's host
machine and then exposed to the pod.
flexVolume <Object>
flexVolume represents a generic volume resource that is
provisioned/attached using an exec based plugin.
flocker <Object>
flocker represents a Flocker volume attached to a kubelet's host machine.
This depends on the Flocker control service being running
gcePersistentDisk <Object>
gcePersistentDisk represents a GCE Disk resource that is attached to a
kubelet's host machine and then exposed to the pod. More info:
https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
gitRepo <Object>
gitRepo represents a git repository at a particular revision. DEPRECATED:
GitRepo is deprecated. To provision a container with a git repo, mount an
EmptyDir into an InitContainer that clones the repo using git, then mount
the EmptyDir into the Pod's container.
glusterfs <Object>
glusterfs represents a Glusterfs mount on the host that shares a pod's
lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md
hostPath <Object>
hostPath represents a pre-existing file or directory on the host machine
that is directly exposed to the container. This is generally used for
system agents or other privileged things that are allowed to see the host
machine. Most containers will NOT need this. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
iscsi <Object>
iscsi represents an ISCSI Disk resource that is attached to a kubelet's
host machine and then exposed to the pod. More info:
https://examples.k8s.io/volumes/iscsi/README.md
name <string> -required-
name of the volume. Must be a DNS_LABEL and unique within the pod. More
info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
nfs <Object>
nfs represents an NFS mount on the host that shares a pod's lifetime More
info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
persistentVolumeClaim <Object>
persistentVolumeClaimVolumeSource represents a reference to a
PersistentVolumeClaim in the same namespace. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
photonPersistentDisk <Object>
photonPersistentDisk represents a PhotonController persistent disk attached
and mounted on kubelets host machine
portworxVolume <Object>
portworxVolume represents a portworx volume attached and mounted on
kubelets host machine
projected <Object>
projected items for all in one resources secrets, configmaps, and downward
API
quobyte <Object>
quobyte represents a Quobyte mount on the host that shares a pod's lifetime
rbd <Object>
rbd represents a Rados Block Device mount on the host that shares a pod's
lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md
scaleIO <Object>
scaleIO represents a ScaleIO persistent volume attached and mounted on
Kubernetes nodes.
secret <Object>
secret represents a secret that should populate this volume. More info:
https://kubernetes.io/docs/concepts/storage/volumes#secret
storageos <Object>
storageOS represents a StorageOS volume attached and mounted on Kubernetes
nodes.
vsphereVolume <Object>
vsphereVolume represents a vSphere volume attached and mounted on kubelets
host machine
常用的如下:
emptyDir
hostPath
nfs
persistentVolumeClaim
glusterfs
cephfs
configMap
secret
在 Kubernetes 中,EmptyDir 是一种卷(Volume),它提供了一个空目录来供容器使用。EmptyDir 卷在 Pod 级别上创建,与 Pod 的生命周期绑定。EmptyDir 卷在 Pod 被删除或重新启动时会被清空,因 此它不是持久化的存储解决方案。
EmptyDir 卷的使用场景包括:
- 临时文件共享:如果多个容器需要在同一个 Pod 中进行临时文件共享,EmptyDir 卷是一个简便 的解决方案。容器可以将文件写入 EmptyDir 卷,并且其他容器可以读取和修改这些文件。当 Pod 被删除或重启时,EmptyDir 卷中的文件会被清空。
- 共享数据:某些应用程序可能需要在容器之间共享一些中间结果或临时数据。EmptyDir 卷可以 作为容器之间的临时数据交换机制。容器可以将数据写入 EmptyDir 卷,其他容器可以读取和处 理这些数据,从而实现数据共享和协作。
- 缓存:EmptyDir 卷可以用作容器的缓存存储。某些应用程序可能需要将频繁访问的数据缓存到 本地存储中,以提高性能。EmptyDir 卷提供了一个临时的、高速的存储介质来存储缓存数据, 提供快速的读取和写入操作。
当在 Kubernetes 中使用存储卷(Volume),需要经历以下步骤:
-
定义 Pod 的 Volume:在 Pod 的配置中定义一个 Volume,指定它要关联到哪个存储上。可以 使用不同类型的 Volume,如 EmptyDir、HostPath、PersistentVolumeClaim 等,具体选 择取决于需求。
-
在容器中使用 Volume Mounts:在 Pod 的配置中,为每个容器定义 Volume Mounts,将 Volume 挂载到容器内部的指定路径上。这样容器就能够访问和操作 Volume 中的数据。
-
通过 Volume 实现数据持久化和共享:一旦 Volume 被挂载到容器中,容器就可以将数据写入 Volume 或从 Volume 中读取数据。这使得数据能够在容器的生命周期内持久存在,并且可以被 其他容器共享和访问。
创建一个临时卷案例
参考:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#emptydir-配置示例
[root@k8s-slave1 volumes]# cat emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
# sizeLimit: 500Mi #可以设置目录大小
k8s 持久化存储方案-hostPath
hostPath 是 Kubernetes 中的一种卷类型,它将主机节点上的文件或目录挂载到容器中。使用 hostPath,可以将主机节点上的文件系统路径直接映射到容器的文件系统中。这种方式在某些情况下非常有用,但也需要谨慎使用,因为它具有一些潜在的限制和风险。
以下是 hostPath 的一些关键特点和适用场景:
- 直接访问主机文件系统:hostPath 卷允许容器直接访问主机节点上的文件系统。这对于需要访问主机节点上的特定文件或目录的应用程序非常有用。例如,某些日志收集器可能需要访问主机 上的日志文件。
- 主机依赖性:hostPath 卷的挂载是与特定主机节点紧密关联的,因此在调度 Pod 时需要特别 注意。
如果 Pod 被调度到另一个主机节点上,它将无法访问之前挂载的主机文件系统。
- 危险性:hostPath 卷的使用需要谨慎,因为容器可以访问主机节点上的任何文件或目录,包括 敏感的系统文件。此外,如果多个 Pod 使用相同的 hostPath 卷并且并发写入同一个文件,可 能会导致冲突和数据损坏。
- 开发和测试环境:hostPath 卷特别适用于开发和测试环境,因为它可以方便地将主机节点上的 文件或目录映射到容器中,从而加快开发和测试工作流程。
需要注意的是,hostPath 卷并不适合生产环境中的大多数用例。在生产环境中,建议使用更可靠和 弹性的持久化存储方案,例如网络存储卷(NFS)、云提供商的块存储或对象存储等。
查看 hostPath 存储卷的用法
[root@k8s-slave1 ~]# kubectl explain pod.spec.volumes.hostPath
KIND: Pod
VERSION: v1
RESOURCE: hostPath <Object>
DESCRIPTION:
hostPath represents a pre-existing file or directory on the host machine
that is directly exposed to the container. This is generally used for
system agents or other privileged things that are allowed to see the host
machine. Most containers will NOT need this. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
Represents a host path mapped into a pod. Host path volumes do not support
ownership management or SELinux relabeling.
FIELDS:
path <string> -required-
path of the directory on the host. If the path is a symlink, it will follow
the link to the real path. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
type <string>
type for HostPath Volume Defaults to "" More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
官网:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
apiVersion: v1
kind: Pod
metadata:
name: tomcat
namespace: volumes # 单独开一个ns环境
spec:
volumes:
- name: tomcat-log
hostPath:
path: /share/pod_share/tomcat/ #设置目录不用自动创建
containers:
- name: tomcat-log
image: tomcat
volumeMounts:
- name: tomcat-log
mountPath: /usr/local/tomcat/logs/
删除pod查看数据是否存在
k8s 持久化存储方案-NFS
NFS(Network File System)是一种网络文件系统协议,它允许不同计算机之间共享文件和目录。 在 Kubernetes(k8s)中,NFS 是一种常见的持久化存储方案,用于将网络共享的存储卷挂载到容器中。
下面是 NFS 的基本介绍和常见应用场景:
- 基本原理:NFS 允许将存储资源(文件或目录)通过网络共享给其他计算机。NFS 服务器将存 储资源公开为共享,并将其挂载到客户端计算机上。客户端可以像访问本地文件系统一样访问这 些共享资源。
- 持久化存储方案:在 Kubernetes 中,NFS 可以作为持久化存储方案使用。它可以提供可靠的 存储,并在 pod 被重新调度到不同的节点时保持数据的一致性。
- 分布式访问:NFS 允许多个客户端同时访问共享资源。这使得它非常适合那些需要多个容器或 Pod 共享数据的场景,例如数据库系统或分布式文件共享。
- 跨平台兼容性:NFS 是一种跨平台的文件系统协议,支持在不同操作系统之间进行文件共享。这 使得它成为在混合操作系统集群中实现持久化存储的理想选择。
- 灵活性:NFS 提供了对存储资源的灵活访问和管理。管理员可以根据需求创建和配置 NFS 服务 器,设置共享权限以及实施访问控制策略。
- 备份和恢复:NFS 具备备份和恢复数据的能力。通过使用备份工具和策略,可以对 NFS 共享的 数据进行定期备份,以防止数据丢失或损坏。
NFS服务器搭建就不写了
创建pod,挂载nfs共享目录
apiVersion: v1
kind: Pod
metadata:
name: nfs
namespace: volumes
spec:
containers:
- image: nginx
name: nfs
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: nfs-volume
volumes:
- name: nfs-volume
nfs:
server: 192.168.33.100
path: /volumes
nfs存储卷也可以保存用户数据,不受宿主机影响,但是万一nfs服务器宕机了,就会影响你的数据,生成环境中需要使用分布式存储,常见的分布式有glusterfs和cephfs。
k8s 持久化存储方案-PVC
官网:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
K8s PV 是什么?
PersistentVolume(PV):PV 是集群中的存储资源,可以是物理存储设备、网络存储或云存储等。 PV 独立于 Pod 存在,它们是集群级别的资源,由集群管理员进行配置和管理。PV 具有持久性,即使 Pod 被删除,PV 中的数据也会保留。PV 定义了存储的容量、访问模式和其他属性。
K8s PVC 是什么?
PersistentVolumeClaim(PVC):PVC 是 Pod 对 PV 的申请,它表示 Pod 需要一定的存储资源来 满足其持久化存储需求。PVC 在 Pod 和 PV 之间建立了一个抽象层,使得 Pod 无需关心底层存储的具体 细节。PVC 定义了 Pod 对存储的需求,包括存储容量、访问模式等。
K8s PVC 和 PV 工作原理
当创建一个 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)时,它们之间的相互作 用和工作原理如下:
-
PV 的供应方式:
• 静态配置:集群管理员预先创建 PV 对象,包含了实际存储资源的详细信息。这些 PV 存在于 Kubernetes API 中,供用户使用。
• 动态配置:当静态 PV 无法匹配用户的 PVC 时,Kubernetes 可以尝试为 PVC 动态地 配置 PV。这基于 StorageClass,PVC 必须请求存储类,并且管理员必须创建和配置该 类以进行动态配置。
-
绑定:
• 用户创建 PVC 并指定所需的存储资源和访问模式。
• 在找到可用的 PV 之前,PVC 保持未绑定状态。
-
使用:
• 首先,存储管理员创建 PV,并将其划分为多个存储卷。
• 用户在创建 Pod 之前创建 PVC,并指定所需的 PV 大小和访问模式。
• 创建 PVC 后,可以将其作为存储卷使用,并在 Pod 定义中引用该 PVC。
• PV 和 PVC 是一对一的关系。一旦 PV 被某个 PVC 绑定,其他 PVC 就不能使用它。
• 如果没有合适的 PV 可用,PVC 将处于挂起状态,直到有一个合适的 PV 可用为止。
-
回收策略:
• 当删除使用 PVC 作为存储卷的 Pod 时,PVC 与 PV 的绑定将解除。
• PV 有不同的回收策略可供选择:
• Retain(保留):删除 PVC 后,PV 保留,并且数据仍然存在。PV 不会被绑 定到其他 PVC 上,可以再次使用。
• Recycle(回收,不推荐):删除 PVC 后,PV 会被清空数据并准备重新使用。 这个回收策略在 Kubernetes 1.15 版本后被废弃。
• Delete(删除):删除 PVC 后,PV 也会从 Kubernetes 中移除,并且相关 的存储资源也会被删除。
通过 PV 和 PVC 的结合使用,Kubernetes 提供了一种灵活的持久化存储管理机制,使得 k8s 使用者可以轻松地申请、使用和管理存储资源,同时提供了不同的回收策略以满足不同的需求。
创建pod,使用pvc作为持久化存储卷
pvc后端的存储,支持多种iscsl、nfs、fc等,这里使用nfs作为后端存储。
查看定义pv需要的字段
查看定义nfs类型的pv需要的字段
创建pv
需要现在nfs服务器创建出来共享目录,一个pv对应一个共享目录。
官网链接:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
pv不属于任何名称空间,所以不用指定名称空间
[root@k8s-slave1 volumes]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v1
server: 192.168.33.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 5Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v2
server: 192.168.33.100
查看pv
创建pvc
pv相当于把硬盘分好放到库房,当有pod需要存储空间的时候,pod不能直接使用pv,需要通过pvc去申请空间,pvc和pv一一对应。
[root@k8s-slave1 volumes]# cat pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
使用标签绑定pv pvc
[root@k8s-slave1 volumes]# cat pv2.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
labels:
app: pv1
spec:
capacity:
storage: 1Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v1
server: 192.168.33.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
labels:
app: pv2
spec:
capacity:
storage: 1Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v2
server: 192.168.33.100
[root@k8s-slave1 volumes]# cat pvc2.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
[root@k8s-slave1 volumes]# cat pvc3.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
selector:
matchLabels:
app: pv2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
使用存储类型绑定pv pvc
[root@k8s-slave1 volumes]# cat pv4.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v1
server: 192.168.33.100
storageClassName: nfs # 添加存储类
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 5Gi #pv的存储空间容量
accessModes:
- ReadWriteOnce
nfs:
path: /volumes/v2
server: 192.168.33.100
storageClassName: nfs # 添加存储类
[root@k8s-slave1 volumes]# cat pvc5.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc5
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
创建pod挂载pvc
在 Kubernetes 中,PV(Persistent Volume)和PVC(Persistent Volume Claim)是资源对象,它们是独立于命名空间的。PV 和 PVC 在创建时不受命名空间的影响。PV 和 PVC 通常是在集群级别创建的,它们可以跨命名空间使用。
但是,当 PVC 与 Pod 绑定时,Pod 和 PVC 必须在同一命名空间中
。如果不在同一名称空间,创建pod将是pending状态。
#创建名称空间
apiVersion: v1
kind: Namespace
metadata:
name: aa
---
#创建pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
labels:
app: pv2
spec:
capacity:
storage: 1Gi #pv的存储空间容量
accessModes:
- ReadWriteMany
nfs:
path: /volumes/v2
server: 192.168.33.100
---
#创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
selector:
matchLabels:
app: pv2
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
#创建pod挂载pvc
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
#namespace: aa
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-html
persistentVolumeClaim:
claimName: pvc2
k8s 存储类: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 提供了以下好处:
- 简化管理:StorageClass 允许管理员创建一组可重用的存储配置模板,而无需为每个 PVC 手动 创建和管理 PV。这降低了管理成本和复杂性。
- 动态供应:使用 StorageClass,管理员可以根据需求动态创建 PV,从而自动为 PVC 提供存储 资源。这种动态供应的机制使得存储的分配更加灵活和自动化。
- 可选性和灵活性:StorageClass 允许管理员根据存储的不同特性和需求创建不同的 StorageClass。用户可以根据自己的需求选择合适的 StorageClass,并使用相应的存储资源。
查看定义storageclass需要的字段
[root@k8s-slave1 volumes]# 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.
reclaimPolicy <string>
Dynamically provisioned PersistentVolumes of this storage class are created
with this reclaimPolicy. Defaults to Delete.
volumeBindingMode <string>
VolumeBindingMode indicates how PersistentVolumeClaims should be
provisioned and bound. When unset, VolumeBindingImmediate is used. This
field is only honored by servers that enable the VolumeScheduling feature.
provisioner:供应商,storageclass 需要有一个供应者,用来确定我们使用什么样的存储来创建 pv,常见的 provisioner 如下:
官网: https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
provisioner 既可以由内部供应商提供,也可以由外部供应商提供,如果是外部供应商可以参考 https://github.com/kubernetes-incubator/external-storage/下提供的方法创建。
allowVolumeExpansion:允许卷扩展,PersistentVolume 可以配置成可扩展。将此功能设置为 true 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。当基础存储类的 allowVolumeExpansion 字段设置为 true 时,以下类型的卷支持卷扩展。
安装 nfs provisioner,用于配合存储类动态生成 pv
因为nfs是外部的存储,所以需要安装制备器
参考:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
1、创建运行 nfs-provisioner 需要的 sa 账号
[root@k8s-slave1 volumes]# cat serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
扩展:什么是 sa?
sa 的全称是 serviceaccount。 serviceaccount 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。
指定了 serviceaccount 之后,我们把 pod 创建出来了,我们在使用这个 pod 时,这个 pod 就有了 我们指定的账户的权限了。
2、对 sa 授权
kubectl create clusterrolebinding nfs-provisioner --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner
3、安装 nfs-provisioner 程序
在nfs服务器上创建一个共享目录
[root@nfs 课程资料]# cat nfs-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-provisioner
spec:
selector:
matchLabels:
app: nfs-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-provisioner
image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: example.com/nfs
- name: NFS_SERVER
value: 192.168.33.100 #改成你自己的地址
- name: NFS_PATH
value: /volumes/nfs #改成你自己的共享目录
volumes:
- name: nfs-client-root
nfs:
server: 192.168.33.100
path: /volumes/nfs
创建 storageclass,动态供给 pv
[root@k8s-slave1 volumes]# cat nfs-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
provisioner: example.com/nfs
创建 pvc,通过 storageclass 动态生成 pv
[root@k8s-slave1 volumes]# cat claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 1Gi
storageClassName: nfs
可以看到到 test-claim1 的 pvc 已经成功创建了,绑定的 pv 是pvc-b8526c49-f2ca-4cab-b679-b0d3e65059a4,这个 pv 是由 storageclass 调用 nfs provisioner 自动生成的。
步骤总结:
1、供应商:创建一个 nfs provisioner (只需要创建一次
)
2、创建 storageclass,storageclass 指定刚才创建的供应商 (只需要创建一次
)
3、创建 pvc,这个 pvc 指定 storageclass
创建 pod,挂载 storageclass 动态生成的 pvc
[root@k8s-slave1 volumes]# cat pvc3-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx3
namespace: aa
spec:
replicas: 3
selector:
matchLabels:
app: nginx3
template:
metadata:
labels:
app: nginx3
spec:
containers:
- name: nginx3
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-html
persistentVolumeClaim:
claimName: test-claim2
hou
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!