3.12. 使用本地卷的持久性存储

OpenShift Container Platform 可以使用本地卷来置备持久性存储。本地持久性卷允许您使用标准 PVC 接口访问本地存储设备,如磁盘或分区。

无需手动将 Pod 调度到节点即可使用本地卷,因为系统了解卷节点的约束。但是,本地卷仍会受到底层节点可用性的影响,而且并不适用于所有应用程序。

注意

本地卷只能用作静态创建的持久性卷。

3.12.1. 安装 Local Storage Operator

默认情况下,OpenShift Container Platform 中不会安装 Local Storage Operator。使用以下流程来安装和配置这个 Operator,从而在集群中启用本地卷。

先决条件

  • 访问 OpenShift Container Platform web 控制台或命令行 (CLI)。

流程

  1. 创建 local-storage 项目:

    $ oc new-project local-storage
  2. 可选:允许在 master 和基础架构节点上创建本地存储。

    您可能希望使用 Local Storage Operator 在 master 基础架构节点上(不只限于 worker 节点上)创建卷来支持一些组件,如日志记录和监控。

    要允许在 master 和基础架构节点上创建本地存储,请输入以下命令为 DaemonSet 添加容限:

    $ oc patch ds local-storage-local-diskmaker -n local-storage -p '{"spec": {"template": {"spec": {"tolerations":[{"operator": "Exists"}]}}}}'
    $ oc patch ds local-storage-local-provisioner -n local-storage -p '{"spec": {"template": {"spec": {"tolerations":[{"operator": "Exists"}]}}}}'

使用 UI

按照以下步骤,通过 web 控制台安装 Local Storage Operator:

  1. 登陆到 OpenShift Container Platform Web 控制台。
  2. 导航至 OperatorsOperatorHub
  3. 在过滤器框中键入 Local Storage 以查找 Local Storage Operator。
  4. 点击 Install
  5. Create Operator Subscription 页面中,选择 A specific namespace on the cluster。从下拉菜单中选择 local-storage
  6. Update ChannelApproval Strategy 的值调整为所需的值。
  7. Subscribe.

完成后,Web 控制台的 Installed Operators 部分中会列出 Local Storage Operator。

使用 CLI

  1. 通过 CLI 安装 Local Storage Operator。

    1. 创建一个对象 YAML 文件来为 Local Storage Operator 定义一个 Namespace、OperatorGroup 和 Subscription。例如 local-storage.yaml:

      local-storage 示例

        apiVersion: v1
        kind: Namespace
        metadata:
          name: local-storage
        ---
        apiVersion: operators.coreos.com/v1alpha2
        kind: OperatorGroup
        metadata:
          name: local-operator-group
          namespace: local-storage
        spec:
          targetNamespaces:
            - local-storage
        ---
        apiVersion: operators.coreos.com/v1alpha1
        kind: Subscription
        metadata:
          name: local-storage-operator
          namespace: local-storage
        spec:
          channel: "{product-version}" 1
          installPlanApproval: Automatic
          name: local-storage-operator
          source: redhat-operators
          sourceNamespace: openshift-marketplace

      1
      此字段可以被编辑,以匹配选择的 OpenShift Container Platform 的发行版本。
  2. 输入以下命令来创建 Local Storage Operator 对象:

    $ oc apply -f local-storage.yaml

    在此阶段,Operator Lifecycle Manager (OLM) 已可以了解 Local Storage Operator。Operator 的 ClusterServiceVersion (CSV) 应出现在目标命名空间中,由 Operator 提供的 API 应可用于创建。

  3. 通过检查是否创建了所有 Pod 和 Local Storage Operator 来验证本地存储安装:

    1. 检查是否创建了所有必需的 Pod:

      $ oc -n local-storage get pods
      NAME                                      READY   STATUS    RESTARTS   AGE
      local-storage-operator-746bf599c9-vlt5t   1/1     Running   0          19m
    2. 检查 ClusterServiceVersion (CSV) YAML 清单,查看 local-storage 项目中是否有 Local Storage Operator:

      $ oc get csvs -n local-storage
      NAME                                         DISPLAY         VERSION               REPLACES   PHASE
      local-storage-operator.4.2.26-202003230335   Local Storage   4.2.26-202003230335              Succeeded

