你当前正在访问 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>
替换为 azureDisk
、ephemeraldisk
或 elasticSan
。
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
命名空间添加到排除列表,请执行以下步骤:
- 创建 Azure Kubernetes 群集。
- 启用适用于 AKS 的 Azure Policy。
- 创建一个你猜想将阻止安装 Azure 容器存储的策略。
- 尝试在 AKS 群集中安装 Azure 容器存储。
- 检查网关守卫控制器 Pod 的日志,确认任何策略冲突。
- 添加
acstor
命名空间和azure-extensions-usage-system
命名空间添加到策略的排除列表中。 - 尝试再次在 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 容器存储能够以独占方式管理这些本地磁盘:
运行以下命令,查看临时存储池声明的容量:
$ kubectl get sp -A NAMESPACE NAME CAPACITY AVAILABLE USED RESERVED READY AGE acstor ephemeraldisk-nvme 0 0 0 0 False 82s
此示例显示了
ephemeraldisk-nvme
存储池声明的零容量。运行以下命令,确认这些本地成组设备的未声明状态,并检查磁盘上的现有文件系统:
$ 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
状态,并且磁盘上有一个现有文件系统。在继续操作之前,请确认你要使用 Azure 容器存储以独占方式管理本地数据磁盘。
停止并移除管理本地数据磁盘的守护程序集或组件。
登录到具有本地数据磁盘的每个节点。
将现有文件系统从所有本地数据磁盘中移除。
重启 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
等待几秒钟,并检查临时存储池是否从本地数据磁盘声明容量。
$ 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_LRS
、Standard_LRS
、StandardSSD_LRS
、Premium_ZRS
和 StandardSSD_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 支持开具支持票证。