Use Azure Files Storage¶
You can provide persistent storage for MKE workloads on Microsoft Azure by using Azure Files. You can either pre-provision Azure Files shares to be consumed by Kubernetes Pods, or you can use the Azure Kubernetes integration to dynamically provision Azure Files shares as needed.
This guide assumes that you have already provisioned an MKE environment on Microsoft Azure and that you have provisioned a cluster after meeting all of the prerequisites listed in Install MKE on Azure.
To complete the steps in this topic, you must download and configure the client bundle.
Manually provision Azure Files shares¶
You can use existing Azure Files shares or manually provision new ones to provide persistent storage for Kubernetes Pods. You can manually provision Azure Files shares in the Azure Portal, using ARM Templates, or using the Azure CLI. The following example uses the Azure CLI to manually provision an Azure Files share.
To manually provision an Azure Files share:
Note
The Azure Kubernetes driver does not support Azure Storage accounts created using Azure Premium Storage.
Create an Azure Storage account:
Create the following environment variables, replacing
<region>
with the required region:REGION=<region> SA=mystorageaccount RG=myresourcegroup
Create the Azure Storage account:
az storage account create \ --name $SA \ --resource-group $RG \ --location $REGION \ --sku Standard_LRS
Provision an Azure Files share:
Create the following environment variables, adjusting the size of this share to satisfy the user requirements.
FS=myfileshare SIZE=5
Obtain the Azure collection string, which you can also obtain from the Azure Portal:
export AZURE_STORAGE_CONNECTION_STRING=`az storage account show-connection-string --name $SA --resource-group $RG -o tsv`
Provision the Azure Files share:
az storage share create \ --name $FS \ --quota $SIZE \ --connection-string $AZURE_STORAGE_CONNECTION_STRING
To configure a Kubernetes Secret:
After creating an Azure Files share, you must load the Azure Storage account access key into MKE as a Kubernetes Secret. This provides access to the file share when Kubernetes attempts to mount the share into a Pod. You can find this Secret either in the Azure Portal or by using the Azure CLI, as in the following example.
Create the following environment variables, if you have not done so already:
SA=mystorageaccount RG=myresourcegroup FS=myfileshare
Obtain the Azure Storage account access key, which you can also obtain from the Azure Portal:
STORAGE_KEY=$(az storage account keys list --resource-group $RG --account-name $SA --query "[0].value" -o tsv)
Load the Azure Storage account access key into MKE as a Kubernetes Secret:
kubectl create secret generic azure-secret \ --from-literal=azurestorageaccountname=$SA \ --from-literal=azurestorageaccountkey=$STORAGE_KEY
To mount the Azure Files share into a Kubernetes Pod:
The following example creates a standalone Kubernetes Pod, though you can use the same syntax to create DaemonSets, Deployments, and StatefulSets.
Create the following environment variable:
FS=myfileshare
Mount the Azure Files share into a Kubernetes Pod:
cat <<EOF | kubectl create -f - apiVersion: v1 kind: Pod metadata: name: mypod-azurefile spec: containers: - image: nginx name: mypod volumeMounts: - name: mystorage mountPath: /data volumes: - name: mystorage azureFile: secretName: azure-secret shareName: $FS readOnly: false EOF
Dynamically provision Azure Files shares¶
Kubernetes can dynamically provision Azure Files shares using the Azure Kubernetes integration, configured at the time of your MKE installation. For Kubernetes to determine which APIs to use when provisioning storage, you must create Kubernetes StorageClass objects specific to each storage backend.
Note
The Azure Kubernetes plugin only supports using the Standard StorageClass. File shares that use the Premium StorageClass will fail to mount.
To define the Azure Files StorageClass:
Create the storage class:
cat <<EOF | kubectl create -f - kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: standard provisioner: kubernetes.io/azure-file mountOptions: - dir_mode=0777 - file_mode=0777 - uid=1000 - gid=1000 parameters: skuName: Standard_LRS storageAccount: <existingstorageaccount> # Optional location: <existingstorageaccountlocation> # Optional EOF
Verify which storage classes have been provisioned:
kubectl get storageclasses
Example output:
NAME PROVISIONER AGE azurefile kubernetes.io/azure-file 1m
To create an Azure Files share using a PersistentVolumeClaim:
After you create a storage class, you can use Kubernetes Objects to dynamically provision Azure Files shares. This is done using Kubernetes PersistentVolumesClaims.
Kubernetes uses an existing Azure Storage account, if one exists inside of the Azure Resource Group. If an Azure Storage account does not exist, Kubernetes creates one.
The following example uses the standard storage class and creates a 5 Gi Azure File share. Alter these values to fit your use case.
Create a PersistentVolumeClaim:
cat <<EOF | kubectl create -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: azure-file-pvc spec: accessModes: - ReadWriteMany storageClassName: standard resources: requests: storage: 5Gi EOF
Verify the creation of the PersistentVolumeClaim:
kubectl get pvc
Example output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE azure-file-pvc Bound pvc-f7ccebf0-70e0-11e9-8d0a-0242ac110007 5Gi RWX standard 22s
Verify the creation of the PerstentVolume:
kubectl get pv
Example output:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-f7ccebf0-70e0-11e9-8d0a-0242ac110007 5Gi RWX Delete Bound default/azure-file-pvc standard 2m
To attach the new Azure Files share to a Kubernetes Pod:
You can now mount the Kubernetes PersistentVolume into a Kubernetes Pod. The file share can be consumed by any Kubernetes object type, including a Deployment, DaemonSet, or StatefulSet. However, the following example simply mounts the PersistentVolume into a standalone Pod.
Attach the new Azure Files share to a Kubernetes Pod:
cat <<EOF | kubectl create -f -
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: azure-file-pvc
EOF
Troubleshoot Azure Files shares¶
When creating a PersistentVolumeClaim, the volume can get stuck in a
Pending
state if the persistent-volume-binder
service account does not
have the relevant Kubernetes RBAC permissions.
To resolve this issue:
Review the status of the PVC:
kubectl get pvc
Example output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE azure-file-pvc Pending standard 32s
Describe the PVC:
kubectl describe pvc azure-file-pvc
The storage account creates a Kubernetes Secret to store the Azure Files storage account key. If the
persistent-volume-binder
service account does not have the correct permissions, a warning such as the following will display:Warning ProvisioningFailed 7s (x3 over 37s) persistentvolume-controller Failed to provision volume with StorageClass "standard": Couldn't create secret secrets is forbidden: User "system:serviceaccount:kube-system:persistent-volume-binder" cannot create resource "secrets" in API group "" in the namespace "default": access denied
Grant the
persistent-volume-binder
service account the relevant RBAC permissions by creating the following RBAC ClusterRole:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: subjectName: kube-system-persistent-volume-binder name: kube-system-persistent-volume-binder:cluster-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: persistent-volume-binder namespace: kube-system
See also
Kubernetes Pods in the official Kubernetes documentation
Azure Kubernetes in the official Microsoft Azure documentation