如果通过了所有检查,则代表 Local Storage Operator 已被成功安装。

3.12.2. 置备本地卷

无法通过动态置备来创建本地卷。相反,PersistentVolume 必须由 Local Storage Operator 创建。此置备程序会在定义的资源中指定的路径上查找任意设备,包括文件系统和块卷。

先决条件

  • 安装了 Local Storage Operator。
  • 本地磁盘已附加到 OpenShift Container Platform 节点。

流程

  1. 创建本地卷资源。这必须定义本地卷的节点和路径。

    注意

    不要在同一设备中使用不同的 StorageClass 名称。这样做可创建多个持久性卷 (PV)。

    例如:Filesystem

    apiVersion: "local.storage.openshift.io/v1"
    kind: "LocalVolume"
    metadata:
      name: "local-disks"
      namespace: "local-storage" 1
    spec:
      nodeSelector: 2
        nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - ip-10-0-140-183
              - ip-10-0-158-139
              - ip-10-0-164-33
      storageClassDevices:
        - storageClassName: "local-sc"
          volumeMode: Filesystem 3
          fsType: xfs 4
          devicePaths: 5
            - /path/to/device 6

    1
    安装了 Local Storage Operator 的命名空间。
    2
    可选:包含附加了本地存储卷的节点列表的节点选择器。这个示例使用从 oc get node 获取的节点主机名。如果没有定义值,则 Local Storage Operator 会尝试在所有可用节点上查找匹配的磁盘。
    3
    定义本地卷类型的卷模式,可以是 FilesystemBlock
    4
    第一次挂载本地卷时所创建的文件系统。
    5
    包含要从中选择的本地存储设备列表的路径。
    6
    将这个值替换为您的到 LocalVolume 资源的实际本地磁盘文件路径,如 /dev/xvdg。当置备程序已被成功部署时,会为这些本地磁盘创建 PV。

    例如:Block

    apiVersion: "local.storage.openshift.io/v1"
    kind: "LocalVolume"
    metadata:
      name: "local-disks"
      namespace: "local-storage" 1
    spec:
      nodeSelector: 2
        nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - ip-10-0-136-143
              - ip-10-0-140-255
              - ip-10-0-144-180
      storageClassDevices:
        - storageClassName: "localblock-sc"
          volumeMode: Block  3
          devicePaths: 4
            - /path/to/device 5

    1
    安装了 Local Storage Operator 的命名空间。
    2
    可选:包含附加了本地存储卷的节点列表的节点选择器。这个示例使用从 oc get node 获取的节点主机名。如果没有定义值,则 Local Storage Operator 会尝试在所有可用节点上查找匹配的磁盘。
    3
    定义本地卷类型的卷模式,可以是 FilesystemBlock
    4
    包含要从中选择的本地存储设备列表的路径。
    5
    将这个值替换为您的到 LocalVolume 资源的实际本地磁盘文件路径,如 /dev/xvdg。当置备程序已被成功部署时,会为这些本地磁盘创建 PV。
  2. 通过指定您刚才创建的文件,在 OpenShift Container Platform 集群中创建本地卷资源:

    $ oc create -f <local-volume>.yaml
  3. 确定已创建置备程序,并且创建了相应的 DaemonSet:

    $ oc get all -n local-storage
    
    NAME                                          READY   STATUS    RESTARTS   AGE
    pod/local-disks-local-provisioner-h97hj       1/1     Running   0          46m
    pod/local-disks-local-provisioner-j4mnn       1/1     Running   0          46m
    pod/local-disks-local-provisioner-kbdnx       1/1     Running   0          46m
    pod/local-disks-local-diskmaker-ldldw         1/1     Running   0          46m
    pod/local-disks-local-diskmaker-lvrv4         1/1     Running   0          46m
    pod/local-disks-local-diskmaker-phxdq         1/1     Running   0          46m
    pod/local-storage-operator-54564d9988-vxvhx   1/1     Running   0          47m
    
    NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
    service/local-storage-operator    ClusterIP   172.30.49.90     <none>        60000/TCP   47m
    
    NAME                                           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    daemonset.apps/local-disks-local-provisioner   3         3         3       3            3           <none>          46m
    daemonset.apps/local-disks-local-diskmaker     3         3         3       3            3           <none>          46m
    
    NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/local-storage-operator   1/1     1            1           47m
    
    NAME                                                DESIRED   CURRENT   READY   AGE
    replicaset.apps/local-storage-operator-54564d9988   1         1         1       47m

    查看需要的和当前的 DaemonSet 进程数。如果需要的数目是 0,这表示标签选择器无效。

  4. 确认创建了 PersistentVolume:

    $ oc get pv
    
    NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
    local-pv-1cec77cf   100Gi      RWO            Delete           Available           local-sc                88m
    local-pv-2ef7cd2a   100Gi      RWO            Delete           Available           local-sc                82m
    local-pv-3fa1c73    100Gi      RWO            Delete           Available           local-sc                48m
