第 3 章 配置持久性存储

3.1. 使用 AWS Elastic 文件系统的永久性存储

OpenShift Container Platform 可以使用 Amazon Web Services (AWS) Elastic File System volumes (EFS) 。您可以使用 AWS EC2 为 OpenShift Container Platform 集群置备持久性存储。我们假设您对 Kubernetes 和 AWS 有一定的了解。

重要

elastic 文件系统只是一个技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/

Kubernetes 持久性卷框架允许管理员提供带有持久性存储的集群,并使用户可以在不了解底层存储架构的情况下请求这些资源。AWS Elastic Block Store 卷可以动态部署。持久性卷不与某个特定项目或命名空间相关联,它们可以在 OpenShift Container Platform 集群间共享。持久性卷声明是针对某个项目或者命名空间的,相应的用户可请求它。

3.1.1. 先决条件

  • 配置 AWS 安全组来允许来自 EFS 卷安全组的入站 NFS 流量。
  • 将 AWS EFS 卷配置为允许来自任何主机的 SSH 流量。

3.1.2. 在 ConfigMap 中保存 EFS 变量

建议使用 ConfigMap 包含 EFS 置备程序所需的所有环境变量。

流程

  1. 通过创建一个包含以下内容的 configmap.yaml 文件,定义包含环境变量的 OpenShift Container Platform ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: efs-provisioner
    data:
      file.system.id: <file-system-id> 1
      aws.region: <aws-region> 2
      provisioner.name: openshift.org/aws-efs 3
      dns.name: "" 4
    1
    定义 Amazon Web Services (AWS) EFS 文件系统 ID。
    2
    EFS 文件系统的 AWS 区域,比如 us-east-1
    3
    关联的 StorageClass 的置备程序名称。
    4
    用来指定 EFS 卷所在的新 DNS 名称的一个可选参数。如果没有提供 DNS 名称,则置备程序将在 <file-system-id>.efs.<aws-region>.amazonaws.com中搜索 EFS 卷。
  2. 在文件被配置后,运行以下命令在集群中创建该文件:

    $ oc create -f configmap.yaml -n <namespace>

3.1.3. 为 EFS 卷配置授权

EFS 置备程序必须被授权与 AWS 端点沟通,同时观察和更新 OpenShift Container Platform 存储资源。以下是为 EFS 置备程序创建必要权限的流程。

