在K8S中,数据持久化可以让容器在重新调度、重启或者迁移时保留其数据,并且确保数据的可靠性和持久性。
持久化存储通常用于程序的状态数据、数据库文件、日志文件等需要在容器生命周期之外的数据,它可以通过各种存储解决方案实现,如主机路径、本地存储、网络存储(如NFS、ISCSI)、云存储等。
HostPath是将节点上的文件或目录挂载到 Pod 上,此时该目录会变成持久化存储目录,即使 Pod 被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失。
但不适合生产环境,因为它对宿主机的依赖性较高,无法实现数据的高可用和迁移。
apiVersion: v1
kind: Pod
metadata:
name: test-volume-pod
spec:
containers:
- image: nginx
name: nginx-volume
volumeMounts:
- mountPath: /test-pd # 挂载到容器的哪个目录
name: test-volume # 挂载哪个 volume
volumes:
- name: test-volume
hostPath:
path: /data # 节点中的目录
type: Directory # 挂载目录类型 , Directory 代表/data必须存在 ,如果不存在则报错
在volumes类型为hostPath的时候, type有多种配置方式,如:
类型 | 说明 |
---|---|
DirectoryOrCreate | 如果给定的 path 不存在,就创建一个 755 的空目录 |
Directory | 这个目录必须存在 |
FileOrCreate | 如果给定的文件不存在,则创建一个空文件,权限为 644 |
File | 这个文件必须存在 |
Socket | UNIX 套接字,必须存在 |
CharDevice | 字符设备,必须存在 |
BlockDevice | 块设备,必须存在 |
EmptyDir 主要用于一个 Pod 中不同的 容器共享数据使用的,由于只是在 Pod 内部使用,因此与其他 volume 比较大的区别是,当 Pod 如果被删除了,那么 emptyDir 也会被删除。 这种方式适用于临时性的数据存储,当Pod重新启动时,EmptyDir也会被清空。也就是说它只做到了数据化共享,并没有做到持久化存储
apiVersion: v1
kind: Pod
metadata:
name: test-emptyDir-pd
spec:
containers:
- image: nginx
name: nginx-emptydir
volumeMounts:
- mountPath: /cache1
name: cache-volume
- image: nginx
name: nginx-emptydir
volumeMounts:
- mountPath: /cache2
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
需要使用nfs的文件服务的都要安装
apt-get update
# 安装
apt-get install nfs-kernel-server nfs-common
# 启动
systemctl start nfs-server
vim /etc/exports
# /data/nfs/ 代表共享目录 , ip代表可访问的ip信息, 后面是权限
/data/nfs/ 192.168.31.0/24(rw,sync,no_subtree_check,no_root_squash)
# 重新加载
exportfs -f
systemctl reload nfs-server
# 前面的是nfs服务地址及目录,后面是挂载到本地的目录
mount -t nfs 192.168.31.101:/data/nfs/html /data/nfs/nginx/html
查看挂载的目录
mount | grep nfs
apiVersion: v1
kind: Pod
metadata:
name: test-nfs-pd
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
nfs:
server: 192.168.31.101 # 网络存储服务地址
path: /data/nfs/html # 网络存储路径
# 在NFS服务的/data/nfs/html 目录下创建文件
echo '123' > index.html
# 使用命令查看pod的ip
kubectl get po -o wide
#使用wget访问
wget ip
持久卷(PersistentVolume,PV) 是集群中的一块存储,它可以是物理存储设备、网络存储卷或云提供商的存储服务。PV独立于Pod的生命周期,可以被多个Pod共享。由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。
**持久卷申领(PersistentVolumeClaim,PVC)**是Pod对持久化存储的请求。 它相当于是Pod对PV的申请单。Pod可以通过声明PVC来请求所需的存储资源,并指定访问模式、容量和存储类等要求。Kubernetes会根据PVC的要求去匹配可用的PV,并将其绑定到Pod上。
总结起来,PV是集群中的存储资源,而PVC是Pod对存储资源的抽象化请求。PVC通过与PV的绑定,为Pod提供持久化存储。
需要创建PV。PV定义了集群中的实际存储资源,可以是物理存储设备、网络存储等。然后,使用PVC来申请PV。PVC描述了应用程序对存储资源的需求。
当用户创建一个 PVC 对象后,它会尝试与合适的PV进行绑定。绑定是通过使用PVC的标签选择器与PV的标签进行匹配完成的。如果找到匹配的PV,PVC就会与之绑定。
如果找不到对应的 PV,则需要看 PVC 是否设置 StorageClass 来决定是否动态创建 PV,若没有配置,PVC 就会一致处于未绑定状态,直到有与之匹配的 PV 后才会申领绑定关系。
Pod 将 PVC 当作存储卷来使用,集群会通过 PVC 找到绑定的 PV,并为 Pod 挂载该卷。
Pod 一旦使用 PVC 绑定 PV 后,为了保护数据,避免数据丢失问题,PV 对象会受到保护,在系统中无法被删除。
当PVC不再使用时,可以对其进行回收。回收的方式有两种:保留和删除
保留模式下,PV和相关的存储资源会被保留下来,不会被自动删除。这样可以确保数据的安全性,并提供手动清理的机会。
删除模式下,PV和相关的存储资源会被自动删除。这将释放存储资源供其他应用程序使用。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
spec:
capacity:
storage: 1Gi # pv 的容量
volumeMode: Filesystem # 存储类型为文件系统
accessModes: # 访问模式:ReadWriteOnce-单个读写、ReadWriteMany-多个读写、ReadOnlyMany-多个读
- ReadWriteOnce # 可被单节点独写
persistentVolumeReclaimPolicy: Recycle # 回收策略
storageClassName: slow # 创建 PV 的存储类名,需要与 pvc 的相同
mountOptions: # 加载配置
- hard
- nfsvers=4.1
nfs: # 连接到 nfs
path: /data/nfs/pv001 # 存储路径
server: 192.168.31.101 # nfs 服务地址
kubectl get pv
------------------------
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS
pv001 1Gi RWO Recycle Available slow
状态值 | 说明 |
---|---|
Available | 空闲,未被绑定 |
Bound | 已经被 PVC 绑定 |
Released | PVC 被删除,资源已回收,但是 PV 未被重新使用 |
Failed | 自动回收失败 |
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteOnce # 权限需要与对应的 pv 相同
volumeMode: Filesystem
resources:
requests:
storage: 1Gi # 资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv
storageClassName: slow # 名字需要与对应的 pv 相同
# selector: # 使用选择器选择对应的 pv
# matchLabels:
# env: "dev"
# matchExpressions:
# - {key: environment, operator: In, values: [dev]}
当创建pvc能与pv匹配,后再查看pv状态时候,就会转变为Bound
apiVersion: v1
kind: Pod
metadata:
name: pvc-test-pod
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nfs-pvc-test
volumes:
- name: nfs-pvc-test
persistentVolumeClaim:
claimName: nfs-pvc # pvc 的名称
测试
# 先使用命令查看pod的内网地址
kubectl get po -o wide
--------------------------------
NAME READY STATUS RESTARTS AGE IP
pvc-test-pod 1/1 Running 0 4m36s 10.244.36.124
#调用
curl 10.244.36.124