存储卷基础
层级关系
从概念上讲,存储卷是可供Pod中的所有容器访问的目录
- Pod规范中声明的存储卷来源决定了目录的创建方式、使用的存储介质以及目录的初始内容
- 存储卷插件(存储驱动)决定了支持的后端存储介质或存储服务,例如hostPath插件使用宿主机文件系 统,而nfs插件则对接指定的NFS存储服务等
- kubelet内置支持多种存储卷插件
- Pod在规范中需要指定其包含的卷以及这些卷在容器中的挂载路径
- 存储卷对象并非Kubernetes系统一等公民,它定义在Pod上,因而卷本身的生命周期同Pod一样
- 删除pod 卷也就删除了(卷的定义删除 但是后端存储的实际数据不会被删除 例如nfs)
- 后端的存储及相关数据的生命周期通常要取决于存储介质
存储卷类型和相应的插件
In-Tree存储卷插件 (内置)
kubectl explain pods.spec.volumes
一 临时存储卷 emptyDir
删除pod就没有了 主要是提供缓存 或者数据交换
二 节点本地存储卷
临时需要的场景 (只能在节点上持久)
- hostPath
- pod删除了 但是数据不会删除
- 节点没了 数据也没了 pod调度到其他节点的话 数据就找不到了
- local (可以支持pv pvc)
- pod重新调度在其他节点时 数据也会失效
三 网络存储卷(持久化存储)的类型
1 文件系统 类型
- NFS
- GlusterFS
- CephFS和Cinder
2 块设备 类型
- iSCSI
- FC
- RBD(ceph image 存储)
- vSphereVolume
3 存储平台 类型
- Quobyte
- PortworxVolume
- StorageOS
- ScaleIO
4 云存储 类型
- awsElasticBlockStore
- gcePersistentDisk
- azureDisk和azureFile
四 特殊存储卷
- Secret
- ConfigMap
- DownwardAPI pod外部的信息 注入到pod中
- Projected
五 扩展接口
CSI 当前推荐使用的方式
- 可以结合NFS使用
FlexVolume(弃用了)
Out-of-Tree存储卷插件 (外置)
- 经由CSI或FlexVolume接口扩展出的存储系统称为Out-of-Tree类的存储插件
- 公有云服务商提供的存储服务
存储卷资源规范
定义存储卷
- 存储卷对象并非Kubernetes系统一等公民,它需要定义在Pod上
- 卷本身的生命周期同Pod,但其后端的存储及相关数据的生命周期通常要 取决于存储介质
存储卷的配置由两部分组成
- 通过.spec.volumes字段定义在Pod之上的存储卷列表
- 它经由特定的存储卷 插件并结合特定的存储供给方的访问接口进行定义
- 嵌套定义在容器的volumeMounts字段上的存储卷挂载列表
- 它只能挂载当前Pod对象中定义的存储卷
volumes 配置规范
spec:
volumes:
# 卷名称标识,仅可使用DNS标签格式的字符,在当前Pod中必须惟一;
- name <string>
# 存储卷插件VOL_TYPE <Object>
VOL_TYPE <Object>
# 存储卷插件及具体的目标存储供给方的相关配置;
containers:
- name: …
image: …
volumeMounts:
- name <string>
# 要挂载的存储卷的名称,必须匹配存储卷列表中某项的定义;
mountPath <string>
# 容器文件系统上的挂载点路径;
readOnly <boolean>
# 是否挂载为只读模式,默认为否;
subPath <string>
# 挂载存储卷上的一个子目录至指定的挂载点;
subPathExpr <string>
# 挂载由指定的模式匹配到的存储卷的文件或目录至挂载点;
mountPropagation <string>
# 挂载卷的传播模式;
emptyDir 临时存储卷
- Pod对象上的一个临时目录
- 在Pod对象启动时即被创建,而在Pod对象被移除时一并被删除
适用场景:
- 缓存 数据交互 不支持持久
- 同一Pod内的多个容器间文件共享
- 作为容器数据的临时存储目录用于数据缓存系统
配置参数
- medium:此目录所在的存储介质的类型,可用值为"default"或 "Memory"
- sizeLimit:当前存储卷的空间限额,默认值为nil,表示不限制
样例-emptyDir 临时存储卷
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: test
spec:
containers:
- name: store
image: ikubernetes/demoapp:v1.0
volumeMounts:
- name: data
mountPath: /data1
- name: read
image: ikubernetes/demoapp:v1.0
volumeMounts:
- name: data
mountPath: /data2
volumes:
- name: data
emptyDir:
medium: Memory
sizeLimit: 16Mi
kubectl exec -ti pod-demo -n test /bin/sh
样例2-两个容器共享存储(emptyDir 临时存储卷)
# 定义重启策略
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: test
spec:
containers:
- name: server
image: ikubernetes/demoapp:v1.0
volumeMounts:
- name: data
mountPath: /sensorsdata/
readOnly: false
- name: client
image: ikubernetes/admin-box:v1.2
command: ['/bin/sh', '-c', 'sleep 9999']
volumeMounts:
- name: data
mountPath: /mydata
readOnly: true
volumes:
- name: data
emptyDir:
medium: Memory
sizeLimit: 16Mi
进入对应的容器
kubectl exec -ti -n test -c server pod-demo /bin/sh
kubectl exec -ti -n test -c client pod-demo /bin/sh
hostPath存储卷介绍
只能在节点上持久
- 将Pod所在节点上的文件系统的某目录用作存储卷
- 数据的生命周期与节点相同
适用场景
- 实现node节点上的持久性, 临时需要维持node上 一段时间的持久性
- 不适用集群内的数据持久
配置参数
- path:指定工作节点上的目录路径,必选字段
- type:指定节点之上存储类型
查看参数
root@k8s-master01:~# kubectl explain pods.spec.volumes.hostPath
KIND: Pod
VERSION: v1
RESOURCE: hostPath <Object>
DESCRIPTION:
hostPath represents a pre-existing file or directory on the host machine
that is directly exposed to the container. This is generally used for
system agents or other privileged things that are allowed to see the host
machine. Most containers will NOT need this. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
Represents a host path mapped into a pod. Host path volumes do not support
ownership management or SELinux relabeling.
FIELDS:
path <string> -required-
path of the directory on the host. If the path is a symlink, it will follow
the link to the real path. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
type <string>
type for HostPath Volume Defaults to "" More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
样例-hostPath卷
apiVersion: v1
kind: Pod
metadata:
name: volumes-hostpath-demo
labels:
app: redis
spec:
containers:
- name: redis
image: redis:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data
name: redisdata
volumes:
- name: redisdata
hostPath:
path: /appdatas/redis/
type: DirectoryOrCreate
type参数解释
- DirectoryOrCreate 路径如果不存在 需要进行创建
- Directory 必须是个路径 并且存在
删除pod后 主机上的/appdatas/redis/仍然还在
NFS存储卷 (外置存储)
- nfs存储卷
- 将nfs服务器上导出(export)的文件系统用作存储卷
- nfs是文件系统级共享服务,它支持多路挂载请求,可由多个Pod对象同时 用作存储卷后端
- 需要准备nfs server, 每个节点需要安装nfs client
- 配置参数
- server :NFS服务器的IP地址或主机名,必选字段
- path :NFS服务器导出(共享)的文件系统路径,必选字段
- readOnly :是否以只读方式挂载,默认为false
root@k8s-master01:~/pratice# kubectl explain pods.spec.volumes.nfs
KIND: Pod
VERSION: v1
RESOURCE: nfs <Object>
DESCRIPTION:
nfs represents an NFS mount on the host that shares a pod's lifetime More
info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do
not support ownership management or SELinux relabeling.
FIELDS:
path <string> -required-
path that is exported by the NFS server. More info:
https://kubernetes.io/docs/concepts/storage/volumes#nfs
readOnly <boolean>
readOnly here will force the NFS export to be mounted with read-only
permissions. Defaults to false. More info:
https://kubernetes.io/docs/concepts/storage/volumes#nfs
server <string> -required-
server is the hostname or IP address of the NFS server. More info:
https://kubernetes.io/docs/concepts/storage/volumes#nfs
样例-nfs存储卷
nfs搭建方法 juejin.cn/post/720614…
yaml示例
apiVersion: v1
kind: Pod
metadata:
name: volumes-hostpath-demo
labels:
app: redis
spec:
containers:
- name: redis
image: redis:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data
name: nfsdata
volumes:
- name: nfsdata
nfs:
server: 172.30.66.169
path: /sensors/storage
readOnly: false