7.3. 使用卷来持久保留容器数据

容器中的文件是临时的。因此,当容器崩溃或停止时,其数据就会丢失。您可以使用来持久保留 pod 中容器使用的数据。卷是在 pod 的生命周期内保存数据的一个目录,可供 pod 中的容器访问。

7.3.1. 了解卷

卷是挂载的文件系统,供 pod 及其容器使用,可以通过多个主机上本地或网络附加存储端点来支持。默认情况下,容器不具持久性;重启之后,其中的内容会被清除。

为确保卷上的文件系统不包含任何错误,并在出现错误时尽可能进行修复,OpenShift Container Platform 在调用 mount 实用程序之前会先调用 fsck。在添加卷或更新现有卷时会出现这种情况。

最简单的卷类型是 emptyDir,这是单一机器上的一个临时目录。管理员也可以允许您请求自动附加到 pod 的持久性卷。

注意

如果集群管理员启用了 FSGroup 参数,则 emptyDir 卷存储可能会受到基于 pod FSGroup 的配额的限制。

7.3.2. 使用 OpenShift Container Platform CLI 操作卷

您可以使用 CLI 命令 oc set volume,为任何使用 pod 模板的对象(如复制控制器或部署配置)添加和移除卷和卷挂载。您还可以列出 pod 中的卷,或列出使用 pod 模板的任何对象。

oc set volume 命令使用以下通用语法:

$ oc set volume <object_selection> <operation> <mandatory_parameters> <options>
对象选择
oc set volume 命令中为 object_selection 参数指定以下内容之一:

表 7.1. 对象选择

语法描述示例

<object_type> <name>

选择类型为 <object_type><name>

deploymentConfig registry

<object_type>/<name>

选择类型为 <object_type><name>

deploymentConfig/registry

<object_type>--selector=<object_label_selector>

选择与给定标签选择器匹配且类型为 <object_type> 的资源。

deploymentConfig--selector="name=registry"

<object_type> --all

选择类型为 <object_type> 的所有资源。

deploymentConfig --all

-f--filename=<file_name>

用于编辑资源的文件名、目录或文件 URL。

-f registry-deployment-config.json

操作
oc set volume 命令中的 operation 参数指定 --add--remove
必要参数
所有必需的参数都特定于所选操作,并在后续小节中阐述。
选项
所有选项都特定于所选操作,并在后续小节中讨论。

7.3.3. 列出 pod 中的卷和卷挂载

您可以列出 pod 或 pod 模板中的卷和卷挂载:

流程

列出卷:

$ oc set volume <object_type>/<name> [options]

列出卷支持的选项:

选项描述默认

--name

卷的名称。

 

-c, --containers

按名称选择容器。它还可以使用通配符 '*’ 来匹配任意字符。

'*'

例如:

  • 列出 pod p1 的所有卷:

    $ oc set volume pod/p1
  • 列出在所有部署配置中定义的卷 v1

    $ oc set volume dc --all --name=v1

7.3.4. 将卷添加到 pod

您可以将卷和卷挂载添加到 pod。

流程

将卷和/或卷挂载添加到 pod 模板中:

$ oc set volume <object_type>/<name> --add [options]

表 7.2. 添加卷时支持的选项

选项描述默认

--name

卷的名称。

若未指定,则自动生成。

-t, --type

卷源的名称。支持的值有 emptyDirhostPathsecretconfigmappersistentVolumeClaimprojected

emptyDir

-c, --containers

按名称选择容器。它还可以使用通配符 '*’ 来匹配任意字符。

'*'

-m, --mount-path

所选容器内的挂载路径。不要挂载到容器 root、/ 或主机和容器中相同的任何路径。如果容器有足够权限,可能会损坏您的主机系统(如主机的 /dev/pts 文件)。使用 /host 挂载主机是安全的。

 

--path

主机路径。--type=hostPath 的必要参数。不要挂载到容器 root、/ 或主机和容器中相同的任何路径。如果容器有足够权限,可能会损坏您的主机系统(如主机的 /dev/pts 文件)。使用 /host 挂载主机是安全的。

 

--secret-name

secret 的名称。--type=secret 的必要参数。

 

--configmap-name

configmap 的名称。--type=configmap 的必要参数。

 

--claim-name

持久性卷声明的名称。--type=persistentVolumeClaim 的必要参数。

 

--source

以 JSON 字符串表示的卷源详情。如果 --type 不支持所需的卷源,则建议使用此参数。

 

-o, --output

显示修改后的对象,而不在服务器上更新它们。支持的值有 jsonyaml

 

--output-version

输出给定版本的修改后对象。

api-version

