# 卷类型

Kubernetes支持许多不同的卷类型，不同的云服务厂商都会各自开发不同的卷设备类型，因此这里仅对部分通用的卷类型进行说明：

* [**emptyDir**](https://yangsijie151104.gitbook.io/k8s-note/juan/juan-lei-xing/emptydir) — 用于存储临时数据的简单空目&#x5F55;**（生命周期与Pod一致，无法实现持久化存储）**；
* [**gitRepo**](https://yangsijie151104.gitbook.io/k8s-note/juan/juan-lei-xing/gitrepo) — 通过从Git仓库中的内容初始化&#x5377;**（生命周期与Pod一致，无法实现持久化存储）**；
* [**hostPath**](https://yangsijie151104.gitbook.io/k8s-note/juan/juan-lei-xing/hostpath) — 将Node上的目录挂载至Pod中的容器&#x4E2D;**（仅适用于单Node集群）**；
* [**nfs**](https://yangsijie151104.gitbook.io/k8s-note/juan/juan-lei-xing/nfs) — nfs共享卷；
* gcePersistentDisk（Google高效能型存储磁盘卷）、awsElasticBlockStore（Amazon Web服务弹性块存储卷）、azureDisk（Microsoft Azure此判断） — 云服务商提供的特定存储类型；
* cinder、cephfs、iscsi、flocker、glusterfs、quobyte、rbd、flexVolume、vsphere-Volume、photonPersistentDisk、scaleIO — 一些网络存储；
* [**persistentVolumeClaim**](https://yangsijie151104.gitbook.io/k8s-note/juan/pvc) — 通过持久卷声明来申请持久卷设&#x5907;**（一种特殊的可挂载设备）**；
* [**configMap**](https://yangsijie151104.gitbook.io/k8s-note/configmap-he-secret/configmap/cong-configmap-zhong-du-qu-pei-zhi/configmap-du-qu-wei-wen-jian)、[**secret**](https://yangsijie151104.gitbook.io/k8s-note/configmap-he-secret/secret/secret-lei-xing/generic-lei-xing-secret) — 配置数据和敏感数据的挂&#x8F7D;**（一种特殊的可挂载设备）**；
* [**downwardAPI**](https://yangsijie151104.gitbook.io/k8s-note/huo-qu-ji-qun-yuan-shu-ju/9.-huo-qu-ji-qun-yuan-shu-ju/downwardapi-juan) — 通过Kubernetes的API获得集群的元数&#x636E;**（一种特殊的可挂载设备）**；

{% hint style="info" %}
**Tips:** Pod所支持的卷类型，及其详细配置选项可以通过Pod的`spec.volumes`中进行查看；各卷类型支持的相关配置，则可通过`spec.volumes.{卷类型}`查看，如查看emptyDir卷支持的配置，则查看`spec.volumes.emptyDir`即可。
{% endhint %}

## 定义卷及挂载卷

由于每一种类型的卷的定义都不相同，因此这里仅对通用的地方做一个概括，具体的定义方式还需看各章的配置以及使用`explain`命令查看。

卷在Kubernetes中不是以一种资源的形式出现的，因此其定义是在Pod的`spec.volumes`中定义的；在定义好之后，再在Pod的`spec.containers.volumeMounts`中进行挂载。

因此总结如下两步：

1. 定义卷：在Pod的`spec.volumes`中定义卷的类型，以及卷的相关配置；其中**卷名**是必须的，因为在挂载时需要用到；
2. 挂载卷：在Pod的`spec.containers.volumeMounts`中进行挂载，指定容器中的挂载点，以及挂载的**卷名**；

### 仅挂载卷内指定文件且不隐藏挂载点中的原文件

上面的这种方式，是以全覆盖的形式，即将卷中的所有文件，都挂载至挂载点下，并且挂载点中若原先有文件存在，会被隐藏处理，这就与Linux中挂载时类似。

下面介绍一种方式，可以仅挂载卷内指定的文件，并且不会隐藏挂载点中的原文件。

在第二步的挂载卷中，Pod的`spec.containers.volumeMounts.subPath`中指定需要挂载的文件名，并且`spec.containers.volumeMounts.mountPath`中的挂载点指定的是文件路径，而不是目录路径。

下面举个例子：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-hostpath-test-subpath
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:    # 定义挂载点
    - name: hostpath    # 卷名
      mountPath: /etc/nginx/conf.d/aaa.txt    # 挂载点，即将a.txt挂载至容器中，并改名为aaa.txt
      readOnly: true
      subPath: a.txt    # 将hostPath卷中的a.txt文件挂载至容器中
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:    # 定义卷
  - name: hostpath    # 卷名
    hostPath:    # hostPath类型的卷
      path: "/tmp/test_hostpath_dir"
```