流程

  1. 创建一个 efs-provisioner 服务帐户:

    $ oc create serviceaccount efs-provisioner
  2. 创建定义所需权限的文件 clusterrole.yaml

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: efs-provisioner-runner
    rules:
      - apiGroups: [""]
        resources: ["persistentvolumes"]
        verbs: ["get", "list", "watch", "create", "delete"]
      - apiGroups: [""]
        resources: ["persistentvolumeclaims"]
        verbs: ["get", "list", "watch", "update"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["create", "update", "patch"]
      - apiGroups: ["security.openshift.io"]
        resources: ["securitycontextconstraints"]
        verbs: ["use"]
        resourceNames: ["hostmount-anyuid"]
  3. 创建一个文件 clusterrolebinding.yaml,该文件定义一个集群角色绑定把定义的角色和服务帐户进行绑定:

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: run-efs-provisioner
    subjects:
      - kind: ServiceAccount
        name: efs-provisioner
        namespace: default 1
    roleRef:
      kind: ClusterRole
      name: efs-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
    1
    运行 EFS provisioner pod 的命名空间。如果 EFS 置备程序不在 default 命名空间中运行,则必须更新这个值。
  4. 创建一个文件 role.yaml,它定义了具有所需权限的角色:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-efs-provisioner
    rules:
      - apiGroups: [""]
        resources: ["endpoints"]
        verbs: ["get", "list", "watch", "create", "update", "patch"]
  5. 创建一个文件 rolebinding.yaml,它定义了一个角色绑定将这个角色和服务帐户进行绑定:

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-efs-provisioner
    subjects:
      - kind: ServiceAccount
        name: efs-provisioner
        namespace: default 1
    roleRef:
      kind: Role
      name: leader-locking-efs-provisioner
      apiGroup: rbac.authorization.k8s.io
    1
    运行 EFS provisioner pod 的命名空间。如果 EFS 置备程序不在 default 命名空间中运行,则必须更新这个值。
  6. 在 OpenShift Container Platform 集群中创建资源:

    $ oc create -f clusterrole.yaml,clusterrolebinding.yaml,role.yaml,rolebinding.yaml

3.1.4. 创建 EFS StorageClass

在创建 PersistentVolumeClaims 前,OpenShift Container Platform 集群中应已存在一个 StorageClass。以下是为 EFS 置备程序创建 StorageClass 的流程。

流程

  1. 通过创建包含以下内容的 storageclass.yaml 来定义包含环境变量的 OpenShift Container Platform ConfigMap:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: aws-efs
    provisioner: openshift.org/aws-efs
    parameters:
      gidMin: "2048" 1
      gidMax: "2147483647" 2
      gidAllocate: "true" 3
    1
    定义卷分配的最小组群 ID (GID)。这是一个可选参数。默认值为 2048
    2
    定义卷分配的最大 GID。这是一个可选参数。默认值为 2147483647
    3
    指定是否为卷分配 GID。它是一个可选参数。如果为 false,则动态置备的卷不会分配 GID,这将允许所有用户对创建的卷进行读和写操作。默认值为 true
  2. 在文件被配置后,运行以下命令在集群中创建该文件:

    $ oc create -f storageclass.yaml

3.1.5. 创建 EFS 置备程序

EFS 置备程序是一个 OpenShift Container Platform Pod,它将 EFS 卷作为 NFS 共享挂载。

先决条件

  • 创建定义 EFS 环境变量的 ConfigMap。
  • 创建包含必要的集群和角色权限的服务帐户。
  • 为置备卷创建一个 StorageClass。
  • 配置 Amazon Web Services (AWS) 安全组,允许在所有 OpenShift Container Platform 节点上接收进入的 NFS 网络数据。
  • 配置 AWS EFS 卷安全组配置,允许来自所有源的 SSH 网络数据。

流程

  1. 通过创建包含以下内容的 provisioner.yaml 文件定义 EFS 置备程序:

    kind: Pod
    apiVersion: v1
    metadata:
      name: efs-provisioner
    spec:
      serviceAccount: efs-provisioner
      containers:
        - name: efs-provisioner
          image: quay.io/external_storage/efs-provisioner:latest
          env:
            - name: PROVISIONER_NAME
              valueFrom:
                configMapKeyRef:
                  name: efs-provisioner
                  key: provisioner.name
            - name: FILE_SYSTEM_ID
              valueFrom:
                configMapKeyRef:
                  name: efs-provisioner
                  key: file.system.id
            - name: AWS_REGION
              valueFrom:
                configMapKeyRef:
                  name: efs-provisioner
                  key: aws.region
            - name: DNS_NAME
              valueFrom:
                configMapKeyRef:
                  name: efs-provisioner
                  key: dns.name
                  optional: true
          volumeMounts:
            - name: pv-volume
              mountPath: /persistentvolumes
      volumes:
        - name: pv-volume
          nfs:
            server: <file-system-id>.efs.<region>.amazonaws.com 1
            path: / 2
    1
    包含 EFS 卷的 DNS 名称。必须为 Pod 更新这个字段以可以发现 EFS 卷。
    2
    EFS 卷的挂载路径。每个持久性卷都是作为 EFS 卷的独立子目录创建的。如果这个 EFS 卷是用于 OpenShift Container Platform 以外的其他项目,那么建议您在 EFS 上为集群手动创建一个独立的 OpenShift Container Platform 子目录,以防止数据被其他项目访问。指定不存在的目录会导致错误。
  2. 在文件被配置后,运行以下命令在集群中创建该文件:

    $ oc create -f provisioner.yaml

3.1.6. 创建 EFS persistentVolumeClaim

创建 EFS persistentvolumeclaim 的目的是为了使 Pod 可以挂载底层的 EFS 存储。

先决条件

  • 创建 EFS provisioner pod。

流程 (UI)

  1. 在 OpenShift Container Platform 控制台中,点击 StoragePersistent Volume Claims
  2. 在持久性卷声明概述页中,点 Create Persistent Volume Claim
  3. 在接下来的页面中定义所需选项。

    1. 从列表中选择您创建的存储类。
    2. 输入存储声明的唯一名称。
    3. 选择访问模式来决定所创建存储声明的读写访问权限。
    4. 定义存储声明的大小。

      注意

      虽然您必须输入大小,但每个访问 EFS 卷的 Pod 都有无限存储。定义一个值,比如 1Mi,它会提醒您存储大小是无限的。

  4. 点击 Create 创建持久性卷声明,并生成一个持久性卷。

流程 (CLI)

  1. 另外,您还可以通过创建一个包含以下内容的 pvc.yaml 文件来定义 EFS PersistentVolumeClaim:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: efs-claim 1
      namespace: test-efs
      annotations:
        volume.beta.kubernetes.io/storage-provisioner: openshift.org/aws-efs
      finalizers:
        - kubernetes.io/pvc-protection
    spec:
      accessModes:
        - ReadWriteOnce 2
      resources:
        requests:
          storage: 5Gi 3
      storageClassName: aws-efs 4
      volumeMode: Filesystem
    1
    PVC 的唯一名称。
    2
    决定所创建 PVC 的读写访问权限的访问模式。
    3
    定义 PVC 的大小。
    4
    EFS 置备程序 StorageClass 的名称。
  2. 在文件被配置后,运行以下命令在集群中创建该文件:

    $ oc create -f pvc.yaml