快速入门:适用于 Go 的 Azure Blob 存储客户端模块

开始使用适用于 Go 的 Azure Blob 存储客户端模块来管理 Blob 和容器。 请按照以下步骤安装程序包并试用基本任务的示例代码。

API 参考文档 | 库源代码 | 包 (pkg.go.dev)

先决条件

设置

本部分逐步指导如何准备一个项目,使其与适用于 Go 的 Azure Blob 存储客户端模块配合使用。

下载示例应用程序

本快速入门中使用的示例应用程序是基本的 Go 应用程序。

使用 git 可将应用程序的副本下载到开发环境。

git clone https://github.com/Azure-Samples/storage-blobs-go-quickstart 

此命令会将存储库克隆到本地 git 文件夹。 若要打开 Blob 存储的 Go 示例,请查找名为 storage-quickstart.go 的文件。

安装包

若要使用存储帐户中的 Blob 和容器资源,请使用以下命令安装 azblob 包:

go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob

若要使用 Microsoft Entra ID 进行身份验证(推荐),请使用以下命令安装 azidentity 模块:

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

向 Azure 进行身份验证并授权访问 Blob 数据

对 Azure Blob 存储的应用程序请求必须获得授权。 建议使用 DefaultAzureCredential 和 Azure 标识客户端库在代码中实现与 Azure 服务(包括 Blob 存储)的无密码连接。

你还可以使用帐户访问密钥授权对 Azure Blob 存储的请求。 但是,应谨慎使用此方法。 开发人员必须尽量避免在不安全的位置公开访问密钥。 具有访问密钥的任何人都可以授权针对存储帐户的请求,并且实际上有权访问所有数据。 DefaultAzureCredential 提供比帐户密钥更好的管理和安全优势,来实现无密码身份验证。 以下示例演示了这两个选项。

DefaultAzureCredential 是由用于 Go 的 Azure 标识客户端库提供的凭据链实现。 DefaultAzureCredential 支持多种身份验证方法,并确定应在运行时使用哪种方法。 通过这种方法,你的应用可在不同环境(本地与生产)中使用不同的身份验证方法,而无需实现特定于环境的代码。

若要详细了解 DefaultAzureCredential 查找凭据的顺序和位置,请参阅 Azure 标识库概述

例如,应用可在本地开发时使用 Azure CLI 登录凭据进行身份验证。 一旦部署到 Azure,你的应用就可以使用托管标识。 环境之间的这种转换不需要任何代码更改。

将角色分配至 Microsoft Entra 用户帐户

在本地开发时,请确保访问 Blob 数据的用户帐户具有正确的权限。 需有“存储 Blob 数据参与者”角色才能读取和写入 Blob 数据。 若要为你自己分配此角色,需要具有“用户访问管理员”角色,或者具有包含 Microsoft.Authorization/roleAssignments/write 操作的其他角色。 可使用 Azure 门户、Azure CLI 或 Azure PowerShell 向用户分配 Azure RBAC 角色。 可以在范围概述页上详细了解角色分配的可用范围。

在此方案中,你将为用户帐户分配权限(范围为存储帐户)以遵循最低权限原则。 这种做法仅为用户提供所需的最低权限,并创建更安全的生产环境。

以下示例将“存储 Blob 数据参与者”角色分配给用户帐户,该角色提供对存储帐户中 Blob 数据的读取和写入访问权限。

重要

在大多数情况下,角色分配在 Azure 中传播需要一两分钟的时间,但极少数情况下最多可能需要 8 分钟。 如果在首次运行代码时收到身份验证错误,请稍等片刻再试。

  1. 在 Azure 门户中,使用主搜索栏或左侧导航找到存储帐户。

  2. 在存储帐户概述页的左侧菜单中选择“访问控制 (IAM)”。

  3. 在“访问控制 (IAM)”页上,选择“角色分配”选项卡。

  4. 从顶部菜单中选择“+ 添加”,然后从出现的下拉菜单中选择“添加角色分配”。

    显示如何分配角色的屏幕截图。

  5. 使用搜索框将结果筛选为所需角色。 在此示例中,搜索“存储 Blob 数据参与者”并选择匹配的结果,然后选择“下一步”。

  6. 在“访问权限分配对象”下,选择“用户、组或服务主体”,然后选择“+ 选择成员”。

  7. 在对话框中,搜索 Microsoft Entra ID 用户名(通常是 user@domain 电子邮件地址),然后选中对话框底部的“选择”。

  8. 选择“查看 + 分配”转到最后一页,然后再次选择“查看 + 分配”完成该过程。

使用 DefaultAzureCredential 登录并将应用代码连接到 Azure

可按照以下步骤授权访问存储帐户中的数据:

  1. 确保在存储帐户上向将角色分配到的同一 Microsoft Entra 帐户进行身份验证。 以下示例演示了如何通过 Azure CLI 进行身份验证:

    az login
    
  2. 若要在 Go 应用程序中使用 DefaultAzureCredential,请使用以下命令安装 azidentity 模块:

    go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
    

Azure CLI 身份验证不推荐用于在 Azure 中运行的应用程序。 部署到 Azure 时,你可以使用相同的代码来授权 Azure 中运行的应用程序对 Azure 存储的请求。 但是,你需要在 Azure 中的应用上启用托管标识,并将存储帐户配置为允许该托管标识进行连接。 有关在 Azure 服务之间配置此连接的详细说明,请参阅 Azure 托管应用中的身份验证教程。

若要详细了解不同的身份验证方法,请参阅使用 Azure SDK for Go 进行 Azure 身份验证

运行示例

