掛接 Azure 檔案共享時發生錯誤

本文提供導致 Azure 檔案共用掛接失敗之錯誤的可能原因和解決方案。

徵狀

您可以在 Azure Kubernetes Service (AKS) 環境中部署 Kubernetes 資源,例如部署或 StatefulSet。 部署會建立 Pod,以掛接參考 Azure 檔案共用的 PersistentVolumeClaim (PVC) 。

不過,Pod 會保持在 ContainerCreating 狀態。 當您執行命令時 kubectl describe pods ,您可能會在命令輸出中看到下列其中一個錯誤,導致掛接作業失敗:

請參閱下列輸出作為範例:

MountVolume.MountDevice failed for volume "\<pv-fileshare-name>"
rpc error: code = Internal desc =
volume(\<storage-account's-resource-group>#\<storage-account-name>#\<pv/fileshare-name>#) > mount "//\<storage-account-name>.file.core.windows.net/\<pv-fileshare-name>" on "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/\<pv-fileshare-name>/globalmount" failed with
mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t cifs -o dir_mode=0777,file_mode=0777,uid=0,gid=0,mfsymlinks,cache=strict,actimeo=30,\<masked> //\<storage-account-name>.file.core.windows.net/\<pv-name> /var/lib/kubelet/plugins/kubernetes.io/csi/pv/\<pv-name>/globalmount
Output: mount error(\<error-id>): \<error-description>
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)

注意事項

  • 如果記憶體帳戶可公開存取,輸出中顯示的主機名將會是 <storage-account-name.file.core.windows.net>
  • 如果記憶體帳戶是以私人連結、端點或 DNS 區域私下設定,則主機名會是 <storage-account-name.privatelink.file.core.windows.net>

疑難解答之前

根據輸出中的訊息,如下列範例所示,識別記憶體帳戶和檔案共用—這些值將在稍後的疑難解答步驟中使用。

mount “//<storage-account-name.file.core.windows.net/>< pv-fileshare-name>”

如需可能的原因和解決方案,請參閱下列各節。

掛接錯誤 (2) :沒有這類檔案或目錄

此錯誤表示 AKS 叢集與記憶體帳戶之間沒有連線。

初始疑難解答

Azure 檔案依賴 SMB 通訊協定 (埠 445) 。 請確定不會封鎖記憶體帳戶的埠 445 和/或 IP 位址。

若要檢查記憶體帳戶的 IP 位址,請執行網域名稱系統 (DNS) 指令,例如 nslookupdighost。 例如:

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

若要檢查 AKS 叢集與記憶體帳戶之間是否有連線,請進入 點或 Pod 內,然後執行下列 nctelnet 命令:

nc -v -w 2 <storage-account-name>.file.core.windows.net 445
telnet <storage-account-name>.file.core.windows.net 445

掛接錯誤的可能原因 (2)

注意事項

  • 原因 1、2 和 4 適用於公用和私人記憶體帳戶案例。
  • 原因 3 僅適用於公用案例。

原因 1:檔案共用不存在

若要檢查檔案共用是否存在,請遵循下列步驟:

  1. 搜尋 Azure 入口網站 中的記憶體帳戶,並存取您的記憶體帳戶。

    Azure 入口網站 中記憶體帳戶清單的螢幕快照。

  2. 選取記憶體帳戶中 [數據記憶體] 底下的 [檔案分享],並檢查 Pod、部署或 statefulset 之 yaml 檔案中的相關聯 PersistentVolumeClaim 是否存在於檔案共用中。

    選取記憶體帳戶中檔案共享的螢幕快照。

解決方案:確定檔案共用存在

若要解決此問題,請確定與 PV/PVC 相關聯的檔案共用存在。

原因 2:網路安全組會封鎖 AKS 與記憶體帳戶之間的流量

Check the output of the nc or telnet command mentioned in the Initial troubleshooting section. 如果顯示逾時,請檢查 網路安全組 (NSG) ,並確定未封鎖記憶體帳戶的IP位址。

