你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure 容器存储排除故障

Azure 容器存储是一项基于云的卷管理、部署和业务流程服务,专为容器原生构建。 使用本文排查 Azure 容器存储的常见问题,并查找问题的解决方法。

安装问题疑难解答

由于缺少配置,Azure 容器存储无法安装

运行 az aks create 后,可能会看到“Azure 容器存储安装失败。AKS 群集已创建。请运行 az aks update--enable-azure-container-storage 来启用 Azure 容器存储

此消息表示未安装 Azure 容器存储,但已正确创建你的 AKS(Azure Kubernetes 服务)群集。

若要再群集上安装 Azure 容器存储和创建存储池,请运行以下命令。 将 <cluster-name><resource-group> 替换为自己的值。 将 <storage-pool-type> 替换为 azureDiskephemeraldiskelasticSan

az aks update -n <cluster-name> -g <resource-group> --enable-azure-container-storage <storage-pool-type>

由于 Azure Policy 限制,Azure 容器存储无法安装

如果存在 Azure Policy 限制,Azure 容器存储可能无法安装。 具体而言,Azure 容器存储依赖于特权容器。 可以将 Azure Policy 配置为阻止特权容器。 当它们被阻止时,Azure 容器存储的安装可能会超时或失败,并且你可能会在 gatekeeper-controller 日志中看到错误,例如:

