文章目录
- 一、持久化存储
- emptyDir
- 实际操作
- hostPath
- 建立过程
- NFS存储
- NFS 存储的优点
- NFS 存储的缺点
- 具体操作
- pv和pvc
- Persistent Volume (PV)
- 使用场景
- Persistent Volume Claim (PVC)
- 使用场景
- 使用 PV 和 PVC 的场景
- 实际操作
- StorageClass
- StorageClass 概述
- 应用场景
- 实际应用
一、持久化存储
在Kubernetes (K8s) 中,持久化存储是一个重要的概念,它允许容器化应用程序在 Pod 重启或重新调度时保留数据。
使用存储卷,需要如下步骤:
1、定义 pod 的 volume,这个 volume 指明它要关联到哪个存储上的。
volumes:
- mountPath: PATH
name: NAME
2、在容器中要使用 volumemounts 挂载对应的存储。
volumeMounts:
- mountPath: PATH
name: PATH_NAME
emptyDir
emptyDir 是 Kubernetes 中的一种基本卷类型,它为 Pod 中的容器提供了临时存储空间。
生命周期:
- emptyDir 卷的生命周期与 Pod 相同。
- 当 Pod 被分配到节点时创建,当 Pod 从节点上移除时删除。
作用:
- 临时文件存储
- 计算过程中的中间数据
- 容器间共享的临时数据
- 作为应用程序的缓存
可以通过默认截止指定大小限制,来限制 emptyDir 卷的存储容量。来防止占满整个磁盘应用。
实际操作
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: harbor.hiuiu.com/nginx/nginx:1.21.5
ports:
- containerPort: 80
volumeMounts:
- mountPath: /cache# 指定容器中的目录。
name: cache-volume
volumes:
- name: cache-volume#创建一个cache-volume的卷
emptyDir:
sizeLimit: 500Mi
验证过程:
找到pod相对应的node节点,并找出uid,去相对应的节点找到这个文件夹。
kubectl get pod nginx -o yaml |grep uid
kubectl get pod -o wide
kubectl exec -it -n <namespace> <pod-name> -c <container-name> -- /bin/bash
进入容器内部,然后验证结果。
容器内部:
对应的pod上:
缺点:
hostPath
hostPath 是 Kubernetes 中的一种卷类型,它允许将主机节点的文件系统上的文件或目录挂载到 Pod 中。以下是关于 hostPath 的重要概念和特性:
-
功能:
- 允许 Pod 访问主机文件系统。
- 可以挂载单个文件或整个目录。
-
持久性:
- 数据持久存在于主机上,即使 Pod 被删除。
-
使用场景:
- 访问主机系统文件。
- 在容器中运行需要访问 Docker 内部的应用。
建立过程
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-dep
spec:
replicas: 10
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: harbor.hiuiu.com/nginx/nginx:1.22a
ports:
- containerPort: 80 #以上是用deployment建立pod
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nginx-volume
volumes:
- name: nginx-volume
hostPath:
path: /data/webs
type: DirectoryOrCreate#type的值有不同的
---
apiVersion: v1
kind: Service
metadata:
name: my-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30007
#建立service,可以通过外网访问
将这些 hostPath 的类型:
- DirectoryOrCreate
- 如果路径不存在,创建一个空目录
- 权限设置为 0755
- 与 kubelet 具有相同的组和属主信息
- Directory
- 在指定路径上必须已存在目录
- FileOrCreate
- 如果路径不存在,创建一个空文件
- 权限设置为 0644
- 与 kubelet 具有相同的组和所有权
- File
- 在指定路径上必须已存在文件
- Socket
- 在指定路径上必须存在 UNIX 套接字
- CharDevice (仅限 Linux 节点)
- 在指定路径上必须存在字符设备
- BlockDevice (仅限 Linux 节点)
- 在指定路径上必须存在块设备
在不同的节点上,不同的pod会有不同的效果。这是因为挂载的文件内容是不一样的。
NFS存储
在 Kubernetes 中,NFS(Network File System)是一种用于共享存储的卷类型,可以在多个 Pod 之间共享持久化数据。使用 NFS 卷允许不同节点上的 Pod 访问同一存储空间,适合需要共享文件存储的应用场景。以下是关于 Kubernetes 中 NFS 存储的关键点:
NFS 存储的优点
-
共享访问:
- 多个 Pod 可以同时访问同一个 NFS 卷,实现数据共享。
-
持久性:
- 数据存储在 NFS 服务器上,与 Pod 的生命周期独立,这样即使 Pod 被删除,数据也会被保留。
-
可移植性:
- 可以在不同节点和 Pod 之间轻松移动和共享数据。
-
分离存储和计算:
- 存储和计算可以分别扩展,从而优化资源使用。
-
集中管理:
- 简化了对存储的管理,可以在集中式文件系统中进行备份和恢复。
NFS 存储的缺点
-
性能:
- 相较于本地存储,网络传输可能会导致较高的延迟。
- 性能可能受到网络带宽和 NFS 服务器性能的限制。
-
可用性依赖:
- NFS 服务器成为数据访问的单点故障,需确保其高可用性。
-
安全性:
- 需要配置适当的权限和网络策略以防止未经授权的访问。
-
复杂的设置:
- 需要在 Kubernetes 外部配置和维护 NFS 服务器。
具体操作
apt install nfs-kernel-server
vim /etc/exports
/data/disk *(rw,sync,no_root_squash,no_subtree_check)
代表的含义:
-
/data/disk
:- 这是你在 NFS 服务器上导出的目录路径。客户端将能够通过 NFS 挂载并访问此目录。
-
*
:- 代表允许所有主机访问该导出。通常在生产环境中,为了安全起见,这一部分会被限定为特定的主机或域名,例如
192.168.1.0/24
或者*.example.com
。
- 代表允许所有主机访问该导出。通常在生产环境中,为了安全起见,这一部分会被限定为特定的主机或域名,例如
-
rw
:- Read/Write,允许客户端对该导出的目录进行读和写操作。
-
sync
:- 规定 NFS 服务器在响应前,将所有数据写入磁盘。这确保了数据的持久性,即使服务器意外崩溃后,数据不易丢失。
sync
选项较async
有更好的数据完整性,但可能会稍微影响性能,因为需要等待数据实际写入磁盘。
- 规定 NFS 服务器在响应前,将所有数据写入磁盘。这确保了数据的持久性,即使服务器意外崩溃后,数据不易丢失。
-
no_root_squash
:- 默认情况下,NFS 会将客户端的 root 用户请求映射为匿名用户,这被称为
root_squash
,防止远程 root 用户在服务器上拥有 root 权限。而no_root_squash
则取消这个映射,允许客户端的 root 用户对导出的文件和目录具有 root 权限。这一选项在某些情况下可能造成安全漏洞,因为它允许更高特权的访问。
- 默认情况下,NFS 会将客户端的 root 用户请求映射为匿名用户,这被称为
-
no_subtree_check
:- 禁用子树检查。这一选项用于提升性能。默认情况下,NFS 会检查客户端请求是否属于导出文件系统中的子树。然而,如果导出目录不是文件系统的根目录,检查会增加开销。禁用此选项可以减少这种开销。
exportfs -arv
刷新/etc/exports文件
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: harbor.hiuiu.com/nginx/nginx:1.21.5
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html#镜像共享的地址
name: nginx-volume
volumes:
- name: nginx-volume
nfs:
server: 192.168.232.100#nfs服务器的地址
path: /data/disk#本机的地址
readOnly: false#是否是只读
验证:
进入集群,添加index.html文件。
挂载的文件夹中也会出现index.html。
pv和pvc
在 Kubernetes 中,持久存储由 Persistent Volume (PV) 和 Persistent Volume Claim (PVC) 负责管理。它们的设计使得存储与工作负载解耦,实现存储资源的动态管理和高效利用。以下是它们的详细解释以及在实际应用中的使用场景。
Persistent Volume (PV)
Persistent Volume 是一个独立于 Pod 生命周期的存储抽象。PV 是集群中具体存储的表示,由管理员管理和配置。PV 可以在多种存储后端上实现,如本地磁盘、NFS、云提供商的存储服务等。
PV 定义了:
- 存储容量(如 1Gi)
- 访问模式(如 ReadWriteOnce、ReadOnlyMany、ReadWriteMany)
- 存储后端类型和具体配置(如 NFS 服务器地址和路径)
使用场景
- 企业数据存储:例如,将重要的数据库持久化,将数据库数据文件存储在一个 PV 上,确保即便 Pod 停止或迁移,数据都不会丢失。
- 共享存储使用:多个应用可以共享相同的持久化数据源,例如多个应用共享一个内容管理系统(CMS)的静态内容。
Persistent Volume Claim (PVC)
PVC 是用户对存储的一种请求。PVC 代表某种存储需求,如需要一个持久化的存储卷,指定的存储大小和访问模式等。PVC 将业务需求与具体存储实现分离,使得开发者无需关心底层存储的细节。
PVC 发出请求后,Kubernetes 会自动寻找满足条件的 PV 并进行绑定。
PVC 定义了:
- 所需存储大小(如 1Gi)
- 访问模式(需与所请求的 PV 兼容)
使用场景
- Pod 持久化存储:对于需要持久化存储空间的应用,Pod 可以通过 PVC 使用后台的 PV,PVC 确保应用所需存储资源存续及可用。
- 动态存储供给:通过 StorageClass 和 PVC,Kubernetes 可以自动为 PVC 创建和销毁 PV,实现存储的动态供给。
使用 PV 和 PVC 的场景
- 静态存储:管理员提前配置好 PV,对应于实际的存储资源。用户创建 PVC 时,这些 PVC 自主找到可用的 PV 并进行绑定,实现静态资源利用。
- 动态存储:通过 StorageClass,PVC 可以请求动态供应的存储。Kubernetes 使用 StorageClass 来自动化地为 PVC 创建相应的 PV。这样,存储资源在需要时动态创建,减少了管理员的工作量。
- 跨集群存储:通过 PV 和 PVC 的结合,可以实现多集群间共享底层存储资源,用于灾备和跨集群高可用设计。
总结来说,PV 和 PVC 是 Kubernetes 世界中强大而灵活的持久化存储管理方式,降低了深度存储系统管理的复杂性,提供了与工作负载分离的资源管理方式,使得开发和运维能够更专注于应用本身的开发与交付。
实际操作
创建顺序:pv>pvc>pod
删除顺序:pod>pvc>pv
(1)准备存储服务
mkdir /data/disk/v{1,2,3,4,5} -p
vim /etc/exports
/data/disk/v1 *(rw,sync,no_root_squash)
/data/disk/v2 *(rw,sync,no_root_squash)
/data/disk/v3 *(rw,sync,no_root_squash)
/data/disk/v4 *(rw,sync,no_root_squash)
/data/disk/v5 *(rw,sync,no_root_squash)
(2)建立pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: v1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadOnlyMany
nfs:
path: /data/volume/v1
server: 172.16.1.30
在 Kubernetes 中,Persistent Volume(PV)通过访问模式(Access Modes)来定义如何被 Pod 挂载和使用。访问模式对 PV 的使用场景有着重要的影响,它决定了 Pod 如何在节点间使用存储资源。
访问模式(Access Modes)
-
ReadWriteOnce (RWO) :
- 描述: 卷可以被单个节点以读写模式挂载。
- 典型使用场景: 数据库、日志管理等需要读写操作且通常只会运行在单个节点上的应用。
- 限制: 一旦一个节点已经使用此模式挂载卷,其他节点无法再以读写方式挂载。
-
ReadOnlyMany (ROX) :
- 描述: 卷可以被多个节点以只读模式挂载。
- 典型使用场景: 静态内容服务器、共享配置或数据分发等无需写入操作的场景。
- 优势: 允许在多个节点上同时读取,适用于水平扩展的读取密集型服务。
-
ReadWriteMany (RWX) :
- 描述: 卷可以被多个节点以读写模式挂载。
- 典型使用场景: 需要多个实例共同读写共享数据的应用,如并行处理框架。
- 限制: 并非所有存储系统都支持此模式,需要了解底层存储的具体支持情况。
回收策略
在 Kubernetes 中,持久卷(PV)的回收策略(Reclaim Policy)是在 PV 的定义中指定的。这个策略决定了当一个绑定的 PVC 被删除后,PV 的处理方式。有以下几种回收策略:
-
Retain:
- 这种策略意味着即使 PVC 被删除,PV 仍然会保留,转变为
Released
状态。 - 数据仍留在 PV 中,未被清除。
- 需要管理员手动处理 PV 才能重新使用,比如清除数据或重新绑定,适用于数据需要审查或备份的场景。
- 这种策略意味着即使 PVC 被删除,PV 仍然会保留,转变为
-
Delete:
- 当与之绑定的 PVC 被删除时,PV 及其后端存储资产也会被自动删除。
- 适用于不需要保留数据的场景,比如临时数据存储。
- 常见于动态供应的存储系统中。
-
Recycle(已弃用):
- 该策略会简单地擦除 PV 上的数据,并将 PV 标记为
Available
,供再次使用。 - 在 Kubernetes 版本 1.15 已被弃用,建议使用其他更现代的存储策略。
- 该策略会简单地擦除 PV 上的数据,并将 PV 标记为
如何设置回收策略
回收策略在 PersistentVolume(PV)的配置文件中进行定义。以下是一个定义 PV 及其回收策略的示例:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /path/to/nfs
server: nfs-server.example.com
在配置文件中的设置位置
-
persistentVolumeReclaimPolicy
字段:这是在 PV 规格(spec
)下定义的,它指定了 PV 的回收策略。可选的值为Retain
和Delete
。 - 默认策略:如果未指定,Kubernetes 将使用默认的
Retain
策略。这意味着数据会保留,除非明确设置为Delete
。
通过合理配置回收策略,可以有效管理存储资源,确保在应用需要时存储行为符合期望的数据处理和安全策略。
(3)创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
这边有一个问题,并没有指定pvc去找哪个pv,而且我设置的pv的限制也不相同,他们是如何寻找并绑定的呢?
PVC 和 PV 的自动匹配和绑定
-
自动匹配和绑定
- Kubernetes 控制平面的控制循环持续监控新创建的 PVC。
- 当新的 PVC 被创建时,控制器寻找能够满足其要求的可用 PV。
- 如果找到匹配的 PV,系统会自动绑定 PVC 和 PV。
-
等待和绑定
- 如果没有适合的 PV(例如缺少足够的存储大小或不匹配的访问模式),PVC 将保持未绑定状态。
- 当一个匹配的 PV 后续被创建或释放时,此 PVC 将自动与之绑定。
- 例如,若 PVC 请求 100 Gi 的存储而集群中只有多个 50 Gi 的 PV,则 PVC 会等待,直到有一个 100 Gi 的 PV 可用。
-
在 Pod 中使用 PVC
- Pod 使用 PVC 申领的存储卷,Kubernetes 将根据 PVC 的绑定信息找到对应的 PV 并挂载到 Pod 上。
- 如果 PV 支持多种访问模式,用户在 Pod 中使用 PVC 时需指定希望的访问模式。
-
持久绑定关系
- 一旦 PVC 与 PV 绑定成功,PV 就专属于该 PVC,直到 PVC 被删除。
- 用户通过在 Pod 规格中的
volumes
字段中引用persistentVolumeClaim
节区来使用已申领的 PV。
(4)创建pod
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc
spec:
containers:
- name: nginx
image: harbor.hiuiu.com/nginx/nginx:1.21.5
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-html
persistentVolumeClaim:
claimName: my-pvc
(5)验证效果
由于选的pv是/data/disk/v2,所以我们选择在v2下编写index.html文件。然后去访问相应的pod。
StorageClass
在 Kubernetes 中,StorageClass
是用于定义和管理持久卷(Persistent Volume, PV)动态供应的配置方法。通过 StorageClass
,管理员可以抽象出底层存储实现的细节,并提供一种灵活的资源分配机制。以下是 StorageClass
的详细解释及其应用场景:
StorageClass 概述
-
定义:
StorageClass
是 Kubernetes 的一种资源对象,用来定义如何为 Persistent Volume Claim (PVC) 动态创建和配置 Persistent Volume (PV)。- 包含的信息通常包括存储类型、参数、供应策略等。
-
关键属性:
-
provisioner
: 指定用于动态创建存储的插件或驱动程序。 -
parameters
: 包含配置provisioner
所需的参数,如存储类型、区位信息等。 -
reclaimPolicy
: 定义当 PVC 删除后 PV 的回收策略(如Retain
和Delete
)。 -
volumeBindingMode
: 指定卷绑定时间,可以是Immediate
(即时)或WaitForFirstConsumer
(等待第一个消费者)。
-
-
动态供应:
- 使用
StorageClass
可以实现 PV 的动态供应,当 PVC 请求存储时,系统根据相关StorageClass
创建符合需求的 PV。 - 动态供应常用于云环境中,通过自动化的方式减少手动干预。
- 使用
应用场景
-
多种存储类型管理:
- 在同一集群中管理不同的存储类型,比如高性能 SSD 和低成本 HDD,为不同的工作负载提供更合适的存储解决方案。
-
按需分配资源:
- 动态供应可根据应用需求自动分配存储资源,而不是预先分配所有存储,提高资源效率和利用率。
-
支持不同应用需求:
- 不同的应用程序可能需要不同的存储特性(如速度、容量、备份机制等)。利用不同的
StorageClass
可以为每种需求提供个性化解决方案。
- 不同的应用程序可能需要不同的存储特性(如速度、容量、备份机制等)。利用不同的
-
跨区域的可用性:
- 对于分布式应用,通过
StorageClass
可以指定存储的区域或可用区,提升数据访问的延迟性能和冗余度。
- 对于分布式应用,通过
-
简化运维:
- 集群管理员可以通过
StorageClass
统一管理存储策略和配置,简化了复杂的存储管理任务。
- 集群管理员可以通过
实际应用
(1)创建一个SA账户
在 Kubernetes 中,“ServiceAccount”(服务账户,缩写为 SA)是一种用于管理应用在集群内运行时访问 API 服务器的身份标识。
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
(2)对sa授权
kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner
(3)创建StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs
provisioner: example.com/nfs
定义了资源的类型为 StorageClass。
NFS provisioner,用于该 StorageClass。provisioner 是存储提供者(插件或驱动)的标识符。通常你会用实际的 provisioner 名称,如 nfs-provisioner。
(4)构建一个provisioner,用于动态创建pv
apiVersion: apps/v1
kind: Deployment
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
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: example.com/nfs
- name: NFS_SERVER
value: 192.168.232.100
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.232.100
path: /data/nfs
(5)准备nfs存储
(6)创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-claim1
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs
(7)创建测试pod
apiVersion: v1
kind: Pod
metadata:
name: read-pod
spec:
containers:
- name: read-pod
image: harbor.hiuiu.com/nginx/nginx:1.21.5
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
restartPolicy: Never
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim1
注意:需要给挂载文件夹的权限。否则文件夹挂载不上去。
(8)验证
进入容器去构建index.html
挂载路径下面也有。实验成功。