重要

编辑 LocalVolume 对象不会更改现有 PersistentVolume 的 fsTypevolumeMode,因为这样做可能会导致破坏操作。

3.12.3. 创建本地卷 PersistentVolumeClaim

必须静态创建本地卷作为 PersistentVolumeClaim (PVC) ,才能被 Pod 访问。

前提条件

  • PersistentVolume 已通过本地卷置备程序创建。

流程

  1. 使用对应的 StorageClass 创建 PVC:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: local-pvc-name 1
    spec:
      accessModes:
      - ReadWriteOnce
      volumeMode: Filesystem 2
      resources:
        requests:
          storage: 100Gi 3
      storageClassName: local-sc 4
    1
    PVC 的名称。
    2
    PVC 的类型。默认为 Filesystem
    3
    PVC 可用的存储量。
    4
    声明所需的 StorageClass 的名称。
  2. 通过指定您刚才创建的文件,在 OpenShift Container Platform 集群中创建 PVC:

    $ oc create -f <local-pvc>.yaml

3.12.4. 附加本地声明

本地卷映射到 PersistentVolumeClaim (PVC) 后,可在资源内指定该本地卷。

先决条件

  • 同一命名空间中存在 PVC。

流程

  1. 在资源规格中包含定义的声明。以下示例在 Pod 内声明 PVC:

    apiVersion: v1
    kind: Pod
    spec:
      ...
      containers:
        volumeMounts:
        - name: localpvc 1
          mountPath: "/data" 2
      volumes:
      - name: localpvc
        persistentVolumeClaim:
          claimName: localpvc 3
    1
    要挂载的卷的名称。
    2
    卷在 Pod 内的挂载路径。
    3
    要使用的现有 PVC 的名称。
  2. 通过指定您刚才创建的文件,在 OpenShift Container Platform 集群中创建资源:

    $ oc create -f <local-pod>.yaml

3.12.5. 使用 Local Storage Operator Pod 的容限

污点可用于节点,以防止它们运行常规工作负载。要允许 Local Storage Operator 使用污点节点,您必须在 Pod 或 DaemonSet 定义中添加容限。这允许在这些污点节点上运行所创建的资源。

您可以通过 LocalVolume 资源把容限应用到 Local Storage Operator Pod,通过节点规格把污点应用到一个节点。节点上的污点指示节点排斥所有不容许该污点的 Pod。使用一个没有存在于其他 Pod 上的特定污点可确保 Local Storage Operator Pod 也可以在该节点上运行。

重要

污点与容限由 key、value 和 effect 组成。作为参数,它表示为 key=value:effect。运算符允许您将其中一个参数留空。

先决条件

  • 安装了 Local Storage Operator。
  • 本地磁盘已附加到带有一个污点的 OpenShift Container Platform 节点上。
  • 污点节点可以置备本地存储。

