# 读取为文件

ConfigMap中的条目可以被容器以文件的形式读入，这种情况下，需要将ConfigMap作为卷挂载至Pod中的容器中。

在挂载至容器后，默认情况下，容器会将ConfigMap中的条目的**键**作为文件名，将条目的**值**作为文件内容。

因为ConfigMap中具有多个条目，因此可以通过在`pod.spec.volumes.configMap.items`中进行指定单独挂载的文件。

## 挂载所有文件

将ConfigMap作为卷挂载，需要下面两步：

1. 定义卷：在`spec.volumes.configMap`中指定`name`为预先创建好的ConfigMap资源的名字，即与ConfigMap相关联；
2. 挂载卷：在Pod的`spec.containers.volumeMounts`中指定挂载点和挂载的卷名；

下面举一个例子，在容器的`/etc/nginx/conf.d`下挂载一个名为`config`的configMap卷，该卷与名为`fortune-config`的ConfigMap相关联，容器会将该ConfigMap中的所有条目，以条目的键为文件名，值为文件内容，在挂载点中创建这些文件：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:    # 定义挂载点
    - name: config    # （必须）挂载的卷名
      mountPath: /etc/nginx/conf.d    # （必须）容器中的挂载点，该目录下的原文件都会被隐藏
      readOnly: true
    ports:
      - containerPort: 80
        name: http
        protocol: TCP
  volumes:    # 定义卷
  - name: config    # （必须）卷名
    configMap:    # 创建的是configMap卷
      name: fortune-config    # 需要挂载的ConfigMap的名字
      defaultMode: 0660    # 为挂载的文件设置权限，默认是0644，取值范围为0~0777
```

## 挂载指定文件

同样，挂载卷的方式可以只挂载部分文件，而不是将ConfigMap中的所有文件都挂载进Pod。有两种方法可以实现：

1. 利用`pod.spec.volumeMounts.subPath`将卷中的指定文件挂载至容器中，具体方法可以参考[**卷**](https://yangsijie151104.gitbook.io/k8s-note/juan/juan-lei-xing)这章节；

   优点：挂载点中原本存在的文件不会被隐藏；

   缺点：应用于ConfigMap卷时，被挂载的文件不会随着ConfigMap中条目的更新而更新；
2. 利用`spec.volumes.configMap.items`在**定义卷**时，指定需要被挂载至卷中的条目；

   优点：被挂载的文件会随着ConfigMap中条目的更新而更新；

   缺点：挂载点中原本存在的文件会被隐藏；

这里针对第二种方法进行详细介绍。

下面举一个例子，在容器的`/etc/nginx/conf.d`下挂载一个名为`config`的configMap卷，该卷与名为`fortune-config`的ConfigMap相关联，容器会将该ConfigMap中的键为`my-nginx-config.conf`的条目，并且文件名为`gzip.conf`，值为该文件的内容，在挂载点中创建该文件：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume-with-items
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:    # 定义挂载点
    - name: config    # （必须）挂载的卷名
      mountPath: /etc/nginx/conf.d/my-nginx-config.conf    # （必须）容器中的挂载点，该目录下的源文件都会被隐藏
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:    # 定义卷
  - name: config    # （必须）卷名
    configMap:    # 创建的是configMap卷
      name: fortune-config    # 需要挂载的ConfigMap的名字
      items:    # 仅挂载ConfigMap中的部分条目
      - key: my-nginx-config.conf    # （必须）ConfigMap中条目的键名
        path: gzip.conf    # （必须）挂载至容器中挂载点的相对路径
        mode: 0660    # 为挂载的文件设置权限，默认是0644，取值范围为0~0777
```

## 同步更新

使用ConfigMap卷挂载文件时，可以实现同步更新，即ConfigMap资源中的条目被修改后，挂载至容器中的文件内容也会同步更新。

下面简单了解一下文件被自动更新的过程。

首先检查挂载点，可以看到挂载点中的文件的源头都是`..2020_01_08_11_43_56.932719776`，它是以挂载时间为目录名创建的：

![ConfigMap更新前](https://2906552408-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6Ub8CloS5kJszh6xSR%2Fsync%2F1211eaebe8e548474007a2a1d8d41f62ae3a6a9e.png?generation=1588594613815247\&alt=media)

> my-nginx-config.conf和sleep-interval是ConfigMap中的两个条目

当我们修改ConfigMap中某一个条目的值，再次检查挂载点（不是立刻就有效果的，有延迟），可以看到，文件的源头变成了`..2020_01_08_11_51_52.411250185`，不是之前的目录了：

![ConfigMap更新后](https://2906552408-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6Ub8CloS5kJszh6xSR%2Fsync%2F91eb19541a6c23acc92501ee03a81f07778b3051.png?generation=1588594613953551\&alt=media)
