通过专用终结点使用私有注册表自定义镜像运行Bicep部署脚本
问题描述
我们正尝试在专用网络中使用Azure Bicep部署脚本,需调用存储在私有容器注册表中的自定义镜像,同时希望在脚本执行期间从JFrog Artifactory(或其他私有注册表)拉取额外模块或依赖。请问是否可行?能否配置ACI完成以下操作:
- 从私有容器注册表拉取自定义镜像;
- 在容器内从JFrog Artifactory(或任意私有注册表)拉取额外模块或依赖?
若可行,请提供指导:如何对容器实例进行身份验证以访问JFrog Artifactory或其他私有注册表,以及如何配置镜像在执行期间拉取所需模块。
额外信息:
- 使用Azure部署脚本+Bicep;
- 需确保自定义镜像可从JFrog等私有注册表拉取模块;
- 需提供容器实例与私有注册表交互的身份验证及配置步骤。
解决方案
完全可行,以下是具体实现步骤和配置说明:
一、配置ACI从私有容器注册表拉取自定义镜像
要让部署脚本使用私有ACR的自定义镜像,需在容器配置中添加注册表身份验证信息,同时确保用户分配的托管身份(MI)拥有ACR的AcrPull权限。
步骤1:给托管身份分配ACR拉取权限
通过Azure CLI为托管身份授予目标私有容器注册表的AcrPull角色:
az role assignment create --assignee <MI_CLIENT_ID> --scope <ACR_RESOURCE_ID> --role "AcrPull"
步骤2:在Bicep中配置容器注册表身份验证
修改部署脚本的containerSettings字段,添加私有注册表地址并指定使用托管身份进行验证。
二、配置容器内访问JFrog Artifactory的身份验证
容器内访问JFrog Artifactory主要有两种身份验证方式,可根据场景选择:
方式1:使用托管身份获取临时令牌(适用于支持Azure AD集成的私有注册表)
若JFrog Artifactory已配置Azure AD集成,可利用容器的托管身份获取访问令牌:
- 给托管身份分配JFrog Artifactory的读取权限;
- 在脚本中通过Azure AD获取令牌,用于拉取操作:
# 获取JFrog访问令牌 $token = (Get-AzAccessToken -ResourceUrl "<JFROG_AAD_RESOURCE_ID>").Token # 注册JFrog仓库并拉取PowerShell模块 Register-PSRepository -Name "JFrogRepo" -SourceLocation "https://<JFROG_URL>/artifactory/api/powershell/<REPO_NAME>" -InstallationPolicy Trusted Install-Module -Name "<MODULE_NAME>" -Repository "JFrogRepo" -AccessToken $token
方式2:使用环境变量传递凭据(适用于用户名/密码或API密钥认证)
将JFrog凭据存储在Azure Key Vault,通过托管身份读取后设置为环境变量:
- 将JFrog用户名和API密钥存入Azure Key Vault;
- 给托管身份分配Key Vault的
Secret Reader权限; - 在脚本中读取密钥并配置依赖拉取:
Connect-AzAccount -Identity $jfrogUser = Get-AzKeyVaultSecret -VaultName "<KV_NAME>" -Name "jfrog-username" -AsPlainText $jfrogApiKey = Get-AzKeyVaultSecret -VaultName "<KV_NAME>" -Name "jfrog-apikey" -AsPlainText # 配置npm仓库并拉取包 npm config set registry https://<JFROG_URL>/artifactory/api/npm/<REPO_NAME>/ npm config set //<JFROG_URL>/artifactory/api/npm/<REPO_NAME>/:username $jfrogUser npm config set //<JFROG_URL>/artifactory/api/npm/<REPO_NAME>/:_password $jfrogApiKey npm install <PACKAGE_NAME>
三、完整修改后的Bicep示例代码
param location string param subId string param usmiRG string param vnetName string param vnetRg string param subnetName string param storageAccountName string param currentTime string param acrServer string // 私有容器注册表地址,如xxx.azurecr.io param jfrogUrl string param kvName string // 现有用户分配托管身份 resource mngId 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = { name: 'xxxx' scope: resourceGroup(subId, usmiRG) } // 现有虚拟网络 resource vnet 'Microsoft.Network/virtualNetworks@2021-05-01' existing = { name: vnetName scope: resourceGroup(subId, vnetRg) } // 现有子网 resource containerInstanceSubnet 'Microsoft.Network/virtualNetworks/subnets@2021-05-01' existing = { name: subnetName parent: vnet } // 部署脚本资源 resource Script 'Microsoft.Resources/deploymentScripts@2023-08-01' = { name: 'scriptTestsi' location: location kind: 'AzurePowerShell' identity: { type: 'UserAssigned' userAssignedIdentities: { '${mngId.id}': {} } } properties: { azPowerShellVersion: '7.2' // 建议使用较新版本 containerSettings: { containerGroupName: 'mycustomaci-1' subnetIds: [ { id: containerInstanceSubnet.id } ] image: '${acrServer}/custom-image:latest' // 私有ACR中的自定义镜像 imageRegistryCredentials: [ { server: acrServer identity: mngId.id // 使用托管身份验证ACR } ] } scriptContent: ''' Param([string] $StorageAccountName, [string] $JfrogUrl, [string] $KvName) Connect-AzAccount -Identity # 示例1:用Azure AD令牌拉取JFrog PowerShell模块 $token = (Get-AzAccessToken -ResourceUrl "https://$JfrogUrl").Token Register-PSRepository -Name "JFrogRepo" -SourceLocation "https://$JfrogUrl/artifactory/api/powershell/my-powershell-repo" -InstallationPolicy Trusted Install-Module -Name "MyCustomModule" -Repository "JFrogRepo" -AccessToken $token -Force # 示例2:从Key Vault取凭据拉取npm包 $jfrogUser = Get-AzKeyVaultSecret -VaultName $KvName -Name "jfrog-username" -AsPlainText $jfrogApiKey = Get-AzKeyVaultSecret -VaultName $KvName -Name "jfrog-apikey" -AsPlainText npm config set registry https://$JfrogUrl/artifactory/api/npm/my-npm-repo/ npm config set //$JfrogUrl/artifactory/api/npm/my-npm-repo/:username $jfrogUser npm config set //$JfrogUrl/artifactory/api/npm/my-npm-repo/:_password $jfrogApiKey npm install my-npm-package # 原有存储账户操作 $DeploymentScriptOutputs["output"] = New-AzStorageContext -UseConnectedAccount -StorageAccountName $StorageAccountName ` | Get-AzStorageBlob -Container 'images' -Blob * | Out-String ''' arguments: '-StorageAccountName ${storageAccountName} -JfrogUrl ${jfrogUrl} -KvName ${kvName}' cleanupPreference: 'OnSuccess' retentionInterval: 'PT4H' forceUpdateTag: currentTime storageAccountSettings: { storageAccountName: storageAccountName storageAccountKey: listKeys(resourceId('Microsoft.Storage/storageAccounts', storageAccountName), '2019-06-01').keys[0].value } } } output scriptOutput string = Script.properties.outputs.output
关键注意事项
- 确保ACI所在子网已配置网络规则,允许访问私有容器注册表和JFrog Artifactory(专用网络环境下需配置对等连接或服务端点);
- 自定义镜像需预装必要工具(如npm、PowerShellGet等),以便拉取对应类型的依赖;
- 托管身份需同时拥有ACR的
AcrPull、Key Vault的Secret Reader(若使用Key Vault)以及JFrog的对应权限。
内容的提问来源于stack exchange,提问作者working_pod
相关产品推荐
相关产品推荐

