K8S存储之volume
- 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失一一容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的Volume抽象就很好的解决了这些问题。
1. 背景
- Kubernetes中的卷有明确的寿命一一与封装它的Pod相同。所以,卷的生命比Pod中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当Pod不再存在时,卷也将不复存在。也许更重要的是,Kubernetes
支持多种类型的卷,Pod可以同时使用任意数量的卷。
2. 卷的类型:
Kubernetes支持以下类型的卷:
-
awsElasticBlockStore
、azureDisk
、azureFile
、cephfs
、csi
、downwardAPI
、emptyDir
-
fc
、flocker
、gcepersistentDisk
、gitRepo
、glusterfs
、hostPath
、iscsi
、local
、nfs
-
persistentVolumeclaim
、projected
、portworxVolume
、quobyte
、rbd
、scaleIO
、secret
-
storageos
、vspherevolume
3. emptyDir
-
emptyDir
卷是 Kubernetes 中一种临时性的卷类型,它的生命周期与 Pod 相关联,它通常用于在多个容器之间共享临时数据。 -
以下是 emptyDir 卷的一些使用范围:
-
容器之间共享数据:您可以在一个 Pod 中的多个容器之间使用 emptyDir 卷来共享数据。这对于需要在容器之间传递数据或进行临时存储的应用程序非常有用。
-
简单的缓存:
emptyDir
卷可以用作容器的简单缓存。例如,如果您的应用程序需要在启动时下载一些数据,您可以将这些数据存储在 emptyDir 卷中,以便其他容器可以共享和访问它们,从而避免多个容器都进行下载。 -
临时存储:
emptyDir
卷可以用作临时存储来保存容器运行时需要的临时文件或数据。这些数据将在 Pod 终止时被清除。
-
-
emptyDir
的用法有:- 暂存空间,例如用于基于磁盘的合并排序
- 用作长时间计算崩溃恢复时的检查点
- Web服务器容器提供数据时,保存内容管理器容器提取的文件
apiVersion: v1 #定义了Kubernetes API的版本,这里使用的是v1版本
kind: Pod #定义了资源对象的种类,这里是一个Pod
metadata: #包含了关于Pod的元数据,比如名称等name: my-nginx #定义了pod的名称
spec: #包含了关于Pod的规格信息containers: #定义了Pod中的容器列表- name: my-nginx #定义了容器名称image: nginx:latest #定义容器使用镜像volumeMounts: #这是一个包含卷挂载配置的列表- name: data-volume #这是卷的名称,可以根据需要进行更改mountPath: /data #这是卷在容器内的挂载路径volumes: #这是一个包含卷配置的列表- name: data-volume #这是卷的名称,必须与 volumeMounts 中的名称相匹配。emptyDir: {} #这是一个空的 emptyDir 卷配置
4. hostPath
-
hostPath
卷将主机节点的文件系统中的文件或目录挂载到集群中 -
hostPath的用途如下:
- 运行需要访问Docker内部的容器;使用
/var/lib/docker
的hostPath
- 在容器中运行cAdvisor;使用
/dev/cgroups
的hostPath
- 运行需要访问Docker内部的容器;使用
-
除了所需的path属性之外,用户还可以为
hostPath
卷指定type
值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味看在挂载hostPath卷之前不会执行任何检查。 | |
DirectoryorCreate | 如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为0755,与Kubelet具有相同的组和所有权。 |
Directory | 给定的路径下必须存在目录 |
FileorCreate | 如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设置为0644,与Kubelet具有相同的组和所有权 |
File | 给定的路径下必须存在文件 |
Socket | 给定的路径下必须存在UNIX套接字 |
CharDevice | 给定的路径下必须存在字符设备 |
BlockDevice | 给定的路径下必须存在块设备 |
-
使用这种卷类型是请注意,因为:
- 由于每个节点上的文件都不同,具有相同配置(例如从podTemplate创建的)的pod在不同节点上的行为可能会有所不同
- 当Kubernetes按照计划添加资源感知调度时,将无法考虑
hostPath
使用的资源 - 在底层主机上创建的文件或目录只能由root写入。您需要在特权容器中以root身份运行进程,或修改主机上的文件权限以便写入hostPath卷
vim hostpath-pod.yamlapiVersion: v1 #定义了Kubernetes API的版本。
kind: Pod #定义资源类型为 Pod
metadata: #包含有关资源的元数据,如名称和标签等name: nginx-www #指定 Pod 的名称为 nginx-www
spec: #定义 Pod 的规范,包括容器和卷的配置containers: #定义 Pod 中的容器列表- name: nginx-www #指定容器的名称为 nginx-wwwimage: nginx:latest #指定容器使用的镜像为最新版本的 nginxvolumeMounts: #定义容器中的卷挂载配置- name: nginx-path #指定挂载的卷的名称为 nginx-pathmountPath: /usr/share/nginx/html 指定挂载的卷在容器中的挂载路径为 /usr/share/nginx/htmlvolumes: #定义 Pod 中的卷列表- name: nginx-path #指定卷的名称为 nginx-pathhostPath: #定义 hostPath 类型的卷path: /data/nginx/html #指定要挂载的主机目录或文件路径为 /data/nginx/htmltype: Directory #指定要挂载的主机目录或文件路径为 /data/nginx/html
4.1. 创建:
//创建挂载的主机目录
[root@master1 yaml]# mkdir -p /data/nginx/html
//创建网页文件
[root@master1 yaml]# echo "Welcome to China" > /data/nginx/html/
//创建pod
[root@master1 yaml]# kubectl apply -f hostpath-pod.yaml
[root@master1 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-www 1/1 Running 0 11m 10.244.1.38 node1 <none> <none>[root@master1 yaml]# curl 10.244.1.38
Welcome to China