在 Azure Kubernetes 服务 (AKS) 中通过 Azure 文件共享手动创建并使用卷

基于容器的应用程序通常需要访问数据并将数据保存在外部数据卷中。 如果多个 Pod 需要同时访问同一存储卷,则可以使用 Azure 文件存储通过服务器消息块 (SMB) 协议进行连接。 本文介绍了如何手动创建 Azure 文件共享并将其附加到 AKS 中的 Pod。

有关 Kubernetes 卷的详细信息,请参阅 AKS 中应用程序的存储选项

开始之前

本文假设你已有一个版本不低于 1.21 的 AKS 群集。 如果需要 AKS 群集,请参阅使用 Azure CLI 的 AKS 快速入门、使用 Azure PowerShell 的 AKS 快速入门或使用 Azure 门户的 AKS 快速入门。

若要使用 1.20 或更低版本的 AKS 群集与 Azure 文件存储进行交互,请参阅用于 Azure 文件存储的 Kubernetes 插件

创建 Azure 文件共享

必须先创建 Azure 存储帐户和文件共享,然后才能将 Azure 文件共享用作 Kubernetes 卷。 以下命令创建一个名为 myAKSShare 的资源组、一个存储帐户和一个名为 aksshare 的文件共享:

# Change these four parameters as needed for your own environment
AKS_PERS_STORAGE_ACCOUNT_NAME=mystorageaccount$RANDOM
AKS_PERS_RESOURCE_GROUP=myAKSShare
AKS_PERS_LOCATION=chinaeast2
AKS_PERS_SHARE_NAME=aksshare

# Create a resource group
az group create --name $AKS_PERS_RESOURCE_GROUP --location $AKS_PERS_LOCATION

# Create a storage account
az storage account create -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -l $AKS_PERS_LOCATION --sku Standard_LRS

# Export the connection string as an environment variable, this is used when creating the Azure file share
export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -o tsv)

# Create the file share
az storage share create -n $AKS_PERS_SHARE_NAME --connection-string $AZURE_STORAGE_CONNECTION_STRING

# Get storage account key
STORAGE_KEY=$(az storage account keys list --resource-group $AKS_PERS_RESOURCE_GROUP --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME --query "[0].value" -o tsv)

# Echo storage account name and key
echo Storage account name: $AKS_PERS_STORAGE_ACCOUNT_NAME
echo Storage account key: $STORAGE_KEY

记下脚本输出末尾显示的存储帐户名称和密钥。 在下面的步骤之一中创建 Kubernetes 卷时需要这些值。

创建 Kubernetes 机密

Kubernetes 需要使用凭据访问上一步骤中创建的文件共享。 这些凭据存储在 Kubernetes 机密中,创建 Kubernetes Pod 时将引用它。

使用 kubectl create secret 命令创建机密。 以下示例创建一个名为 azure-secret 的机密并填充上一步骤中的 azurestorageaccountname 和 azurestorageaccountkey。 若要使用现有 Azure 存储帐户,请提供帐户名称和密钥。

kubectl create secret generic azure-secret --from-literal=azurestorageaccountname=$AKS_PERS_STORAGE_ACCOUNT_NAME --from-literal=azurestorageaccountkey=$STORAGE_KEY

装载文件共享作为内联卷

注意

内联卷只能访问与 Pod 相同的命名空间中的机密。 若要指定其他机密命名空间,请改用下面的永久性卷示例

若要将 Azure 文件共享装载到 Pod 中,请在容器规范中配置卷。使用以下内容创建名为 azure-files-pod.yaml 的新文件。 如果更改了文件共享名称或机密名称,请更新 shareNamesecretName。 如果需要,请更新 mountPath,这是文件共享在 Pod 中的装载路径。 对于 Windows Server 容器,请使用 Windows 路径约定指定 mountPath,例如“D:”。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  nodeSelector:
    kubernetes.io/os: linux
  containers:
  - image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
    name: mypod
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
    volumeMounts:
      - name: azure
        mountPath: /mnt/azure
  volumes:
  - name: azure
    csi:
      driver: file.csi.azure.com
      readOnly: false
      volumeAttributes:
        secretName: azure-secret  # required
        shareName: aksshare  # required
        mountOptions: "dir_mode=0777,file_mode=0777,cache=strict,actimeo=30"  # optional

使用 kubectl 命令创建 Pod。

kubectl apply -f azure-files-pod.yaml

现在你有一个正在运行的 Pod,其中 Azure 文件共享装载在 /mnt/azure 处。 可以使用 kubectl describe pod mypod 来验证共享是否已成功装载。

将文件共享装载为永久性卷

注意

对于 SMB 装载,如果 PV 配置中没有提供 nodeStageSecretRef 字段,azure 文件驱动程序将尝试在 Pod 命名空间中获取 azure-storage-account-{accountname}-secret,如果该机密不存在,它将使用 kubelet 标识直接通过 Azure 存储帐户 API 获取帐户密钥(确保 kubelet 标识具有对存储帐户的读取者访问权限)。

  • 装载选项

fileMode 和 dirMode 的默认值为 0777。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: azurefile
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: azurefile-csi
  csi:
    driver: file.csi.azure.com
    readOnly: false
    volumeHandle: unique-volumeid  # make sure this volumeid is unique in the cluster
    volumeAttributes:
      resourceGroup: EXISTING_RESOURCE_GROUP_NAME  # optional, only set this when storage account is not in the same resource group as agent node
      shareName: aksshare
    nodeStageSecretRef:
      name: azure-secret
      namespace: default
  mountOptions:
    - dir_mode=0777
    - file_mode=0777
    - uid=0
    - gid=0
    - mfsymlinks
    - cache=strict
    - nosharesock
    - nobrl

创建一个 azurefile-mount-options-pvc.yaml 文件,其中包含使用 PersistentVolume 的 PersistentVolumeClaim。 例如:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: azurefile
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: azurefile-csi
  volumeName: azurefile
  resources:
    requests:
      storage: 5Gi

使用 kubectl 命令创建 PersistentVolume 和 PersistentVolumeClaim。

kubectl apply -f azurefile-mount-options-pv.yaml
kubectl apply -f azurefile-mount-options-pvc.yaml

验证 PersistentVolumeClaim 是否已创建并绑定到 PersistentVolume。

$ kubectl get pvc azurefile

NAME        STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
azurefile   Bound    azurefile   5Gi        RWX            azurefile      5s

更新容器规范以引用 PersistentVolumeClaim并更新 Pod。 例如:

...
  volumes:
  - name: azure
    persistentVolumeClaim:
      claimName: azurefile

由于无法就地更新 Pod 规范,因此请使用 kubectl 命令进行删除,然后重新创建 Pod:

kubectl delete pod mypod

kubectl apply -f azure-files-pod.yaml

后续步骤

有关 Azure 文件 CSI 驱动程序参数,请参阅 CSI 驱动程序参数

如需相关的最佳做法,请参阅 AKS 中的存储和备份最佳做法