装载 Azure Blob 存储容器时出错

本文提供了可能导致 Azure Blob 存储容器装载失败的错误的原因和解决方案。

现象

在 Azure Kubernetes 服务 (AKS) 环境中部署 Kubernetes 资源,例如 Deployment 和 StatefulSet。 该部署将创建一个 Pod,用于装载引用 Azure Blob 存储容器的 PersistentVolumeClaim (PVC)。

但是,Pod 会一直处于 ContainerCreating 状态。 当你运行 kubectl describe pods 命令时,可能会在命令输出中看到以下错误之一,这会导致装载操作失败。

注意

Azure Blob 存储容器可以使用 BlobFuse 或网络文件系统 (NFS) 版本 3.0 协议。 本文分别记录了 BlobFuse 和 NFS 3.0 方案。

有关可能的原因和解决方法,请查看下列部分。

注意

尽管在某些情况下,问题的原因可能类似,但由于 BlobFuse 和 NFS 3.0 协议的不同性质,错误可能有所不同。

BlobFuse 错误 1:退出状态 255 无法启动 blobfuse,errno=404,由于身份验证或连接问题,无法启动 blobfuse

原因:Blob 容器不存在

若要检查 Blob 容器是否存在,请执行以下步骤:

  1. 在 Azure 门户中搜索并访问存储帐户。

    显示如何查找存储帐户的屏幕截图。

  2. 选择存储帐户中数据存储下的容器,并检查容器是否存在关联的 PersistentVolume (PV)。 若要查看永久性卷 (PV),请检查 YAML 文件中与 Pod 关联的永久性卷声明 (PVC),然后检查哪个 PV 与该 PVC 相关联。

    显示容器中的永久性卷声明的屏幕截图。

解决方案:确保容器存在

若要解决此问题,请确保存在与 PV/PVC 关联的 Blob 容器。

BlobFuse 错误 2:退出状态 255 无法启动 blobfuse、errno=403、由于身份验证或连接问题而无法启动 blobfuse

可能导致此错误的原因如下:

原因 1:Kubernetes 机密未引用正确的存储帐户名称或密钥

如果动态创建 Blob 存储容器,则会使用名称“azure-storage-account-storage-account-name-secret<>”自动创建 Kubernetes 机密资源。

如果 Blob 存储容器是手动创建的,则应手动创建 Kubernetes 机密资源。

无论创建方法如何,如果 Kubernetes 机密中引用的存储帐户名称或密钥与实际值不匹配,装载操作将失败并出现“权限被拒绝”错误。

不匹配的可能原因

  • 如果 Kubernetes 机密是手动创建的,则创建过程中可能会出现拼写错误。

  • 如果在存储帐户级别执行“轮换密钥”操作,则更改不会在 Kubernetes 机密级别有所反映。 这将导致存储帐户级别的密钥值与 Kubernetes 机密级别的值不匹配。

    如果发生“轮换密钥”操作,存储帐户的活动日志中会显示名为“重新生成存储帐户密钥”的操作。 请注意活动日志的 90 天保持期

验证不匹配

若要验证不匹配,请执行以下步骤:

  1. 在 Azure 门户中搜索并访问存储帐户。 选择“访问密钥>显示存储帐户中的密钥”。 你将看到存储帐户名称和关联的密钥。

    显示存储帐户名称和关联密钥的屏幕截图。

  2. 转到 AKS 群集,选择“配置>机密,然后搜索并访问关联的机密。

    显示关联机密的屏幕截图。

  3. 选择“显示(眼睛图标),并将存储帐户名称和关联密钥的值与步骤 1 中的值进行比较。

    显示存储帐户名称和关联密钥的值的屏幕截图。

    在选择“显示之前,存储帐户名称和关联密钥的值将编码为 base64 字符串。 选择“显示后,将解码值。

如果无权访问 Azure 门户中的 AKS 群集,请在 kubectl 级别执行步骤 2:

  1. 获取 Kubernetes 机密的 YAML 文件,然后运行以下命令,从输出中获取存储帐户名称和密钥的值:

    kubectl get secret <secret-name> -n <secret-namespace> -o <yaml-file-name>
    
  2. 使用 echo 命令解码存储帐户名称和密钥的值,并将其与存储帐户级别的值进行对比。

    下面是解码存储帐户名称的示例:

    echo -n '<storage account name>' | base64 --decode ;echo
    

    解码存储帐户名称的命令的屏幕截图。