该代码示例执行以下操作:

  • 创建授权通过 DefaultAzureCredential 访问数据的客户端对象
  • 在存储帐户中创建容器
  • 将 Blob 上传到容器
  • 列出容器中的 Blob
  • 将 Blob 数据下载到缓冲区
  • 删除应用创建的 Blob 和容器资源

在运行示例之前,请打开 storage-quickstart.go 文件。 将 <storage-account-name> 替换为 Azure 存储帐户的名称。

然后使用以下命令来运行应用程序:

go run storage-quickstart.go

应用的输出类似于以下示例:

Azure Blob storage quick start sample
Creating a container named quickstart-sample-container
Uploading a blob named sample-blob
Listing the blobs in the container:
sample-blob
Blob contents:

Hello, world! This is a blob.

Press enter key to delete resources and exit the application.

Cleaning up.
Deleting the blob sample-blob
Deleting the container quickstart-sample-container

在提示符下按 Enter 键时,示例程序会删除应用创建的 Blob 和容器资源。

提示

还可以使用工具(如 Azure 存储资源管理器)查看 Blob 存储中的文件。 Azure 存储资源管理器是免费的跨平台工具,可用于访问存储帐户信息。

了解示例代码

接下来,我们来逐步查看示例代码,了解其工作方式。

授予访问权限并创建客户端对象

使用 SDK 处理任何 Azure 资源从创建客户端对象开始。 为了创建客户端对象,代码示例将使用以下值调用 azblob.NewClient

  • serviceURL - 存储帐户的 URL
  • cred - 通过 azidentity 模块获取的 Microsoft Entra 凭据
  • options - 客户端选项;传递 nil 以接受默认值

以下代码示例创建一个客户端对象,以与存储帐户中的容器和 Blob 资源进行交互:

// TODO: replace <storage-account-name> with your actual storage account name
url := "https://<storage-account-name>.blob.core.chinacloudapi.cn/"
ctx := context.Background()

credential, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

client, err := azblob.NewClient(url, credential, nil)
handleError(err)

创建容器

该代码示例在存储帐户中创建新的容器资源。 如果已存在同名容器,则会引发 ResourceExistsError

重要

容器名称必须为小写。 若要详细了解容器和 Blob 的命名要求,请参阅命名和引用容器、Blob 与元数据

以下代码示例在存储帐户中创建名为 quickstart-sample-container 的新容器:

// Create the container
containerName := "quickstart-sample-container"
fmt.Printf("Creating a container named %s\n", containerName)
_, err = client.CreateContainer(ctx, containerName, nil)
handleError(err)

若要详细了解如何创建容器并浏览更多代码示例,请参阅使用 Go 创建 Blob 容器

将 blob 上传到容器

该代码示例将创建包含某些数据的字节数组,并将数据作为缓冲区上传到指定容器中的新 Blob 资源。

以下代码示例使用 UploadBuffer 方法将 Blob 数据上传到指定的容器:

data := []byte("\nHello, world! This is a blob.\n")
blobName := "sample-blob"

// Upload to data to blob storage
fmt.Printf("Uploading a blob named %s\n", blobName)
_, err = client.UploadBuffer(ctx, containerName, blobName, data, &azblob.UploadBufferOptions{})
handleError(err)

若要详细了解如何上传 Blob 并浏览更多代码示例,请参阅使用 Go 上传 Blob

列出容器中的 Blob

该代码示例将列出指定容器中的 Blob。 此示例使用 NewListBlobsFlatPager,它会从指定标记开始为 Blob 返回分页。 在这里,我们使用空的标记从头开始枚举,并继续分页,直到没有更多结果。 此方法按字典顺序返回 Blob 名称。

以下代码示例列出了指定容器中的 Blob:

// List the blobs in the container
fmt.Println("Listing the blobs in the container:")

pager := client.NewListBlobsFlatPager(containerName, &azblob.ListBlobsFlatOptions{
	Include: azblob.ListBlobsInclude{Snapshots: true, Versions: true},
})

for pager.More() {
	resp, err := pager.NextPage(context.TODO())
	handleError(err)

	for _, blob := range resp.Segment.BlobItems {
		fmt.Println(*blob.Name)
	}
}

若要详细了解如何列出 Blob 并浏览更多代码示例,请参阅使用 Go 列出 Blob

下载 Blob

该代码示例使用 DownloadStream 方法下载 Blob,并创建用于读取数据的重试读取器。 如果某个连接在读取时断开,则重试读取器会发出其他请求来重建连接并继续读取。 可以使用 RetryReaderOptions 结构来指定重试读取器选项。

以下代码示例下载 Blob 并将内容写入控制台:

// Download the blob
get, err := client.DownloadStream(ctx, containerName, blobName, nil)
handleError(err)

downloadedData := bytes.Buffer{}
retryReader := get.NewRetryReader(ctx, &azblob.RetryReaderOptions{})
_, err = downloadedData.ReadFrom(retryReader)
handleError(err)

err = retryReader.Close()
handleError(err)

// Print the contents of the blob we created
fmt.Println("Blob contents:")
fmt.Println(downloadedData.String())

若要详细了解如何下载 Blob 并浏览更多代码示例,请参阅使用 Go 下载 Blob

清理资源

如果不再需要本快速入门中上传的 Blob,则可以使用 DeleteBlob 方法删除单个 Blob,或使用 DeleteContainer 方法删除整个容器及其内容。

// Delete the blob
fmt.Printf("Deleting the blob " + blobName + "\n")

_, err = client.DeleteBlob(ctx, containerName, blobName, nil)
handleError(err)

// Delete the container
fmt.Printf("Deleting the container " + containerName + "\n")
_, err = client.DeleteContainer(ctx, containerName, nil)
handleError(err)

若要详细了解如何删除 Blob 和容器并浏览更多代码示例,请参阅使用 Go 删除 Blob使用 Go 删除容器

下一步