若要檢查 NSG 是否封鎖記憶體帳戶的 IP 位址,請遵循下列步驟:

  1. 在 Azure 入口網站 中,移至 [網路監看員],然後選取 [NSG 診斷]

  2. 使用下列值填入欄位:

    • 通訊協定:任何
    • 方向:輸出
    • 來源類型:IPv4 位址/CIDR
    • IPv4 位址/CIDR:與 AKS 節點相關聯之實例的IP位址
    • 目的地 IP 位址:記憶體帳戶的 IP 位址
    • 目的地埠:445
  3. 選取 [ 檢查] 按鈕,然後檢查 [ 流量 ] 狀態。

[ 流量 ] 狀態可以是 [ 允許] 或 [ 拒絕]。 [ 拒絕 ] 狀態表示 NSG 封鎖了 AKS 叢集與記憶體帳戶之間的流量。 如果狀態為 [拒絕],則會顯示 NSG 名稱。

解決方案:允許 AKS 與記憶體帳戶之間的連線

若要解決此問題,請在 NSG 層級據以執行變更,以允許 AKS 叢集與埠 445 上的記憶體帳戶之間的連線。

原因 3:虛擬設備會封鎖 AKS 與記憶體帳戶之間的流量

例如,如果您使用虛擬設備 (通常是防火牆) 來控制 AKS 叢集 (的輸出流量,則虛擬設備會在 AKS 叢集的子網套用路由表,而路由表具有將流量傳送至虛擬設備) 的路由,則虛擬設備可能會封鎖 AKS 叢集與記憶體帳戶之間的流量。

若要隔離問題,請在路由表中為記憶體帳戶的IP位址新增路由,以將流量傳送至因特網。

若要確認哪個路由表控制 AKS 叢集的流量,請遵循下列步驟:

  1. 移至 Azure 入口網站 中的 AKS 叢集,然後選取 [屬性>基礎結構資源群組]
  2. 如果您使用這類 VM 集合類型,請 (VMSS) 或可用性設定組中的 VM 存取虛擬機擴展集。
  3. 選取 [虛擬網络/子網子網>],並識別 AKS 叢集的子網。 在右側,您會看到路由表。

若要在路由表中新增路由,請遵循 建立路由 中的步驟,並填入下列欄位:

  • 地址前綴: <storage-account's-public-IP>/32
  • 下一個躍點類型:因特網

此路由會透過公用因特網傳送 AKS 叢集與記憶體帳戶之間的所有流量。

新增路由之後,請使用 nctelnet 命令測試連線能力,然後再次執行掛接作業。

解決方案:確定虛擬設備允許 AKS 與記憶體帳戶之間的流量

如果掛接作業成功,建議您洽詢您的網路小組,以確定虛擬設備可以允許AKS 叢集與埠 445 上記憶體帳戶之間的流量。

原因 4:使用已啟用 FIPS 的節點集區