解决方案:调整 Kubernetes 机密并重新创建 Pod

如果 Kubernetes 机密中的存储帐户名称或密钥的值与存储帐户中 访问密钥 中的值不匹配,请运行以下命令来调整 Kubernetes 机密级别的 Kubernetes 机密:

kubectl edit secret <secret-name> -n <secret-namespace>

在 Kubernetes 机密配置中添加的存储帐户名称或密钥的值应为 base64 编码值。 若要获取编码值,请使用 echo 命令。

下面是对存储帐户名称进行编码的示例:

echo -n '<storage account name>'| base64 | tr -d '\n' ; echo

有关详细信息,请参阅使用 kubectl 管理机密

Kubernetes 机密 azure-storage-account-<storage-account-name>-secret 具有正确的值后,重新创建 Pod。 否则,这些 Pod 将继续使用不再有效的旧值。

原因 2:不允许存储帐户使用 AKS 的 VNET 和子网

如果存储帐户的网络仅限于所选网络,但 AKS 群集的 VNET 和子网未添加到所选网络,装载操作便会失败。

解决方案:允许存储帐户使用 AKS 的 VNET 和子网

  1. 运行以下命令,确定托管有故障 Pod 的节点:

    kubectl get pod <pod-name> -n <namespace> -o wide
    

    检查命令输出中的节点:

    可以标识节点和输出的命令的屏幕截图。

  2. 转到Azure 门户中的 AKS 群集,选择“属性>基础结构”资源组,访问与节点关联的虚拟机规模集(VMSS),然后检查虚拟网络/子网以标识 VNET 和子网。

    VNET 和子网的屏幕截图。

  3. 访问Azure 门户中的存储帐户,然后选择“网络”。 如果公用网络访问设置为“从所选虚拟网络启用”“已禁用”,并且连接不是通过专用终结点,请检查防火墙和虚拟网络是否允许 AKS 群集的 VNET 和子网。

    防火墙和虚拟网络设置的屏幕截图。

    如果未添加 AKS 群集的 VNET 和子网,请选择“ 添加现有虚拟网络”。 在“添加网络”页上,键入 AKS 群集的 VNET 和子网,然后选择“添加>保存”。

    “添加网络”对话框的屏幕截图。

    更改可能需要几分钟才能生效。 添加 VNET 和子网后,检查 Pod 状态是否从 ContainerCreating 更改为 “正在运行”。

    屏幕截图显示 Pod 状态为“正在运行”。

BlobFuse 错误 3:超出上下文截止时间/具有给定卷 ID <> 的操作 ...已存在

可能导致此错误的原因包括:

  • 原因 1:网络安全组阻止 AKS 与存储帐户之间的流量
  • 原因 2:虚拟设备阻止 AKS 与存储帐户之间的流量

BlobFuse 错误 3 的初步故障排除

Azure Blob BlobFuse 依赖于端口 443。 确保未阻止端口 443 和/或存储帐户的 IP 地址。

若要检查存储帐户的 IP 地址,请运行域名系统 (DNS) 命令(如 nslookupdighost)。 例如:

nslookup <storage-account-name>.blob.core.windows.net

若要检查 AKS 群集与存储帐户之间是否存在连接,请进入节点Pod 并运行以下 nctelnet 命令:

nc -v -w 2 <storage-account-name>.blob.core.windows.net 443
telnet <storage-account-name>.blob.core.windows.net 443

原因 1:网络安全组阻止 AKS 与存储帐户之间的流量

检查 BlobFuse 错误 3 部分的初始故障排除中提到的或telnet命令的nc输出。 如果显示超时,请检查网络安全组 (NSG) 并确保未阻止存储帐户的 IP 地址。

若要检查 NSG 是否阻止存储帐户的 IP 地址,请执行以下步骤:

  1. 在Azure 门户中,转到网络观察程序并选择 NSG 诊断

  2. 使用以下值填写字段:

    • 协议:TCP
    • 方向:出站
    • 源类型:IPv4 地址/CIDR
    • IPv4 地址/CIDR:与 AKS 节点关联的实例的 IP 地址
    • 目标 IP 地址:存储帐户的 IP 地址
    • 目标端口:443(如果使用 BlobFuse)和 111/2048(如果使用 NFS)
  3. 选择“检查”按钮并检查流量状态。