例如:

  • 将新卷源 emptyDir 添加到 registry DeploymentConfig 对象中:

    $ oc set volume dc/registry --add
    提示

    您还可以应用以下 YAML 来添加卷:

    例 7.1. 带有添加卷的部署配置示例

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: registry
      namespace: registry
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes: 1
            - name: volume-pppsw
              emptyDir: {}
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
    1
    添加卷源 emptyDir
  • 为复制控制器 r1 添加含有 secret secret1 的卷 v1 并挂载到容器中的 /data

    $ oc set volume rc/r1 --add --name=v1 --type=secret --secret-name='secret1' --mount-path=/data
    提示

    您还可以应用以下 YAML 来添加卷:

    例 7.2. 带有添加的卷和 secret 的复制控制器示例

    kind: ReplicationController
    apiVersion: v1
    metadata:
      name: example-1
      namespace: example
    spec:
      replicas: 0
      selector:
        app: httpd
        deployment: example-1
        deploymentconfig: example
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: httpd
            deployment: example-1
            deploymentconfig: example
        spec:
          volumes: 1
            - name: v1
              secret:
                secretName: secret1
                defaultMode: 420
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              volumeMounts: 2
                - name: v1
                  mountPath: /data
    1
    添加卷和 secret。
    2
    添加容器挂载路径。
  • 使用声明名称 pvc1 将现有持久性卷 v1 添加到磁盘上的部署配置 dc.json,将该卷挂载到容器 c1 中的 /data 并更新服务器上的 DeploymentConfig

    $ oc set volume -f dc.json --add --name=v1 --type=persistentVolumeClaim \
      --claim-name=pvc1 --mount-path=/data --containers=c1
    提示

    您还可以应用以下 YAML 来添加卷:

    例 7.3. 添加了持久性卷的部署配置示例

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: example
      namespace: example
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes:
            - name: volume-pppsw
              emptyDir: {}
            - name: v1 1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts: 2
                - name: v1
                  mountPath: /data
    1
    添加名为"pvc1"的持久卷声明。
    2
    添加容器挂载路径。
  • 为所有复制控制器添加基于 Git 存储库 https://github.com/namespace1/project1 且具有修订 5125c45f9f563 的卷 v1

    $ oc set volume rc --all --add --name=v1 \
      --source='{"gitRepo": {
                    "repository": "https://github.com/namespace1/project1",
                    "revision": "5125c45f9f563"
                }}'

7.3.5. 更新 pod 中的卷和卷挂载

您可以修改 pod 中的卷和卷挂载。

流程

使用 --overwrite 选项更新现有卷:

$ oc set volume <object_type>/<name> --add --overwrite [options]

例如:

  • 使用现有持久性卷声明 pvc1 替换复制控制器 r1 的现有卷 v1

    $ oc set volume rc/r1 --add --overwrite --name=v1 --type=persistentVolumeClaim --claim-name=pvc1
    提示

    您还可以应用以下 YAML 来替换卷:

    例 7.4. 使用名为 pvc1的持久性卷声明的复制控制器示例

    kind: ReplicationController
    apiVersion: v1
    metadata:
      name: example-1
      namespace: example
    spec:
      replicas: 0
      selector:
        app: httpd
        deployment: example-1
        deploymentconfig: example
      template:
        metadata:
          labels:
            app: httpd
            deployment: example-1
            deploymentconfig: example
        spec:
          volumes:
            - name: v1 1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts:
                - name: v1
                  mountPath: /data
    1
    将持久卷声明设置为 pvc1
  • 将卷 v1DeploymentConfig d1 挂载点更改为 /opt

    $ oc set volume dc/d1 --add --overwrite --name=v1 --mount-path=/opt
    提示

    您还可以应用以下 YAML 以更改挂载点:

    例 7.5. 将挂载点设置为 opt 的部署配置示例。

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
      name: example
      namespace: example
    spec:
      replicas: 3
      selector:
        app: httpd
      template:
        metadata:
          labels:
            app: httpd
        spec:
          volumes:
            - name: volume-pppsw
              emptyDir: {}
            - name: v2
              persistentVolumeClaim:
                claimName: pvc1
            - name: v1
              persistentVolumeClaim:
                claimName: pvc1
          containers:
            - name: httpd
              image: >-
                image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
              ports:
                - containerPort: 8080
                  protocol: TCP
              volumeMounts: 1
                - name: v1
                  mountPath: /opt
    1
    将挂载点设置为 /opt

7.3.6. 从 pod 中删除卷和卷挂载

您可以从 pod 中移除卷或卷挂载。

流程

从 pod 模板中移除卷:

$ oc set volume <object_type>/<name> --remove [options]

表 7.3. 移除卷时支持的选项

选项描述默认

--name

卷的名称。

 

-c, --containers

按名称选择容器。它还可以使用通配符 '*’ 来匹配任意字符。

'*'

--confirm

指定您想要一次性移除多个卷。

 

-o, --output

显示修改后的对象,而不在服务器上更新它们。支持的值有 jsonyaml

 

--output-version

输出给定版本的修改后对象。

api-version

例如:

  • DeploymentConfig 对象 d1 中删除卷 v1

    $ oc set volume dc/d1 --remove --name=v1
  • DeploymentConfig 对象从 d1 的容器 c1 中卸载卷 v1,并在 d1 上的任何容器都没有引用时删除卷 v1

    $ oc set volume dc/d1 --remove --name=v1 --containers=c1
  • 移除复制控制器 r1 的所有卷:

    $ oc set volume rc/r1 --remove --confirm

7.3.7. 配置卷以在 pod 中用于多种用途

您可以使用 volumeMounts.subPath 属性来指定卷中的 subPath 而非卷的根目录,将卷配置为允许在一个 pod 中多处使用这个卷。

注意

您不能将 subPath 参数添加到现有调度的 pod 中。

流程

  1. 要查看卷中的文件列表,请运行 oc rsh 命令:

    $ oc rsh <pod>

    输出示例

    sh-4.2$ ls /path/to/volume/subpath/mount
    example_file1 example_file2 example_file3

  2. 指定 subPath

    带有 subPath 参数的 Pod spec 示例

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-site
    spec:
        containers:
        - name: mysql
          image: mysql
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql 1
        - name: php
          image: php
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html 2
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-site-data

    1
    数据库存储在 mysql 文件夹中。
    2
    HTML 内容存储在 html 文件夹中。