如果您使用 已啟用 FIPS) 節點集區的聯邦資訊處理標準 (,掛接作業將會失敗,因為 FIPS 會停用某些驗證模組,這會防止掛接 CIFS 共用。 這是預期的行為,而不是 AKS 特有的。

若要解決此問題,請使用下列其中一個解決方案:

解決方案 1:在非 FIPS 節點集區的節點上排程 Pod

預設會在 AKS 節點集區上停用 FIPS,而且只能在節點集區建立期間使用 參數來啟用 --enable-fips-image

若要解決此錯誤,您可以在非 FIPS 節點集區的節點上排程 Pod。

解決方案2:建立可在啟用FIPS的節點上排程的Pod

若要建立可在已啟用 FIPS 的節點上排程的 Pod,請遵循下列步驟:

  1. 使用 Azure 檔案 CSI 驅動程式建立使用 NFS 通訊協定的自定義 StorageClass。

    請參閱下列 YAML 檔案作為範例:

    kind: StorageClass 
    apiVersion: storage.k8s.io/v1 
    metadata: 
      name: azurefile-sc-fips 
    provisioner: file.csi.azure.com 
    reclaimPolicy: Delete 
    volumeBindingMode: Immediate 
    allowVolumeExpansion: true 
    parameters: 
      skuName: Premium_LRS 
      protocol: nfs 
    

    SKU 會設定為在 YAML 檔案中Premium_LRS,因為 NFS 需要進階 SKU。 如需詳細資訊,請參閱 動態布建

    由於進階 SKU,檔案共用的最小大小為 100GB。 如需詳細資訊,請 參閱建立儲存類別

  2. 建立參考自定義 StorageClass azurefile-sc-fips 的 PVC。

    請參閱下列 YAML 檔案作為範例:

    apiVersion: v1 
    kind: PersistentVolumeClaim 
    metadata: 
      name: azurefile-pvc-fips 
    spec: 
      accessModes: 
        - ReadWriteMany 
      storageClassName: azurefile-sc-fips 
      resources: 
        requests: 
          storage: 100Gi 
    
  3. 建立掛接 PVC azurefile-pvc-fips 的 Pod。

    請參閱下列 YAML 檔案作為範例:

    kind: Pod 
    apiVersion: v1 
    metadata: 
      name: azurefile-pod-fips 
    spec: 
      containers: 
      - name: azurefile-pod-fips 
        image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine 
        resources: 
          requests: 
            cpu: 100m 
            memory: 128Mi 
          limits: 
            cpu: 250m 
            memory: 256Mi 
        volumeMounts: 
        - mountPath: "/mnt/azure" 
          name: volume 
      volumes: 
        - name: volume 
          persistentVolumeClaim: 
            claimName: azurefile-pvc-fips 
    

掛接錯誤 (13) :許可權遭拒

以下是此錯誤的可能原因:

注意事項

  • 原因 1 適用於公用和私人案例。
  • 原因 2 僅適用於公用案例。
  • 原因 3 僅適用於私人案例。
  • 原因 4 適用於公用和私人案例。
  • 原因 5 適用於公用和私人案例。

原因 1:Kubernetes 秘密未參考正確的記憶體帳戶名稱或密鑰

如果檔案共用是以動態方式建立,則會自動建立名稱為 “azure-storage-account-storage-account-name-secret<>” 的 Kubernetes 秘密資源

如果手 建立檔案共用,則應手動建立 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 秘密中記憶體帳戶名稱或金鑰的值不符合記憶體帳戶中 Access 金鑰 中的值,請執行下列命令來調整 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 和子網。

    虛擬網路/子網值的螢幕快照。

  3. 存取 Azure 入口網站 中的記憶體帳戶。 選取 [網络]。 如果 [ 允許從 存取 ] 設定為 [ 選取的網络],請檢查是否已新增 AKS 叢集的 VNET 和子網。

    空白選取網路清單的螢幕快照。

    如果未新增 AKS 叢集的 VNET 和子網,請選取 [新增現有的虛擬網络]。 在 [ 新增網络] 頁面上,輸入 AKS 叢集的 VNET 和子網,然後選取 [ 新增>儲存]

    將網路新增至記憶體帳戶的螢幕快照。

    變更可能需要一些時間才會生效。 新增 VNET 和子網之後,請檢查 Pod 狀態是否從 ContainerCreating 變更為 執行中

    顯示目前 Pod 狀態的命令輸出螢幕快照。

原因 3:連線能力是透過私人連結,但節點和私人端點位於不同的 VNET 中

當 AKS 叢集和記憶體帳戶透過私人連結連線時,會使用已核准的私人端點連線。

私人端點連線的螢幕快照。

在此案例中,如果私人端點和 AKS 節點位於相同的 VNET 中,您將能夠掛接 Azure 檔案共用。

如果私人端點和您的 AKS 叢集位於不同的 VNET 中,掛接作業將會失敗,並出現「許可權遭拒」錯誤。

進入節點, 並檢查 FQDN (完整功能變數名稱是否已透過公用或私人IP位址解析) 。 若要執行此動作,請執行下列命令:

nslookup <storage-account-name>.privatelink.file.core.windows.net

如果透過公用IP位址解析 FQDN (請參閱下列螢幕快照) ,請在私人 DNS 區域 (「privatelink.file.core.windows.net」) 層級建立 AKS 叢集 VNET 的虛擬網路連結。 請注意,已針對記憶體帳戶私人端點的 VNET 自動建立虛擬網路連結。

顯示由公用IP位址解析 FQDN 的螢幕快照。

若要建立虛擬網路連結,請遵循下列步驟:

  1. 存取 私用 DNS 區域,然後選取 [虛擬網路連結>新增]

    此螢幕快照顯示已新增至記憶體帳戶的虛擬網路連結。

  2. 填入欄位,然後選取 虛擬網路的 AKS 叢集 VNET。 如需如何識別 AKS 叢集的 VNET,請參閱 解決方案:允許 AKS 的 VNET 和記憶體帳戶的子網 一節。

    顯示如何新增虛擬網路連結的螢幕快照。

  3. 選取 [確定]

新增虛擬網路連結之後,應該透過私人IP位址解析 FQDN,且掛接作業應該會成功。 如需範例,請參閱下列螢幕快照:

顯示已解析私人IP位址的螢幕快照。

原因 4:記憶體帳戶設定為需要用戶端不支援的加密

Azure 檔案儲存體 安全性設定包含數個選項,可用來控制記憶體帳戶上的安全性和加密設定。 限制允許的方法和演算法可能會防止客戶端連線。

1.25 之前的 AKS 版本是以 Ubuntu 18.04 LTS 為基礎,其使用 Linux 5.4 核心,且僅支援 AES-128-CCM 和 AES-128-GCM 加密演算法。 [最大安全性配置檔] 或停用 AES-128-GCM 的自定義配置檔會導致共用對應失敗。

AKS 1.25 版和更新版本是以 Ubuntu 22.04 為基礎,其使用 Linux 5.15 核心,並支援 AES-256-GCM。

解決方案:允許使用 AES-128-GCM 加密演算法

使用啟用 AES-128-GCM 的最大相容性 配置檔或 自訂 配置檔來啟用 AES-128-GCM 演算法。 如需詳細資訊,請參閱 Azure 檔案儲存體 安全性設定]