流量状态可以是“允许”或拒绝”。 “被拒绝”状态表示 NSG 正在阻止 AKS 群集和存储帐户之间的流量。 如果状态为 “拒绝”,将显示 NSG 名称。

解决方案:允许 AKS 和存储帐户之间的连接

若要解决此问题,请在 NSG 级别进行相应的更改,以允许 AKS 群集与端口 443 上的存储帐户之间的连接。

原因 2:虚拟设备阻止 AKS 与存储帐户之间的流量

如果使用虚拟设备(通常为防火墙)来控制 AKS 群集的出站流量(例如,虚拟设备在 AKS 群集的子网中应用了路由表,并且该路由表具有将流量发送到虚拟设备的路由),则虚拟设备可能会阻止 AKS 群集与存储帐户之间的流量。

若要隔离该问题,请在路由表中为存储帐户的 IP 地址添加路由,以便将流量发送到 Internet。

若要确认 AKS 群集的流量由哪个路由表控制,请执行以下步骤:

  1. 转到Azure 门户中的 AKS 群集,然后选择“属性>基础结构”资源组。
  2. 如果使用的是此类 VM 集类型,请访问可用性集中的 VMSS 或虚拟机 (VM)。
  3. 选择虚拟网络/子网>子网并标识 AKS 群集的子网。 可以在右侧看到路由表。

若要在路由表中添加路由,请按照创建路由中的步骤操作并填写以下字段:

  • 地址前缀: <存储帐户的-public-IP>/32
  • 下一跃点类型:Internet

此路由将通过公共 Internet 发送 AKS 群集和存储帐户之间的所有流量。

添加路由后,使用 nctelnet 命令测试连接性,然后再次执行装载操作。

解决方案:确保虚拟设备允许 AKS 和存储帐户之间的流量

如果装载操作成功,建议咨询网络团队,确保虚拟设备可以允许 AKS 群集与端口 443 上的存储帐户之间的流量。

NFS 3.0 错误 1:退出状态 32。 没有此类文件或目录

原因:Blob 容器不存在

若要检查 Blob 容器是否存在,请执行以下步骤:

  1. 在Azure 门户中搜索存储帐户并访问存储帐户。

    显示如何搜索存储帐户的屏幕截图。

  2. 选择存储帐户中数据存储下的容器,并检查容器是否存在关联的 PersistentVolume (PV)。 若要查看永久性卷 (PV),请检查 YAML 文件中与 Pod 关联的永久性卷声明 (PVC),然后检查哪个 PV 与该 PVC 相关联。

    显示永久性卷声明(PVC)的屏幕截图。

解决方案:确保 Blob 容器存在

若要解决此问题,请确保存在与 PV/PVC 关联的 Blob 容器。

NFS 3.0 错误 2:退出状态 32,装载时服务器拒绝访问

原因:不允许存储帐户使用 AKS 的 VNET 和子网

如果存储帐户的网络仅限于所选网络,但 AKS 群集的 VNET 和子网未添加到所选网络,装载操作便会失败。

解决方案:允许存储帐户使用 AKS 的 VNET 和子网

  1. 运行以下命令,确定托管有故障 Pod 的节点:

    kubectl get pod <pod-name> -n <namespace> -o wide
    

    检查命令输出中的节点:

    显示“kubectl get pod”命令输出的屏幕截图。

  2. 转到Azure 门户中的 AKS 群集,选择“属性>基础结构”资源组,访问与节点关联的 VMSS,然后检查虚拟网络/子网以标识 VNET 和子网。

    VNET 和子网的屏幕截图。

  3. 访问Azure 门户中的存储帐户,然后选择“网络”。 如果公用网络访问设置为“从所选虚拟网络启用”“已禁用”,并且连接不是通过专用终结点,请检查防火墙和虚拟网络是否允许 AKS 群集的 VNET 和子网。

    “防火墙和虚拟网络”下的设置的屏幕截图。

    如果未添加 AKS 群集的 VNET 和子网,请选择“ 添加现有虚拟网络”。 在“添加网络”页上,键入 AKS 群集的 VNET 和子网,然后选择“添加>保存”。

    “添加网络”对话框的屏幕截图。

    更改可能需要几分钟才能生效。 添加 VNET 和子网后,检查 Pod 状态是否从 ContainerCreating 更改为 “正在运行”。

    Pod 状态的屏幕截图。

