k8s持久化存储-常见的存储卷介绍
当在Kubernetes中部署应用程序时,数据通常存储在容器内部的文件系统中。然而,容器的生命 周期是临时的,当容器被删除或重新启动时,容器内的数据也会丢失。
为了解决这个问题,需要在Kubernetes中实现数据持久化。数据持久化是将数据保存到持久化存 储介质(如磁盘)上,以便在容器被重新创建或迁移到其他节点时仍然可用。
数据持久化的场景包括: 1. 数据存储:许多应用程序需要保存用户生成的数据,如文件、图片、日志等。通过数据持久化, 可以确保这些数据在容器销毁或重启后仍然存在。 2. 数据共享:在某些情况下,多个容器或Pod可能需要访问和共享相同的数据。适通过将数据存储 在持久化卷中,可以使多个容器之间共享数据,实现数据一致性和共享访问。 3. 数据备份和恢复:持久化存储解决方案通常提供数据备份和恢复机制,以防止数据丢失。这对于 保护重要数据、应对故障或恢复到先前的状态非常重要。 4. 数据迁移和扩展:在Kubernetes集群中,可能需要扩展应用程序到多个节点或迁移到其他集 群。通过将数据存储在持久化卷中,可以方便地将数据与应用程序一起迁移到新的环境,天无需担 心数据丢失。 5. 数据安全:某些行业或应用程序对数据的安全性有严格的要求。持久化存储解决方案通常提供数 据加密和访问控制功能,以确保数据在传输和存储过程中的安全性。
实战:k8s持久化存储方案-emptyDir
在Kubernetes中,EmptyDir是一种卷(Volume),它提供了一个空目录来供容器使用。 EmptyDir卷在Pod级别上创建,与Pod的生命周期绑定。EmptyDir卷在Pod被删除或重新启动时 会被清空,因此它不是持久化的存储解决方案。
EmptyDir卷的使用场景包括: 1. 临时文件共享:如果多个容器需要在同一个Pod中进行临时文件共享,EmptyDir卷是一个简 便的解决方案。容器可以将文件写入EmptyDir卷,并且其他容器可以读取和修改这些文件。 当Pod被删除或重启时,EmptyDir卷中的文件会被清空。 2. 共享数据:某些应用程序可能需要在容器之间共享一些中间结果或临时数据。EmptyDir卷可以 作为容器之间的临时数据交换机制。容器可以将数据写入EmptyDir卷,其他容器可以读取和 处理这些数据,从而实现数据共享和协作。 3. 缓存:EmptyDir卷可以用作容器的缓存存储。某些应用程序可能需要将频繁访问的数据缓存到 本地存储中,以提高性能。EmptyDir卷提供了一个临时的、高速的存储介质来存储缓存数据, 提供快速的读取和写入操作。
当在Kubernetes中使用存储卷(Volume),需要经历以下步骤:
- 定义Pod的Volume:在Pod的配置中定义一个Volume,指定它要关联到哪个存储上。可 以使用不同类型的Volume,如EmptyDir、HostPath、PersistentVolumeClaim等,具体 选择取决于需求。
- 在容器中使用Volume·Mounts:在Pod的配置中,为每个容器定义Volume·Mounts,将 Volume挂载到容器内部的指定路径上。这样容器就能够访问和操作Volume中的数据。
- 通过Volume实现数据持久化和共享:一旦Volume被挂载到容器中,容器就可以将数据写入 Volume或从Volume中读取数据。这使得数据能够在容器的生命周期内持久存在,并且可以 被其他容器共享和访问。
示例: pod-empty.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-empty
spec:
containers:
- name: container-empty
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- emptyDir: {}
name: cache-volume
- 获取uid
$ kubectl get pod pod-empty -oyaml | grep uid
uid: ffca5db6-ec43-4736-b4e1-a1eb33c8d1ce
- 获取临时目录
$ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-empty 1/1 Running 0 3m45s 10.250.209.145 xuegod64 <none> <none>
# 在xuegod64去执行
# 查看目录
$ tree /var/lib/kubelet/pods/ffca5db6-ec43-4736-b4e1-a1eb33c8d1ce
$ cd /var/lib/kubelet/pods/ffca5db6-ec43-4736-b4e1-a1eb33c8d1ce/volumes/kubernetes.io~empty-dir/cache-volume/
# 创建文件
$ touch hello
- 在容器中能查看到了
# 查看创建的文件
$ kubectl exec -it pod-empty -- ls /cache
hello
实战:k8s持久化存储方案-hostPath
hostPath是:Kubernetes·中的一种卷类型,它将主机节点上的文件或目录挂载到容器中。使用· hostPath,可以将主机节点上的文件系统路径直接映射到容器的文件系统中。这种方式在某些情况下非 常有用,但也需要谨慎使用,因为它具有一些潜在的限制和风险。
以下是·hostPath·的一些关键特点和适用场景: 1. 直接访问主机文件系统:hostPath·卷允许容器直接访问主机节点上的文件系统。这对于需要访 问主机节点上的特定文件或目录的应用程序非常有用。1例如,某些日志收集器可能需要访问主机 上的日志文件。 2. 主机依赖性:hostPath·卷的挂载是与特定主机节点紧密关联的,因此在调度·Pod·时需要特别 注意。如果·Pod·被调度到另一个主机节点上,它将无法访问之前挂载的主机文件系统。 3. 危险性:hostPath·卷的使用需要谨慎,因为容器可以访问主机节点上的任何文件或目录,包括 敏感的系统文件。此外,如果多个·Pod·使用相同的·hostPath·卷并且并发写入同一个文件 可能会导致冲突和数据损坏。 4. 开发和测试环境:hostPath·卷特别适用于开发和测试环境,因为它可以方便地将主机节点上的 文件或目录映射到容器中,从而加快开发和测试工作流程。
需要注意的是,hostPath·卷并不适合生产环境中的大多数用例。在生产环境中,建议使用更可靠和 弹性的持久化存储方案,例如网络存储卷(NFS)、云提供商的块存储或对象存储等。
示例:pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
containers:
- name: container-empty
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /test-volume
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data1
type: DirectoryOrCreate
$ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hostpath 1/1 Running 0 25s 10.250.158.3 xuegod62 <none> <none>
# 在xuegod62节点上执行
$ tree /data1
$ cd /data1
$ touch hello
# 在容器中查看
$ kubectl exec -it pod-hostpath -- ls /test-volume
hello
实战:k8s持久化存储方案-NFS·a
相关参考: https://todoit.tech/k8s/nfs/#%E6%B7%BB%E5%8A%A0-helm-%E4%BB%93%E5%BA%93
-
安装
# 更新软件包列表 sudo apt update # 安装 NFS 服务器软件 sudo apt install -y nfs-kernel-server # 创建共享目录 sudo mkdir -p /data/nfs sudo chown nobody:nogroup /data/nfs sudo chmod 777 /data/nfs -
配置访问
/etc/exports
/data/nfs *(rw,sync,no_subtree_check,no_root_squash)
# 或限制ip
/data/nfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
- 应用配置
# 重新加载配置
sudo exportfs -ra
# 导出共享目录
sudo exportfs -a
# 重启 NFS 服务
sudo systemctl restart nfs-kernel-server
# 设置开机自启
sudo systemctl enable nfs-kernel-server
- 客户端安装
sudo apt install -y nfs-common
linux 测试挂载
mount -t nfs 192.168.8.132:/data/nfs /nfs
- 官方storage class
https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#nfs
- 其他
https://www.zhaowenyu.com/kubernetes-doc/storage/nfs.html
- 遇见问题
客户端出现
mount.nfs: access denied by server while mounting
#监控nfs服务器系统日志
$ sudo journalctl -f
Jun 15 10:32:22 zhr rpc.mountd[24332]: refused mount request from 192.168.42.17 for /data/mytest (/data/mytest): illegal port 57564
所以 配置/etc/exports 加上 insecure 标识
/data/nfs *(insecure,rw,sync,no_subtree_check,no_root_squash)