You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Bicep的VM Run Command在Azure Linux虚拟机挂载文件共享失败排查

排查与解决步骤

1. 先查看Run Command执行日志

登录Azure门户,找到目标VM,进入运行命令,选择samount命令,查看执行输出和错误输出,定位具体失败环节。这是最直接的排查方式,能明确脚本中哪一步出现问题。

2. 修复脚本变量传递问题

你的脚本直接使用$resourceGroupName和$storageAccountName占位符,但Bicep未将实际值注入脚本,导致az命令执行失败。需要在Bicep中定义参数并拼接进脚本:

param storageAccountName string
param storageAccountRgName string

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' existing = {
  name: 'rabolinuxvm'
}

resource customextensionscript 'Microsoft.Compute/virtualMachines/runCommands@2022-11-01' = {
  name: 'samount'
  parent: vm
  location: 'eastus'
  properties: {
    source: {
      script: ''' 
      sudo mkdir /etc/share3                
      credentialRoot="/etc/smbcredentials"
      sudo mkdir -p "$credentialRoot"
      storageAccountKey=$(az storage account keys list \\
        --resource-group ''' + storageAccountRgName + ''' \\
        --account-name ''' + storageAccountName + ''' \\
        --query "[0].value" --output tsv | tr -d '"')

      smbCredentialFile="$credentialRoot/''' + storageAccountName + '''.cred"

      if [ ! -f $smbCredentialFile ]; then
         echo "username=''' + storageAccountName + '''" | sudo tee $smbCredentialFile > /dev/null
         echo "password=$storageAccountKey" | sudo tee -a $smbCredentialFile > /dev/null
      else
        echo "The credential file $smbCredentialFile already exists, and was not modified."
      fi

      sudo chmod 600 $smbCredentialFile
      fileShareName="share4" 
      mntPath="/mnt/$fileShareName"
      sudo mkdir -p $mntPath
      httpEndpoint=$(az storage account show \\
        --resource-group ''' + storageAccountRgName + ''' \\
        --name ''' + storageAccountName + ''' \\
        --query "primaryEndpoints.file" --output tsv | tr -d '"')

      smbPath=$(echo $httpEndpoint | cut -c7-${#httpEndpoint})$fileShareName

     if [ -z "$(grep "$smbPath $mntPath" /etc/fstab)" ]; then
        echo "$smbPath $mntPath cifs nofail,credentials=$smbCredentialFile,serverino,nosharesock,actimeo=30" | sudo tee -a /etc/fstab > /dev/null
     else
       echo "/etc/fstab was not modified to avoid conflicting entries as this Azure file share was already present. You may want to double check /etc/fstab to ensure the configuration is as desired."
     fi
     sudo mount -a  
     '''
    }
  }
}

说明:Bicep用+拼接字符串,脚本内换行需用\\转义,避免解析错误;同时将挂载点改为/mnt目录,减少系统目录权限冲突。

3. 给VM分配存储账户访问权限

由于存储账户在不同资源组,需给VM的系统分配身份添加存储账户密钥操作员角色,确保VM能获取存储账户密钥:

  • 启用VM系统分配身份:
    resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' existing = {
      name: 'rabolinuxvm'
      identity: {
        type: 'SystemAssigned'
      }
    }
    
  • 在存储账户所在资源组分配角色:
    resource storageAccountKeyRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
      name: guid(storageAccountId, vm.id, 'StorageAccountKeyOperator')
      scope: resourceGroup(storageAccountRgName)
      properties: {
        roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12') // 存储账户密钥操作员角色ID
        principalId: vm.identity.principalId
      }
    }
    

4. 安装SMB依赖包

Linux挂载SMB共享需要cifs-utils,在脚本开头添加安装命令(根据系统选择):

# Debian/Ubuntu系统
sudo apt-get update && sudo apt-get install -y cifs-utils
# RHEL/CentOS系统
# sudo yum install -y cifs-utils

5. 修复脚本语法问题

  • 原脚本中部分命令被拆分行导致不完整,需将echo "password=$storageAccountKey"等命令合并为完整一行;
  • grep命令需用引号包裹参数,避免路径含特殊字符时出错:grep "$smbPath $mntPath"

6. 手动验证挂载逻辑

如果脚本执行后fstab已添加条目但未挂载,登录VM执行sudo mount -a,查看具体报错,排查存储账户防火墙是否允许VM访问、挂载点权限是否正常等问题。

内容的提问来源于stack exchange,提问作者ramesh reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:32:37