原因 5:不符合記憶體帳戶的最低加密需求

解決方案:為所有記憶體帳戶啟用 AES-128-GCM 加密演算法

若要成功掛接或存取檔案共用,應為所有記憶體帳戶啟用 AES-128-GCM 加密演算法。

如果您只想要使用 AES-256-GCM 加密,這是 SMB 3.1.1) 的最大安全性 (,請執行下列動作:

Linux

使用下列腳本來檢查用戶端是否支援 AES-256-GCM,並且只有在支援 AES-256-GCM 時才強制執行:

cifsConfPath="/etc/modprobe.d/cifs.conf" 
echo "`date` before change ${cifsConfPath}:"
cat ${cifsConfPath}
if !(( grep require_gcm_256 ${cifsConfPath} ))
then
modprobe cifs
echo 1 > /sys/module/cifs/parameters/require_gcm_256
echo "options cifs require_gcm_256=1" > ${cifsConfPath}
echo "`date` after changing ${cifsConfPath}:"
cat ${cifsConfPath}
fi

Windows

使用 Set-SmbClientConfiguration PowerShell 命令來指定 SMB 用戶端所使用的加密加密,以及慣用的加密類型,而不需要使用者確認:

Set-SmbClientConfiguration -EncryptionCiphers "AES_256_GCM" -Confirm:$false

注意事項

EncryptionCiphers適用於 x64 型系統的 Windows Server 21H2 2022-06 累積更新開始, (KB5014665 ) 和 Windows 11 版本 22H2 (KB5014668) 的累積更新開始,即可使用 參數。

其他相關資訊

如果您遇到其他掛接錯誤,請參閱針對Linux中的 Azure 檔案儲存體問題進行疑難解答

與我們連絡,以取得說明

如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以將產品意見反應提交給 Azure 意應見反社群