# 意义
Kubernetes引入Volume资源来解决以下问题:
- 容器中的文件在磁盘上是临时存放的,kubelet重启容器后,文件将会丢失;
- 在运行多个容器的Pod内实现文件共享。
# 配置
一个典型的有挂载卷的Pod配置如下:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: docker.io/nginx:latest
name: nginx
volumeMounts:
- mountPath: /nginx-master-data
name: test-volume
volumes:
- name: test-volume
emptyDir: {}
-
spec.containers.volumeMounts.mountPath
字段定义了Volume在容器中的挂载位置; - 字段
spec.containers.volumeMounts
与spec.volumes.name
必须相同; -
spec.volumes.emptyDir
代表Volume的类型。
类型
Volume的核心是包含一些数据的一个目录,Pod中的容器可以访问该目录。Volume的类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。
emptyDir
在当前Pod对应的目录创建了一个空的文件夹,这个文件夹会随着 Pod 的删除而删除。
hostPath
将Pod所在节点文件系统上的文件或目录挂载到Pod中。
nfs
将NFS(Network File System)挂载到Pod中,可以在不同节点上的不同Pod之间共享数据并被多个Pod同时读写。当Pod被移除时,将仅仅卸载nfs数据卷,Volume中的数据仍将被保留;
configMap
提供了向Pod注入配置数据的方法。ConfigMap对象中存储的数据可以被configMap类型的卷引用,然后被Pod中运行的应用使用。其典型配置如下:
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_key
path: log_path
名为log-config的ConfigMap对象以卷的形式挂载到Pod中。其中,挂载的目录为ConfigMap对象中键为log_key的所有内容(spec.volumes.configMap.items.key
),路径为Pod中的/etc/config/log_path(spec.containers.volumeMounts.mountPath
/spec.volumes.configMap.items.path
)。
secret
secret类型的数据卷可以用来注入敏感信息(例如密码)到Pod中。
persistentVolumeClaim(PVC)
常见的Volume类型,如emptyDir、hostPath、configMap和secret等,与所属的Pod具有相同的生命周期。为了实现数据的持久化存储,我们需要使用persistentVolumeClaim类型的Volume“申领”持久卷PV(PersistentVolume)并挂载到Pod中。
PV、PVC和存储类(StorageClass)三者之间的关系如下:
-
PV是集群中的持久化存储资源,通常由集群管理员创建和管理;
-
StorageClass用于用于描述集群中可以提供的PV的类型。若PVC关联了StorageClass且配置符合要求,StorageClass也可以根据自身配置中的
provisioner
、parameters
和reclaimPolicy
字段动态创建PV;apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: standard provisioner: kubernetes.io/aws-ebs parameters: type: gp2 reclaimPolicy: Retain allowVolumeExpansion: true mountOptions: - debug volumeBindingMode: Immediate
-
StorageClass配置中的
provisioner
字段定义了使用哪种数据卷插件来创建PV(大多数由云服务商提供),parameters
字段则定义了数据卷类型; -
StorageClass配置中的
reclaimPolicy
字段定义了PV的回收策略,默认为Delete,代表移除PV及其关联的外部存储介质。若设置为Retain,则PVC删除后PV及PV中的数据依然存在,只是不会再被其他PVC申领; -
PVC是申领PV资源的请求,通常由应用程序发出并指定StorageClass和需求的Volume空间大小;
数据卷内子路径
定义spec.containers.volumeMounts.subPath
字段,可以使容器在挂载Volume时指向数据卷内部的一个子路径,而不是直接指向数据卷的根路径。在下面的例子中,一个运行LAMP(Linux Apache Mysql PHP)应用的Pod使用了一个共享数据卷,HTML内容映射到数据卷内部的html目录,而数据库的内容映射到了mysql目录:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
readOnly: false
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
readOnly: false
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
挂载传播
Volume的传播能力允许将容器挂载的Volume共享到同一Pod中的其他容器,甚至共享到同一节点上的其他Pod。由Pod配置中的spec.containers.volumeMounts.mountPropagation
字段控制。可选的取值有:
-
None:默认值。在数据卷被挂载到容器之后,此挂载卷将不会接受主机或其他容器后续在此卷或其任何子目录上执行的挂载操作。类似的,容?所创建的卷挂载在主机上也不可见。
-
HostToContainer:在数据卷被挂载到容器之后,宿主机向该数据卷对应目录添加挂载时,容器是可见的。
-
Bidirectional:在数据卷被挂载到容器之后,宿主机向该数据卷对应目录添加挂载时,容器是可见的;同时,从容器中向该数据卷创建挂载,宿主机同样可见。如果在容器内进行不合适的挂载,可能影响宿主机的操作系统正常执行。