$ kubectl logs -n gatekeeper-system deployment/gatekeeper-controller
... 
{"level":"info","ts":1722622443.9484184,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: prereq, securityContext: {\"privileged\": true, \"runAsUser\": 0}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-prereq-gt58x","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}
{"level":"info","ts":1722622443.9839077,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: metrics-exporter, securityContext: {\"privileged\": true}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-metrics-exporter-286np","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}
{"level":"info","ts":1722622444.0515249,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: csi-node, securityContext: {\"privileged\": true}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-csi-node-7hcd7","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}
{"level":"info","ts":1722622444.0729053,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: io-engine, securityContext: {\"privileged\": true}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-io-engine-84hwx","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}
{"level":"info","ts":1722622444.0742755,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: ndm, securityContext: {\"privileged\": true}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-ndm-x6q5n","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}
{"level":"info","ts":1722622449.2412128,"logger":"webhook","msg":"denied admission: Privileged container is not allowed: ndm, securityContext: {\"privileged\": true}","hookType":"validation","process":"admission","details":{},"event_type":"violation","constraint_name":"azurepolicy-k8sazurev2noprivilege-686dd8b209a774ba977c","constraint_group":"constraints.gatekeeper.sh","constraint_api_version":"v1beta1","constraint_kind":"K8sAzureV2NoPrivilege","constraint_action":"deny","resource_group":"","resource_api_version":"v1","resource_kind":"Pod","resource_namespace":"acstor","resource_name":"azurecontainerstorage-ndm-b5nfg","request_username":"system:serviceaccount:kube-system:daemon-set-controller"}

若要解决阻止,需要将 acstor 命名空间添加到 Azure Policy 的排除列表中。 Azure Policy 用于创建和强制实施规则以管理 Azure 中的资源,包括 AKS 群集。 在某些情况下,策略可能会阻止创建 Azure 容器存储 Pod 和组件。 可通过查阅适用于 Kubernetes 的 Azure Policy 来查找有关使用适用于 Kubernetes 的 Azure Policy 的更多详细信息。

若要将 acstor 命名空间添加到排除列表,请执行以下步骤:

  1. 创建 Azure Kubernetes 群集
  2. 启用适用于 AKS 的 Azure Policy。
  3. 创建一个你猜想将阻止安装 Azure 容器存储的策略。
  4. 尝试在 AKS 群集中安装 Azure 容器存储。
  5. 检查网关守卫控制器 Pod 的日志,确认任何策略冲突。
  6. 添加 acstor 命名空间和 azure-extensions-usage-system 命名空间添加到策略的排除列表中。
  7. 尝试再次在 AKS 群集中安装 Azure 容器存储。

无法在具有污点的节点池中安装和启用 Azure 容器存储

可以在节点池上配置节点污点,以限制在这些节点池上调度 Pod。 在这些节点池上安装和启用 Azure 容器存储可能会受到阻止,因为无法在这些节点池中创建所需的 Pod。 此行为适用于安装时的系统节点池和启用时的用户节点池。

可以使用以下示例检查节点污点:

$ az aks nodepool list -g $resourceGroup --cluster-name $clusterName --query "[].{PoolName:name, nodeTaints:nodeTaints}"
[
...
  {
    "PoolName": "nodepoolx",
    "nodeTaints": [
      "sku=gpu:NoSchedule"
    ]
  }
]

可以暂时移除这些污点以取消阻止,并在安装并成功启用后重新配置它们。 可以转到 Azure 门户 > AKS 群集 > 节点池,单击节点池,移除“污点和标签”部分中的污点。 或者,可以使用以下命令移除污点并确认更改。

$ az aks nodepool update -g $resourceGroup --cluster-name $clusterName --name $nodePoolName --node-taints ""
$ az aks nodepool list -g $resourceGroup --cluster-name $clusterName --query "[].{PoolName:name, nodeTaints:nodeTaints}"
[
...
  {
    "PoolName": "nodepoolx",
    "nodeTaints": null
  }
]

成功移除节点污点后重试安装或启用。 成功完成后,可以配置节点污点以恢复 Pod 调度限制。

无法将存储池类型设置为 NVMe

如果尝试使用临时磁盘安装 Azure 容器存储,特别是虚拟机 (VM) SKU 没有 NVMe 驱动器的群集上的本地 NVMe,你会收到以下错误消息:无法将 --storage-pool-option 设置为 NVMe,因为节点池均不支持临时 NVMe 磁盘。

若要修正,请使用具有 NVMe 驱动器的 VM SKU 创建节点池,然后重试。 请参阅存储优化 VM

排查存储池问题

若要检查存储池的状态,请运行 kubectl describe sp <storage-pool-name> -n acstor。 下面是可能会遇到的一些问题。

临时存储池在临时磁盘由其他守护程序集使用时不声明容量

在具有临时 SSD 或本地 NVMe 磁盘的节点池上启用临时存储池时,如果其他守护程序集正在使用这些磁盘,则可能无法从这些磁盘中声明容量。

运行以下步骤,使 Azure 容器存储能够以独占方式管理这些本地磁盘:

  1. 运行以下命令,查看临时存储池声明的容量:

    $ kubectl get sp -A
    NAMESPACE   NAME                 CAPACITY   AVAILABLE   USED   RESERVED   READY   AGE
    acstor      ephemeraldisk-nvme   0          0           0      0          False   82s
    

    此示例显示了 ephemeraldisk-nvme 存储池声明的零容量。

  2. 运行以下命令,确认这些本地成组设备的未声明状态,并检查磁盘上的现有文件系统:

    $ kubectl get bd -A
    NAMESPACE   NAME                                           NODENAME                               SIZE            CLAIMSTATE   STATUS   AGE
    acstor      blockdevice-1f7ad8fa32a448eb9768ad8e261312ff   aks-nodepoolnvme-38618677-vmss000001   1920383410176   Unclaimed    Active   22m
    acstor      blockdevice-9c8096fc47cc2b41a2ed07ec17a83527   aks-nodepoolnvme-38618677-vmss000000   1920383410176   Unclaimed    Active   23m
    $ kubectl describe bd -n acstor blockdevice-1f7ad8fa32a448eb9768ad8e261312ff
    Name:         blockdevice-1f7ad8fa32a448eb9768ad8e261312ff
    …
      Filesystem:
        Fs Type:  ext4
    …
    

    此示例显示了成组设备是 Unclaimed 状态,并且磁盘上有一个现有文件系统。

  3. 在继续操作之前,请确认你要使用 Azure 容器存储以独占方式管理本地数据磁盘。

  4. 停止并移除管理本地数据磁盘的守护程序集或组件。

  5. 登录到具有本地数据磁盘的每个节点。

  6. 将现有文件系统从所有本地数据磁盘中移除。

  7. 重启 ndm 守护程序集以发现未使用的本地数据磁盘。

    $ kubectl rollout restart daemonset -l app=ndm -n acstor
    daemonset.apps/azurecontainerstorage-ndm restarted
    $ kubectl rollout status daemonset -l app=ndm -n acstor --watch
    …
    daemon set "azurecontainerstorage-ndm" successfully rolled out
    
  8. 等待几秒钟,并检查临时存储池是否从本地数据磁盘声明容量。

    $ kubectl wait -n acstor sp --all --for condition=ready
    storagepool.containerstorage.azure.com/ephemeraldisk-nvme condition met
    $ kubectl get bd -A
    NAMESPACE   NAME                                           NODENAME                               SIZE            CLAIMSTATE   STATUS   AGE
    acstor      blockdevice-1f7ad8fa32a448eb9768ad8e261312ff   aks-nodepoolnvme-38618677-vmss000001   1920383410176   Claimed      Active   4d16h
    acstor      blockdevice-9c8096fc47cc2b41a2ed07ec17a83527   aks-nodepoolnvme-38618677-vmss000000   1920383410176   Claimed      Active   4d16h
    $ kubectl get sp -A
    NAMESPACE   NAME                 CAPACITY        AVAILABLE       USED          RESERVED      READY   AGE
    acstor      ephemeraldisk-nvme   3840766820352   3812058578944   28708241408   26832871424   True    4d16h
    

    此示例显示了 ephemeraldisk-nvme 存储池从节点上的本地 NVMe 磁盘成功声明容量。

尝试扩展 Azure 磁盘存储池时出错

如果现有存储池小于 4 TiB (4,096 GiB),则最多只能将其扩展到 4,095 GiB。 如果尝试扩展到限制以上,内部 PVC 会显示有关磁盘大小或缓存类型限制的错误消息。 请停止 VM 或拆离磁盘,然后重试该操作。

为了避免错误,如果当前存储池最初小于 4 TiB (4,096 GiB),请不要尝试将其扩展到 4,095 GiB 以上。 容量大于 4 TiB 的存储池可以扩展到可用的最大存储容量。

此限制仅适用于使用 Premium_LRSStandard_LRSStandardSSD_LRSPremium_ZRSStandardSSD_ZRS 磁盘 SKU 时。

弹性 SAN 创建失败

如果尝试创建弹性 SAN 存储池,可能会看到“Azure 弹性 SAN 创建失败: 已创建的订阅的最大弹性 SAN 数”消息。 这意味着,你已达到每个订阅可在一个区域中部署的弹性 SAN 资源数限制。 可在此处查看限制:弹性 SAN 可伸缩性和性能目标。 请考虑删除不再使用的订阅上的所有现有弹性 SAN 资源,或者尝试在其他区域中创建存储池。

找不到块设备

如果看到此消息,则表示你可能尝试在 VM SKU 没有 NVMe 驱动器的群集上创建临时磁盘存储池。

若要修正,请使用具有 NVMe 驱动器的 VM SKU 创建节点池,然后重试。 请参阅存储优化 VM

已启用存储池类型

如果尝试启用已存在的存储池类型,将收到以下消息:--enable-azure-container-storage 值无效。已在群集中为存储池类型 <storage-pool-type> 启用 Azure 容器存储”消息。 可运行 kubectl get sp -n acstor 来检查现在是否已经创建了任何存储池。

禁用存储池类型

通过 az aks update --disable-azure-container-storage <storage-pool-type> 禁用存储池类型或通过 az aks update --disable-azure-container-storage all 卸载 Azure 容器存储时,如果现在有该类型的存储池,你会收到以下消息:

如果为存储池类型 <storage-pool-type> 禁用 Azure 容器存储,将强制删除同一类型的所有存储池,并对使用这些存储池的应用程序产生影响。 强制删除存储池还可能导致正在使用的存储资源泄漏。 是否要在禁用 Azure 容器存储之前验证是否使用了 <storage-pool-type> 类型的存储池? (是/否)

如果选择“是”,则运行自动验证来确保没有从存储池创建的永久性卷。 如果选择“否”,会绕过此验证并禁用存储池类型,从而删除任何现有存储池并可能影响应用程序。

排查卷的问题

由于临时卷大小超出可用容量,Pod 创建处于挂起状态

在单个节点上分配临时卷。 为 Pod 配置临时卷的大小时,大小应小于单个节点临时磁盘的可用容量。 否则,Pod 创建处于挂起状态。

使用以下命令检查 Pod 创建是否处于挂起状态。

$ kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
fiopod   0/1     Pending   0          17s

在此示例中,pod fiopod 处于“Pending”状态。

使用以下命令检查 Pod 是否具有关于创建 persistentvolumeclaim 的警告事件。

$ kubectl describe pod fiopod
...
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  40s   default-scheduler  0/3 nodes are available: waiting for ephemeral volume controller to create the persistentvolumeclaim "fiopod-ephemeralvolume". preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling..

在此示例中,Pod 显示有关创建永久性卷声明 fiopod-ephemeralvolume 的警告事件。

使用以下命令检查永久性卷声明是否由于容量不足而无法预配。

$ kubectl describe pvc fiopod-ephemeralvolume
...
  Warning  ProvisioningFailed    107s (x13 over 20m)  containerstorage.csi.azure.com_aks-nodepool1-29463073-vmss000000_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  failed to provision volume with StorageClass "acstor-ephemeraldisk-temp": rpc error: code = Internal desc = Operation failed: GenericOperation("error in response: status code '507 Insufficient Storage', content: 'RestJsonError { details: \"Operation failed due to insufficient resources: Not enough suitable pools available, 0/1\", message: \"SvcError :: NotEnoughResources\", kind: ResourceExhausted }'")

在此示例中,Insufficient Storage 显示为卷配置失败的原因。

运行以下命令,检查单个节点临时磁盘的可用容量。

$ kubectl get diskpool -n acstor
NAME                                CAPACITY      AVAILABLE     USED        RESERVED    READY   AGE
ephemeraldisk-temp-diskpool-jaxwb   75660001280   75031990272   628011008   560902144   True    21h
ephemeraldisk-temp-diskpool-wzixx   75660001280   75031990272   628011008   560902144   True    21h
ephemeraldisk-temp-diskpool-xbtlj   75660001280   75031990272   628011008   560902144   True    21h

在此示例中,单个节点临时磁盘的可用容量为 75031990272 字节或 69 GiB。

将卷存储大小调整到可用容量以下,然后重新部署 Pod。 请参阅使用通用临时卷部署 Pod

由于元数据存储脱机,卷无法附加

Azure 容器存储使用 etcd(一种分布式、可靠的键值存储)来存储和管理卷的元数据,以支持卷编排操作。 为了获得高可用性和复原能力,可在三个 Pod 中运行 etcd。 当运行的 etcd 实例少于两个时,Azure 容器存储将停止卷编排操作,但仍允许数据访问卷。 Azure 容器存储会自动检测 etcd 实例是否离线,并将其恢复。 但是,如果在重启 AKS 群集后发现卷编排错误,则可能是 etcd 实例未能自动恢复。 按照本节中的说明确定 etcd 实例的运行状况。

运行以下命令以获取 Pod 列表。

kubectl get pods

将显示类似于下面的输出。

NAME     READY   STATUS              RESTARTS   AGE 
fiopod   0/1     ContainerCreating   0          25m 

描述 Pod:

kubectl describe pod fiopod

通常情况下,如果元数据存储处于离线状态,则会看到卷故障消息。 在此示例中,fiopod 处于 ContainerCreating 状态,FailedAttachVolume 警告指示由于卷附加失败,创建正在等待中

Name:             fiopod 

Events: 

Type     Reason              Age                 From                     Message 

----     ------              ----                ----                     ------- 

Normal   Scheduled           25m                 default-scheduler        Successfully assigned default/fiopod to aks-nodepool1-xxxxxxxx-vmss000009

Warning  FailedAttachVolume  3m8s (x6 over 23m)  attachdetach-controller  AttachVolume.Attach failed for volume "pvc-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" : timed out waiting for external-attacher of containerstorage.csi.azure.com CSI driver to attach volume xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

还可以运行以下命令来检查 etcd 实例的状态:

kubectl get pods -n acstor | grep "^etcd"

应会看到类似于以下内容的输出,其中所有实例都处于“正在运行”状态:

etcd-azurecontainerstorage-bn89qvzvzv                            1/1     Running   0               4d19h
etcd-azurecontainerstorage-phf92lmqml                            1/1     Running   0               4d19h
etcd-azurecontainerstorage-xznvwcgq4p                            1/1     Running   0               4d19h

如果运行的实例少于两个,则卷不会附加,因为元数据存储处于离线状态,并且自动恢复失败。 如果是这样,请通过 Azure 支持开具支持票证。

另请参阅