流程

配置本地卷以便在污点节点上调度:

  1. 修改定义 pod 的 YAML 文件并添加 LocalVolume 规格,如下例所示:

      apiVersion: "local.storage.openshift.io/v1"
      kind: "LocalVolume"
      metadata:
        name: "local-disks"
        namespace: "local-storage"
      spec:
        tolerations:
          - key: localstorage 1
            operator: Equal 2
            value: "localstorage" 3
        storageClassDevices:
            - storageClassName: "localblock-sc"
              volumeMode: Block 4
              devicePaths: 5
                - /dev/xvdg
    1
    指定添加到节点的键。
    2
    指定 Equal 运算符,以要求 key/value 参数匹配。如果运算符是 'Exists',系统会检查键是否存在,并忽略它的值。如果运算符是 Equal,则键和值必须匹配。
    3
    指定污点节点的 local 值。
    4
    定义本地卷类型的卷模式,可以是 FilesystemBlock
    5
    包含要从中选择的本地存储设备列表的路径。

定义的容限度将传递给生成的 DaemonSet,允许为包含指定污点的节点创建 diskmaker 和 provisioner Pod。

3.12.6. 删除 Local Storage Operator 资源

3.12.6.1. 删除本地卷

有时候,必须要删除本地卷。虽然移除 LocalVolume 资源中的条目并且删除 PersistentVolume 通常已经足够,但若您要重新使用同一设备路径或者使其由不同的 StorageClass 进行管理,则需要额外的步骤。

警告

以下流程涉及以 root 用户身份访问节点。如果在本流程中步骤范围以外修改节点状态,则可能会导致集群不稳定。

前提条件

  • PersistentVolume 必须处于 ReleasedAvailable 状态。

    警告

    删除仍在使用中的 PersistentVolume 可能会导致数据丢失或崩溃。

流程

  1. 编辑之前创建的 LocalVolume,以删除所有不需要的磁盘。

    1. 编辑集群资源:

      $ oc edit localvolume <name> -n local-storage
    2. 找到 devicePaths 下的行,删除所有代表不需要的磁盘的行。
  2. 删除所有创建的 PersistentVolume。

    $ oc delete pv <pv-name>
  3. 删除节点上的所有符号链接。

    1. 在节点上创建一个调试 Pod:

      $ oc debug node/<node-name>
    2. 将您的根目录改为主机:

      $ chroot /host
    3. 前往包含本地卷符号链接的目录。

      $ cd /mnt/local-storage/<sc-name> 1
      1
      用于创建本地卷的 StorageClass 名称。
    4. 删除归属于已移除设备的符号链接。

      $ rm <symlink>

3.12.6.2. 卸载 Local Storage Operator

要卸载 Local Storage Operator,您必须删除 Operator 以及 local-storage 项目中创建的所有资源。

警告

当本地存储 PV 仍在使用时,不建议卸载 Local Storage Operator。当 Operator 被移除后 PV 仍然会被保留。但是如果在没有删除 PV 和本地存储资源的情况下重新安装 Operator,则可能会出现不确定的行为。

先决条件

  • 访问 OpenShift Container Platform Web 控制台。

流程

  1. 删除项目中的所有本地卷资源:

    $ oc delete localvolume --all --all-namespaces
  2. 从 Web 控制台卸载 Local Storage Operator。

    1. 登陆到 OpenShift Container Platform Web 控制台。
    2. 导航到 OperatorsInstalled Operators
    3. 在过滤器框中键入 Local Storage 以查找 Local Storage Operator。
    4. 点 Local Storage Operator kebab 末尾的 Options 菜单。
    5. 点击 Uninstall Operator
    6. 在出现的窗口中点击 Remove
  3. 由 Local Storage Operator 创建的 PV 将保留在集群中,直到被删除为止。当这些卷不再被使用后,运行以下命令删除它们:

    $ oc delete pv <pv-name>
  4. 删除 local-storage 项目:

    $ oc delete project local-storage