NFS 3.0 错误 3:超出上下文截止时间/已存在具有给定卷 ID <的操作...>

可能导致此错误的原因包括:

  • 原因 1:网络安全组阻止 AKS 与存储帐户之间的流量
  • 原因 2:虚拟设备阻止 AKS 与存储帐户之间的流量

NFS 3.0 错误 3 的初始故障排除

Azure Blob NFS 3.0 依赖于端口 111 和 2049。 确保不会阻止存储帐户的端口 111 和 2049 和/或 IP 地址。

若要检查存储帐户的 IP 地址,请运行域名系统 (DNS) 命令(如 nslookupdighost)。 例如:

nslookup <storage-account-name>.blob.core.windows.net

若要检查 AKS 群集与存储帐户之间是否存在连接,请进入节点Pod 并运行以下 nctelnet 命令:

nc -v -w 2 <storage-account-name>.blob.core.windows.net 111
nc -v -w 2 <storage-account-name>.blob.core.windows.net 2049
telnet <storage-account-name>.blob.core.windows.net 111
telnet <storage-account-name>.blob.core.windows.net 2049

原因 1:网络安全组阻止 AKS 与存储帐户之间的流量

检查 NFS 3.0 错误 3 部分的初始故障排除中提到的或telnet命令的nc输出。 如果显示超时,请检查网络安全组 (NSG) 并确保未阻止存储帐户的 IP 地址。

若要检查 NSG 是否阻止存储帐户的 IP 地址,请执行以下步骤:

  1. 在Azure 门户中,转到网络观察程序并选择 NSG 诊断

  2. 使用以下值填写字段:

    • 协议:TCP
    • 方向:出站
    • 源类型:IPv4 地址/CIDR
    • IPv4 地址/CIDR:与 AKS 节点关联的实例的 IP 地址
    • 目标 IP 地址:存储帐户的 IP 地址
    • 目标端口:111,然后 2048
  3. 选择“检查”按钮并检查流量状态。

流量状态可以是“允许”或拒绝”。 “被拒绝”状态表示 NSG 正在阻止 AKS 群集和存储帐户之间的流量。 如果状态为 “拒绝”,将显示 NSG 名称。

解决方案:允许 AKS 和存储帐户之间的连接

若要解决此问题,请在 NSG 级别进行相应的更改,以允许 AKS 群集与端口 111/2048 上的存储帐户之间的连接。

原因 2:虚拟设备阻止 AKS 与存储帐户之间的流量

如果使用虚拟设备(通常为防火墙)来控制 AKS 群集的出站流量(例如,虚拟设备在 AKS 群集的子网中应用了路由表,并且该路由表具有将流量发送到虚拟设备的路由),则虚拟设备可能会阻止 AKS 群集与存储帐户之间的流量。

若要隔离该问题,请在路由表中为存储帐户的 IP 地址添加路由,以便将流量发送到 Internet。

若要确认 AKS 群集的流量由哪个路由表控制,请执行以下步骤:

  1. 转到Azure 门户中的 AKS 群集,然后选择“属性>基础结构”资源组。

  2. 如果使用的是此类 VM 集类型,请访问可用性集中的虚拟机规模集 (VMSS) 或 VM。

  3. 选择虚拟网络/子网>子网并标识 AKS 群集的子网。 可以在右侧看到路由表。

若要在路由表中添加路由,请按照创建路由中的步骤操作并填写以下字段:

  • 地址前缀: <存储帐户的-public-IP>/32
  • 下一跃点类型:Internet

此路由将通过公共 Internet 发送 AKS 群集和存储帐户之间的所有流量。

添加路由后,使用 nctelnet 命令测试连接性,然后再次执行装载操作。

解决方案:确保虚拟设备允许 AKS 和存储帐户之间的流量

如果装载操作成功,建议咨询网络团队,以确保虚拟设备可以允许 AKS 群集与端口 111 和 2049 上的存储帐户之间的流量。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区