OpenShift Container Platform allows use of Amazon Web Services (AWS) Elastic File System volumes (EFS). You can provision your OpenShift Container Platform cluster with persistent storage using AWS EC2. Some familiarity with Kubernetes and AWS is assumed.

Elastic File System is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.

For more information about the support scope of Red Hat Technology Preview features, see https://access.redhat.com/support/offerings/techpreview/.

The Kubernetes persistent volume framework allows administrators to provision a cluster with persistent storage and gives users a way to request those resources without having any knowledge of the underlying infrastructure. AWS Elastic Block Store volumes can be provisioned dynamically. PersistentVolumes are not bound to a single project or namespace; they can be shared across the OpenShift Container Platform cluster. PersistentVolumeClaims are specific to a project or namespace and can be requested by users.

Prerequisites
  • Configure the AWS security groups to allow inbound NFS traffic from the EFS volume’s security group.

  • Configure the AWS EFS volume to allow incoming SSH traffic from any host.

Store the EFS variables in a ConfigMap

It is recommended to use a ConfigMap to contain all the environment variables that are required for the EFS provisioner.

Procedure
  1. Define an OpenShift Container Platform ConfigMap that contains the environment variables by creating a configmap.yaml file that contains following contents:

    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 Defines the Amazon Web Services (AWS) EFS file system ID.
    2 The AWS region of the EFS file system, such as us-east-1.
    3 The name of the provisioner for the associated StorageClass.
    4 An optional argument that specifies the new DNS name where the EFS volume is located. If no DNS name is provided, the provisioner will search for the EFS volume at <file-system-id>.efs.<aws-region>.amazonaws.com.
  2. After the file has been configured, create it in your cluster by running the following command:

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

Configuring authorization for EFS volumes

The EFS provisioner must be authorized to communicate to the AWS endpoints, along with observing and updating OpenShift Container Platform storage resources. The following instructions create the necessary permissions for the EFS provisioner.

Procedure
  1. Create an efs-provisioner service account:

    $ oc create serviceaccount efs-provisioner
  2. Create a file, clusterrole.yaml that defines the necessary permissions:

    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. Create a file, clusterrolebinding.yaml, that defines a cluster role binding that assigns the defined role to the service account:

    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 The namespace where the EFS provisioner pod will run. If the EFS provisioner is running in a namespace other than default, this value must be updated.
  4. Create a file, role.yaml, that defines a role with the necessary permissions:

    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. Create a file, rolebinding.yaml, that defines a role binding that assigns this role to the service account:

    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 The namespace where the EFS provisioner pod will run. If the EFS provisioner is running in a namespace other than default, this value must be updated.
  6. Create the resources inside the OpenShift Container Platform cluster:

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

Create the EFS StorageClass

Before PersistentVolumeClaims can be created, a StorageClass must exist in the OpenShift Container Platform cluster. The following instructions create the StorageClass for the EFS provisioner.

Procedure
  1. Define an OpenShift Container Platform ConfigMap that contains the environment variables by creating a storageclass.yaml with the following contents:

    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 An optional argument that defines the minimum group ID (GID) for volume assignments. The default value is 2048.
    2 An optional argument that defines the maximum GID for volume assignments. The default value is 2147483647.
    3 An optional argument that determines if GIDs are assigned to volumes. If false, dynamically provisioned volumes are not allocated GIDs, allowing all users to read and write to the created volumes. The default value is true.
  2. After the file has been configured, create it in your cluster by running the following command:

    $ oc create -f storageclass.yaml

Create the EFS provisioner

The EFS provisioner is an OpenShift Container Platform Pod that mounts the EFS volume as an NFS share.

Prerequisites
  • Create A ConfigMap that defines the EFS environment variables.

  • Create a service account that contains the necessary cluster and role permissions.

  • Create a StorageClass for provisioning volumes.

  • Configure the Amazon Web Services (AWS) security groups to allow incoming NFS traffic on all OpenShift Container Platform nodes.

  • Configure the AWS EFS volume security groups to allow incoming SSH traffic from all sources.

Procedure
  1. Define the EFS provisioner by creating a provisioner.yaml with the following contents:

    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 Contains the DNS name of the EFS volume. This field must be updated for the Pod to discover the EFS volume.
    2 The mount path of the EFS volume. Each persistent volume is created as a separate subdirectory on the EFS volume. If this EFS volume is used for other projects outside of OpenShift Container Platform, then it is recommended to create a unique subdirectory OpenShift Container Platform manually on EFS for the cluster to prevent projects from accessing another project’s data. Specifying a directory that does not exist results in an error.
  2. After the file has been configured, create it in your cluster by running the following command:

    $ oc create -f provisioner.yaml

Create the EFS PersistentVolumeClaim

EFS PersistentVolumeClaims are created to allow Pods to mount the underlying EFS storage.

Prerequisites
  • Create the EFS provisioner pod.

Procedure (UI)
  1. In the OpenShift Container Platform console, click StoragePersistent Volume Claims.

  2. In the persistent volume claims overview, click Create Persistent Volume Claim.

  3. Define the required options on the resulting page.

    1. Select the storage class that you created from the list.

    2. Enter a unique name for the storage claim.

    3. Select the access mode to determine the read and write access for the created storage claim.

    4. Define the size of the storage claim.

      Although you must enter a size, every Pod that access the EFS volume has unlimited storage. Define a value, such as 1Mi, that will remind you that the storage size is unlimited.

  4. Click Create to create the persistent volume claim and generate a persistent volume.

Procedure (CLI)
  1. Alternately, you can define EFS PersistentVolumeClaims by creating a file, pvc.yaml, with the following contents:

    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 A unique name for the PVC.
    2 The access mode to determine the read and write access for the created PVC.
    3 Defines the size of the PVC.
    4 Name of the StorageClass for the EFS provisioner.
  2. After the file has been configured, create it in your cluster by running the following command:

    $ oc create -f pvc.yaml