1. 存储卷基础
1.1 为何需要Volumes
Container
中的⽂件在磁盘上是临时存放的,这给Container
中运⾏的较重要的应⽤程序带来⼀些问题。
1、当容器崩溃时,kubelet
将重新启动⼀个"全新的容器",⽽容器中的此前保存的数据则会丢失。
2、当同⼀Pod运⾏多个容器时,通常需要在这些容器之间共享⽂件。
Volume
是 Kubernetes 抽象出来的对象,主要⽤于解决Pod运⾏时⽂件存放的问题,以及pod中多容器数据共享问题。
1.2 什么是Volume
Volume的核心是一个目录,其中可能存有数据,Pod中的容器可以访问该目录中的数据。使用不同的Volume类型将决定该目录如何形成,以及使用何种介质(Disk、Memory)来存储数据。当然不同的卷类型有着不同的生命周期;
临时卷
:临时卷类型的生命周期与Pod 相同,当Pod 不再存在时,Kubernetes 会销毁临时卷; (一般用作缓存场景)
持久卷
:持久卷可以比 Pod 的存活期长,因为Kubernetes不会销毁持久卷。
💡 说明
任何类型的卷,在容器重启期间数据都不会丢失
1.3 Volume的功能
1.Volume是Pod中能够被多个容器访问的共享目录,可以让容器的数据写到宿主机上或者写文件到网络存储中
2.可以实现容器配置文件集中化定义与管理,通过ConfigMap资源对象来实现.
1.4 Volume的特点
k8s中的Volume与Docker的Volume相似,但不完全相同。
- k8s上Volume定义在Pod上,然后被一个Pod中的多个容器挂载到具体的文件目录下。
- k8s的Volume与Pod生命周期相关而不是容器是生命周期,即容器挂掉,数据不会丢失但是Pod挂掉,数据则会丢失。
- k8s中的Volume支持多种类型的Volume:Ceph、GlusterFS等分布式系统
1.5 Pod配置Volume
Pod使⽤卷方式:
1、第⼀步:在pod.spec.volumes
字段中申明,申明该卷提供的卷类型以及卷名字
2、第二步:在.spec.containers[*].voLumeMounts
字段中声明,将卷挂载到容器的哪个位置。
2. Volume类型
先在Pod上声明一个Volume,然后容器引用该Volume并Mount到容器的某个目录
2.1 临时存储
官方文档,https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
emptyDir定义
emptyDir是一个临时存储卷,与Pod的生命周期绑定到一起,如果Pod被删除了,这意味着数据也被随之删除.
emptyDir主要有如下两个字段
- medium:存储介质的类型,有defaut、Memory,
- default:表示使用节点的磁盘存储介质。 (默认)
- Memory:表示使用基于内存临时文件系统,性能高、但整体可用空间受限于内存,一般用于缓存场景。
- sizeLimit:存储卷的空间限额,默认nil表示不限制,如果medium为Memory时,建议配置此值。
emptyDir作用
(1)可以实现持久化;
(2)同一个Pod的多个容器可以实现数据共享,多个不同的Pod之间不能进行数据通信;
(3)随着Pod的生命周期而存在,当我们删除Pod时,其数据也会被随之删除;
emptyDir优缺点
优点:
(1)可以实现同一个Pod内多个容器之间数据共享;
(2)当Pod内的某个容器被强制删除时,数据并不会丢失,因为Pod没有删除;
缺点:
(1)当Pod被删除时,数据也会被随之删除;
(2)不同的Pod之间无法实现数据共享;
❌ 注意
启动pods后,使用emptyDir其数据存储在"/var/lib/kubelet/pods"路径下对应的POD_ID目录
如,/var/lib/kubelet/pods/${POD_ID}/volumes/kubernetes.io~empty-dir/
emptyDir场景1
[root@kube-master volumes]# cat 1.nginx-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
volumes:
- name: my-volume
emptyDir:
medium: Memory
sizeLimit: "1Gi"
containers:
- name: volume-container
image: nginx:latest
volumeMounts:
- name: my-volume
mountPath: /usr/share/nginx/html
initContainers:
- name: init-container
image: busybox
command: ["sh", "-c", "echo '<html><body><h1>Welcome to my website</h1></body></html>' > /data/index.html"]
volumeMounts:
- name: my-volume
mountPath: /data
[root@kube-master volumes]# cat 1.nginx-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
volumes:
- name: my-volume
emptyDir:
medium: Memory
sizeLimit: "1Gi"
containers:
- name: volume-container
image: nginx:latest
volumeMounts:
- name: my-volume
mountPath: /usr/share/nginx/html
initContainers:
- name: init-container
image: busybox
command: ["sh", "-c", "echo '<html><body><h1>Welcome to my website</h1></body></html>' > /data/index.html"]
volumeMounts:
- name: my-volume
mountPath: /data
emptyDir场景2
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
2.2 本地存储
官方文档,https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
hostPath
会将Pod部署所在宿主机
的目录或文件挂载到Pod中去
作用:
- 容器应用日志需要持久化时,可以使用宿主机的高速文件系统进行存储
- 需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统
- 挂载时区
1.在不同的Node上具有相同配置的Pod可能会因为宿主机上的目录或文件不同导致对Volume上目录或文件的访问结果不一致。
2.如果使用了资源配额管理,则kubernetes无法将hostPath在宿主机上使用的资源纳入管理
type类型:
type类型 | 说明 |
---|---|
DirectoryOrCreate | 卷映射对象是一个目录,如果不存在就创建它 |
Directory | 卷映射对象是一个目录,且必须存在 |
FileOrCreate | 卷映射对象是一个文件,如果不存在创建它 |
File | 卷映射对象是一个文件,且必须存在 |
Socket | 卷映射对象是一个Socket套接字,且必须存在 |
CharDevice | 卷映射对象是一个字符设备,且必须存在(仅 Linux 节点) |
BlockDevice | 卷映射对象是一个块设备,且必须存在(仅 Linux 节点) |
案例
[root@kube-master volumes]# cat 2.hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
volumes:
- name: hostpath-volume
hostPath:
path: /data/hostpathdir/ # 宿主上⽬录位置
type: Directory
containers:
- name: container-hostpath
image: nginx:latest
volumeMounts:
- name: hostpath-volume
mountPath: /usr/share/nginx/html/
[root@kube-master volumes]# cat 2.hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
volumes:
- name: hostpath-volume
hostPath:
path: /data/hostpathdir/ # 宿主上⽬录位置
type: Directory
containers:
- name: container-hostpath
image: nginx:latest
volumeMounts:
- name: hostpath-volume
mountPath: /usr/share/nginx/html/