×

容器中的文件是短暂的。因此,当容器崩溃或停止时,数据将会丢失。您可以使用 *卷* 来持久化 Pod 中容器使用的数据。卷是一个目录,Pod 中的容器可以访问它,数据在此目录中存储,直至 Pod 生命周期结束。

理解卷

卷是可以被 Pod 及其容器使用的已挂载文件系统,它可以由许多主机本地或网络附加存储端点支持。默认情况下,容器并非持久性的;重启后,其内容将被清除。

为了确保卷上的文件系统没有错误,并且如果存在错误,则尽可能修复它们,AWS 上的 Red Hat OpenShift 服务会在 `mount` 实用程序之前调用 `fsck` 实用程序。这发生在添加卷或更新现有卷时。

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

如果集群管理员启用了 FSGroup 参数,则 `emptyDir` 卷存储可能会根据 Pod 的 FSGroup 受配额限制。

使用 AWS CLI 操作 Red Hat OpenShift 服务中的卷

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

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

$ oc set volume <object_selection> <operation> <mandatory_parameters> <options>
对象选择

在 `oc set volume` 命令中为 `object_selection` 参数指定以下其中一项

表 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`。

必填参数

任何必填参数都特定于所选操作,将在后面的部分中讨论。

选项

任何选项都特定于所选操作,将在后面的部分中讨论。

列出 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

向 Pod 添加卷

您可以向 Pod 添加卷和卷挂载。

步骤

向 Pod 模板添加卷、卷挂载或两者

$ oc set volume <object_type>/<name> --add [options]
表 2. 添加卷的支持选项
选项 描述 默认值

--name

卷的名称。

如果未指定,则自动生成。

-t, --type

卷源的名称。支持的值:`emptyDir`、`hostPath`、`secret`、`configmap`、`persistentVolumeClaim` 或 `projected`。

emptyDir

-c, --containers

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

'*'

-m, --mount-path

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

--path

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

--secret-name

密钥的名称。`--type=secret` 的必填参数。

--configmap-name

configmap 的名称。`--type=configmap` 的必填参数。

--claim-name

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

--source

作为 JSON 字符串的卷源详细信息。如果 `--type` 不支持所需的卷源,则推荐使用此选项。

-o, --output

显示修改后的对象,而不是在服务器上更新它们。支持的值:`json`、`yaml`。

--output-version

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

api-version

例如

  • 向 **registry** `DeploymentConfig` 对象添加新的卷源 **emptyDir**

    $ oc set volume dc/registry --add

    您可以选择应用以下 YAML 来添加卷

    添加了卷的示例部署配置
    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** 添加具有密钥 **secret1** 的卷 **v1**,并在容器内的 **/data** 位置挂载

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

    您可以选择应用以下 YAML 来添加卷

    添加了卷和密钥的示例复制控制器
    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 添加卷和密钥。
    2 添加容器挂载路径。
  • 将磁盘上 `dc.json` 部署配置中现有的持久卷 **v1**(声明名称为 **pvc1**)挂载到容器 **c1** 的 **/data** 位置,并在服务器上更新 `DeploymentConfig` 对象

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

    您可以选择应用以下 YAML 来添加卷

    添加了持久卷的示例部署配置
    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"
                }}'

更新 Pod 中的卷和卷挂载

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

步骤

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

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

例如

  • 将复制控制器r1中现有的卷v1替换为现有的持久卷声明pvc1

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

    或者,您可以应用以下YAML来替换卷

    包含名为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
  • DeploymentConfig对象d1的挂载点更改为/opt(用于卷v1

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

    或者,您可以应用以下YAML来更改挂载点

    挂载点设置为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

从Pod中删除卷和卷挂载

您可以从Pod中删除卷或卷挂载。

步骤

要从Pod模板中删除卷

$ oc set volume <object_type>/<name> --remove [options]
表3. 删除卷的支持选项
选项 描述 默认值

--name

卷的名称。

-c, --containers

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

'*'

--confirm

指示您要一次删除多个卷。

-o, --output

显示修改后的对象,而不是在服务器上更新它们。支持的值:`json`、`yaml`。

--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

配置Pod中卷的多重用途

您可以使用volumeMounts.subPath属性配置一个卷,以便在单个Pod中共享一个卷用于多个用途,指定卷内部的subPath值而不是卷的根目录。

您无法向已调度的Pod添加subPath参数。

步骤
  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规范示例
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-site
    spec:
        securityContext:
          runAsNonRoot: true
          seccompProfile:
            type: RuntimeDefault
        containers:
        - name: mysql
          image: mysql
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql (1)
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
        - name: php
          image: php
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html (2)
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-site-data
    1 数据库存储在mysql文件夹中。
    2 HTML内容存储在html文件夹中。