掛接 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) 指令,例如 nslookup
、 dig
或 host
。 例如:
nslookup <storage-account-name>.file.core.windows.net
若要檢查 AKS 叢集與記憶體帳戶之間是否有連線,請進入 節 點或 Pod 內,然後執行下列 nc
或 telnet
命令:
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:檔案共用不存在
若要檢查檔案共用是否存在,請遵循下列步驟:
搜尋 Azure 入口網站 中的記憶體帳戶,並存取您的記憶體帳戶。
選取記憶體帳戶中 [數據記憶體] 底下的 [檔案分享],並檢查 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 位址,請遵循下列步驟:
在 Azure 入口網站 中,移至 [網路監看員],然後選取 [NSG 診斷]。
使用下列值填入欄位:
- 通訊協定:任何
- 方向:輸出
- 來源類型:IPv4 位址/CIDR
- IPv4 位址/CIDR:與 AKS 節點相關聯之實例的IP位址
- 目的地 IP 位址:記憶體帳戶的 IP 位址
- 目的地埠:445
選取 [ 檢查] 按鈕,然後檢查 [ 流量 ] 狀態。
[ 流量 ] 狀態可以是 [ 允許] 或 [ 拒絕]。 [ 拒絕 ] 狀態表示 NSG 封鎖了 AKS 叢集與記憶體帳戶之間的流量。 如果狀態為 [拒絕],則會顯示 NSG 名稱。
解決方案:允許 AKS 與記憶體帳戶之間的連線
若要解決此問題,請在 NSG 層級據以執行變更,以允許 AKS 叢集與埠 445 上的記憶體帳戶之間的連線。
原因 3:虛擬設備會封鎖 AKS 與記憶體帳戶之間的流量
例如,如果您使用虛擬設備 (通常是防火牆) 來控制 AKS 叢集 (的輸出流量,則虛擬設備會在 AKS 叢集的子網套用路由表,而路由表具有將流量傳送至虛擬設備) 的路由,則虛擬設備可能會封鎖 AKS 叢集與記憶體帳戶之間的流量。
若要隔離問題,請在路由表中為記憶體帳戶的IP位址新增路由,以將流量傳送至因特網。
若要確認哪個路由表控制 AKS 叢集的流量,請遵循下列步驟:
- 移至 Azure 入口網站 中的 AKS 叢集,然後選取 [屬性>基礎結構資源群組]。
- 如果您使用這類 VM 集合類型,請 (VMSS) 或可用性設定組中的 VM 存取虛擬機擴展集。
- 選取 [虛擬網络/子網子網>],並識別 AKS 叢集的子網。 在右側,您會看到路由表。
若要在路由表中新增路由,請遵循 建立路由 中的步驟,並填入下列欄位:
- 地址前綴: <storage-account's-public-IP>/32
- 下一個躍點類型:因特網
此路由會透過公用因特網傳送 AKS 叢集與記憶體帳戶之間的所有流量。
新增路由之後,請使用 nc
或 telnet
命令測試連線能力,然後再次執行掛接作業。
解決方案:確定虛擬設備允許 AKS 與記憶體帳戶之間的流量
如果掛接作業成功,建議您洽詢您的網路小組,以確定虛擬設備可以允許AKS 叢集與埠 445 上記憶體帳戶之間的流量。
原因 4:使用已啟用 FIPS 的節點集區
如果您使用 已啟用 FIPS) 節點集區的聯邦資訊處理標準 (,掛接作業將會失敗,因為 FIPS 會停用某些驗證模組,這會防止掛接 CIFS 共用。 這是預期的行為,而不是 AKS 特有的。
若要解決此問題,請使用下列其中一個解決方案:
解決方案 1:在非 FIPS 節點集區的節點上排程 Pod
預設會在 AKS 節點集區上停用 FIPS,而且只能在節點集區建立期間使用 參數來啟用 --enable-fips-image
。
若要解決此錯誤,您可以在非 FIPS 節點集區的節點上排程 Pod。
解決方案2:建立可在啟用FIPS的節點上排程的Pod
若要建立可在已啟用 FIPS 的節點上排程的 Pod,請遵循下列步驟:
使用 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。 如需詳細資訊,請 參閱建立儲存類別。
建立參考自定義 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
建立掛接 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:Kubernetes 秘密未參考正確的記憶體帳戶名稱或密鑰
- 原因 2:記憶體帳戶不允許 AKS 的 VNET 和子網
- 原因 3:連線能力是透過私人連結,但節點和私人端點位於不同的 VNET 中
- 原因 4:記憶體帳戶設定為需要用戶端不支援的加密
- 原因 5:不符合記憶體帳戶的最低加密需求
注意事項
- 原因 1 適用於公用和私人案例。
- 原因 2 僅適用於公用案例。
- 原因 3 僅適用於私人案例。
- 原因 4 適用於公用和私人案例。
- 原因 5 適用於公用和私人案例。
原因 1:Kubernetes 秘密未參考正確的記憶體帳戶名稱或密鑰
如果檔案共用是以動態方式建立,則會自動建立名稱為 “azure-storage-account-storage-account-name-secret<>” 的 Kubernetes 秘密資源。
如果手 動建立檔案共用,則應手動建立 Kubernetes 秘密資源。
不論建立方法為何,如果 Kubernetes 秘密中參考的記憶體帳戶名稱或密鑰與實際值不符,掛接作業將會失敗,並出現「許可權遭拒」錯誤。
可能造成不相符的原因
如果以手動方式建立 Kubernetes 秘密,可能會在建立期間發生錯字。
如果在記憶體帳戶層級執行「輪替密鑰」作業,變更將不會反映在 Kubernetes 秘密層級。 這會導致記憶體帳戶層級的密鑰值與 Kubernetes 秘密層級的值不相符。
如果發生「輪替金鑰」作業,名為「重新產生記憶體帳戶密鑰」的作業將會顯示在記憶體帳戶的活動記錄中。 請留意 活動記錄的90天保留期間。
確認不相符
若要確認不相符,請遵循下列步驟:
搜尋 並存取 Azure 入口網站 中的記憶體帳戶。 選 取 [存取金鑰>][在記憶體帳戶中顯示金鑰 ]。 您會看到記憶體帳戶名稱和相關聯的金鑰。
移至 AKS 叢集,選取 [ 設定>秘密],然後搜尋並存取相關聯的秘密。
選取 [顯示 (眼睛圖示) ,然後比較記憶體帳戶名稱和相關密鑰的值與步驟 1 中的值。
選取 [顯示] 之前,儲存體帳戶名稱和相關密鑰的值會編碼為base64字串。 選取 [ 顯示] 之後,值會譯碼。
如果您無法存取 Azure 入口網站 中的 AKS 叢集,請在 kubectl 層級執行步驟 2:
取得 Kubernetes 秘密的 YAML 檔案,然後執行下列命令以從輸出中取得記憶體帳戶名稱和密鑰的值:
kubectl get secret <secret-name> -n <secret-namespace> -o <yaml-file-name>
使用 命令
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 和子網
執行下列命令來識別載入錯誤 Pod 的節點:
kubectl get pod <pod-name> -n <namespace> -o wide
從指令輸出檢查節點:
移至 Azure 入口網站 中的 AKS 叢集,選取 [屬性>基礎結構資源群組],存取與節點相關聯的 VMSS,然後檢查 [虛擬網络/子網] 以識別 VNET 和子網。
存取 Azure 入口網站 中的記憶體帳戶。 選取 [網络]。 如果 [ 允許從 存取 ] 設定為 [ 選取的網络],請檢查是否已新增 AKS 叢集的 VNET 和子網。
如果未新增 AKS 叢集的 VNET 和子網,請選取 [新增現有的虛擬網络]。 在 [ 新增網络] 頁面上,輸入 AKS 叢集的 VNET 和子網,然後選取 [ 新增>儲存]。
變更可能需要一些時間才會生效。 新增 VNET 和子網之後,請檢查 Pod 狀態是否從 ContainerCreating 變更為 執行中。
原因 3:連線能力是透過私人連結,但節點和私人端點位於不同的 VNET 中
當 AKS 叢集和記憶體帳戶透過私人連結連線時,會使用已核准的私人端點連線。
在此案例中,如果私人端點和 AKS 節點位於相同的 VNET 中,您將能夠掛接 Azure 檔案共用。
如果私人端點和您的 AKS 叢集位於不同的 VNET 中,掛接作業將會失敗,並出現「許可權遭拒」錯誤。
解決方案:在私人 DNS 區域建立 AKS 叢集 VNET 的虛擬網路連結
進入節點, 並檢查 FQDN (完整功能變數名稱是否已透過公用或私人IP位址解析) 。 若要執行此動作,請執行下列命令:
nslookup <storage-account-name>.privatelink.file.core.windows.net
如果透過公用IP位址解析 FQDN (請參閱下列螢幕快照) ,請在私人 DNS 區域 (「privatelink.file.core.windows.net」) 層級建立 AKS 叢集 VNET 的虛擬網路連結。 請注意,已針對記憶體帳戶私人端點的 VNET 自動建立虛擬網路連結。
若要建立虛擬網路連結,請遵循下列步驟:
存取 私用 DNS 區域,然後選取 [虛擬網路連結>新增]。
填入欄位,然後選取 虛擬網路的 AKS 叢集 VNET。 如需如何識別 AKS 叢集的 VNET,請參閱 解決方案:允許 AKS 的 VNET 和記憶體帳戶的子網 一節。
選取 [確定]。
新增虛擬網路連結之後,應該透過私人IP位址解析 FQDN,且掛接作業應該會成功。 如需範例,請參閱下列螢幕快照:
原因 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 意應見反社群。