数据卷定义
为了共享磁盘而创造出来的概念。它是pod的一个组成部分,不是独立的k8s对象,不能单独创建和删除。pod容器中的所有容器都可以使用卷,但必须先将它挂载到容器上,每个容器中都可以在其文件系统的任意位置挂载卷。
运行机制
在kubernetes里,Volume(数据卷)存在明确的生命周期(与包含该数据卷的容器组相同)。因此,Volume(数据卷)的生命周期比同一容器组中任意容器的生命周期要更长,不管容器重启了多少次,数据都能被保留下来。当然,如果容器组退出了,数据卷也就自然退出了。此时,根据容器组所使用的 Volume(数据卷)类型不同,数据可能随数据卷的退出而删除,也可能被真正持久化,并在下次容器组重启时仍然可以使用。
从根本上来说,一个 Volume(数据卷)仅仅是一个可被容器组中的容器访问的文件目录(也许其中包含一些数据文件)。这个目录是怎么来的,取决于该数据卷的类型(不同类型的数据卷使用不同的存储介质)。
使用 Volume(数据卷)时,需要先在容器组中定义一个数据卷,并将其挂载到容器的挂载点上。容器中的一个进程所可访问的文件系统是由容器的镜像和容器所挂载的数据卷共同组成的。Docker镜像将被首先加载到该容器的文件系统,任何数据卷都被在此之后挂载到指定的路径上。Volume(数据卷)不能被挂载到其他数据卷上,或者通过引用其他数据卷。同一个容器组中的不同容器各自独立地挂载数据卷,即同一个容器组中的两个容器可以将同一个数据卷挂载到各自不同的路径上。
通过上图来理解容器组、容器、挂载点、数据卷、存储介质(nfs、PVC、ConfigMap)等几个概念之间的关系:
1、一个容器组可以包含多个数据卷、多个容器
2、一个容器通过挂载点决定某一个数据卷被挂载到容器中的什么路径
3、不同类型的数据卷对应不同的存储介质(图中列出了 nfs、PVC、ConfigMap 三种存储介质
一个卷可以被单个容器使用,但更要关注的是如何在一个pod的多个容器间共享数据:
1、emptyDir:用于存储临时数据的简单空目录
2、hostPath:用于将目录从工作节点的文件系统挂载到pod中
3、gitRepo: 通过检出git仓库的内容来初始化的卷
4、NFS:挂载到pod中的NFS共享卷
5、configMap:用于将k8s部分资源、集群信息公开给pod的特殊类型的卷。它不是用于存储数据,而是用于将k8s元数据公开给运行的pod中的应用程序
如何使用emptyDir卷
概念
1、卷从一个空的目录开始,与pod的生命周期一致,即当删除pod时,卷的内容也删除。
2、运行在pod内的应用程序可以写入它需要的任何文件。
3、容器崩溃时,kubelet并不会删除pod,而仅仅是将容器重启,因此emptyDir 中的数据在容器崩溃并重启后,仍然是存在的。
4、emptyDir卷是最简单的卷类型,但是其他类型的卷都是在它的基础上构建的,在创建空目录后,它们会用数据填充它。
使用场景
1、空白的初始空间,例如合并/排序算法中,临时将数据存在磁盘上
长时间计算中存储检查点(中间结果),以便容器崩溃时,可以从上一次存储的检查点(中间结果)继续进行,而不是从头开始
2、作为两个容器的共享存储,使得第一个内容管理的容器可以将生成的页面存入其中,同时由一个 webserver 容器对外提供这些页面
3、默认情况下,emptyDir 数据卷被存储在 node(节点)的存储介质(机械硬盘、SSD、或者网络存储)上。此外,可以设置 emptyDir.medium 字段为 “Memory”,此时 Kubernetes 将挂载一个 tmpfs(基于 RAM 的文件系统)。tmpfs 的读写速度非常快,但是与磁盘不一样,tmpfs 在节点重启后将被清空,并且向该 emptyDir 写入文件时,将消耗对应容器的内存限制。
描述:
编写一个pod中有两个共用同一个卷的容器,fortune-pod.yaml, 它的功能是:包含两个容器和一个挂载在两个容器中的共用的卷,但在不同的路径上。
当html-generator容器启动时,它每10秒启动一次fortune命令输出到 /var/htdocs/index.html文件,因为卷是在 /var/htdocs 上挂载的,所以 index.html文件被写入卷中,而不是容器的顶层。一旦web-server容器启动,它就开始为 /usr/share/nginx/html 目录中的任意html文件提供服务(这是nginx服务的默认服务文件目录)。因为我们将卷挂载在那个确切的位置,Nginx将运行fortune循环的容器输出的index.html 文件提供服务。
最终的效果是:一个客户端向pod上的80 端口发送一个http请求,将接收当前的fortune消息作为响应。
apiVersion: v1 #必选,版本号,例如v1或者是 apps/v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: fortune
namespace: my-namespace #必选,Pod所属的命名空间
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: html-generator
image: luksa/fortune
imagePullPolicy: IfNotPresent #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
volumeMounts: #挂载到容器内部的存储卷配置
- name: html #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: /var/htdocs #存储卷在容器内mount的绝对路径,应少于512字符
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: 300m #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: 500Mi #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
- name: web-server
image: nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
resources:
limits:
cpu: 400m
memory: 500Mi
ports: #需要暴露的端口库号列表
- containerPort: 80 #容器需要监听的端口号
hostPort: 18080 #容器所在主机需要监听的端口号,默认与Container相同
protocol: TCP #端口协议,支持TCP和UDP,默认TCP
volumes: #在该pod上定义共享存储卷列表
- name: html #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
kubectl apply -f fortune-pod.yaml
kubectl get pods -n my-namespace
NAME READY STATUS RESTARTS AGE
fortune 0/2 Pending 0 2m23s
kubectl describe pod fortune -n my-namespace
kubectl -- exec -it fortune /bin/bash -n my-namespace
root@fortune:/var/htdocs# cat index.html
It usually takes more than three weeks to prepare a good impromptu speech. -- Mark Twain
root@fortune:/var/htdocs# cat /var/htdocs/index.html
The whole world is a tuxedo and you are a pair of brown shoes. -- George Gobel
root@fortune:/var/htdocs# cat /var/htdocs/index.html
Try to value useful qualities in one who loves you.
root@fortune:/var/htdocs# cat /var/htdocs/index.html
Q: Why don't Scotsmen ever have coffee the way they like it? A: Well, they like it with two lumps of sugar. If they drink it at home, they only take one, and if they drink it while visiting, they always take three. root@fortune:/var/htdocs#
NFS
概念
NFS(Network File System)即网络文件系统,允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。
机制
NFS在文件传送或信息传送过程中依赖于 RPC(Remote Procedure Call) 协议,即远程过程调用, NFS 的各项功能都必须要向 RPC 来注册,如此一来 RPC 才能了解 NFS 这个服务的各项功能 Port、PID、NFS 在服务器所监听的 IP 等,而客户端才能够透过 RPC 的询问找到正确对应的端口,所以,NFS 必须要有 RPC 存在时才能成功的提供服务,简单的理解二者关系:NFS是 一个文件存储系统,而 RPC 是负责信息的传输。
特点
1、可以在加载 NFS 数据卷前就在其中准备好数据;
2、可以在不同容器组之间共享数据;
3、可以被多个容器组加载并同时读写;
场景
1、存储日志文件
2、mysql的data目录(测试环境中)
3、用户上传的临时文件
底层存储解耦
k8s将存储管理抽象成如何提供存储以及如何使用存储两个点:PersistentVolume 与PersistentVolumeClaim。PersistentVolume只能定义在集群层面,聚焦于集群如何提供存储;PersistentVolumeClaim 必须定义在与应用程序相同的名称空间中,聚焦于应用程序如何使用存储。