掛接 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>。<

疑難排解之前

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

掛接 “@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、部署或具狀態集的 yaml 檔案中是否有相關聯的 PersistentVolumeClaim。

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

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

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

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

檢查初始疑難解答一節中提及的 nctelnet 命令輸出。 如果顯示逾時,請檢查 網路安全組 (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 與記憶體帳戶之間的流量

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

原因 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-pv-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 適用於公用和私人案例。
  • 原因 6 適用於公用和私人案例。

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

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

如果手動建立檔案共用,則應該手動建立 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 和子網。

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

  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

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

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

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

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

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

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

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

  3. 選取 [確定]。

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

顯示已解析私人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 加密,請執行下列動作:

Linux

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

cifsConfPath="/etc/modprobe.d/cifs.conf"
echo "$(date) before change ${cifsConfPath}:"
cat ${cifsConfPath}

# Check if 'require_gcm_256' is already present in the configuration file
if ! grep -q "require_gcm_256" "${cifsConfPath}"; then

    # Load the CIFS module
    modprobe cifs

    # Set the parameter at runtime
    echo 1 > /sys/module/cifs/parameters/require_gcm_256

    # Persist the configuration
    echo "options cifs require_gcm_256=1" >> "${cifsConfPath}"

    echo "$(date) after changing ${cifsConfPath}:"
    cat "${cifsConfPath}"
else
    echo "require_gcm_256 is already set in ${cifsConfPath}"
fi

您也可以使用 Kubernetes DaemonSet 在每個節點上強制執行 AES-256。 請參閱下列範例:

support-cifs-aes-256-gcm.yaml

Windows

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

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

注意

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

原因 6:未啟用 NTLM v2 驗證的安全性配置檔

當您在沒有啟用NTLM v2驗證機制的情況下使用 [最大安全性配置檔] 或 [自定義安全性配置檔] 時,掛接作業將會失敗,並出現「掛接錯誤(13):許可權遭拒」錯誤。

解決方案:啟用NTLM v2驗證或使用「最大相容性」配置檔

若要在 AKS 中正確掛接它,您必須啟用自訂安全性設定檔的 NTLM v2 驗證機制,或使用相容性安全性設定檔上限

其他相關資訊

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

與我們連絡,以取得說明

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