连接到 azurite 使用主机名失败

huangapple go评论94阅读模式
英文:

Connecting to azurite using a hostname fails

问题

以下是您提供的内容的翻译部分:

UPDATE: 我可以确认此行为已在 Azure.Storage.Blobs 12.5.1 中修复。链接:https://www.nuget.org/packages/Azure.Storage.Blobs https://github.com/Azure/azure-sdk-for-net/issues/9404


我如何使用主机名连接到 azurite?

我正在尝试在 Docker 中使用 Azurite 模拟 Azure Blob 存储以进行集成测试。

一切运行良好,直到我必须通过主机名访问 Azurite(据我所知,这对于 Docker 网络是必需的)。

我的连接字符串如下(这是默认的众所周知的连接字符串):

"AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;"

我的 Azurite Docker Compose 的部分如下:

services:
  azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    hostname: azurite
    command: "azurite-blob --loose --blobHost 0.0.0.0"
    ports:
      - "10000:10000"
    volumes:
      - ./test/azurite:/data
    networks:
      - stillsnet

  images:
    container_name: images
    image: myapp/images
    build:
      context: .
      dockerfile: Dockerfile
    ports:
       - "5000:5000"
       - "5001:5001"
    environment:
      - ASPNETCORE_ENVIRONMENT=Test
      - ASPNETCORE_URLS=http://+:5000
      - imagesStorage__AzureBlobStorage__ConnectionString=AccountName=devstoreaccount1;DefaultEndpointsProtocol=http;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000;
    depends_on:
      - azurite
    links:
      - azurite
    networks:
      - stilssnet

我的代码如下:

private const string ConnectionString = "AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;";

[Fact]
public async Task UploadFile()
{
   var container = new BlobContainerClient(ConnectionString, "images");
   await using var stream = File.OpenRead(@"C:\temp\outputee9bc41-40ea-4d05-b180-e74bd5065622\images
private const string ConnectionString = "AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;";
[Fact]
public async Task UploadFile()
{
var container = new BlobContainerClient(ConnectionString, "images");
await using var stream = File.OpenRead(@"C:\temp\output\3ee9bc41-40ea-4d05-b180-e74bd5065622\images\00000000.jpg");
await container.UploadBlobAsync("test.jpg", stream);
}
000000.jpg"); await container.UploadBlobAsync("test.jpg", stream); }

这将引发异常:

System.Xml.XmlException : 根元素丢失。
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
   at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
   at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync_CreateResponse(Response response)
   at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri resourceUri, PublicAccessType access, Nullable`1 timeout, IDictionary`2 metadata, String requestId, Boolean async, String operationName, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.BlobContainerClient.CreateInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken, String operationName)
   at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsAsync(PublicAccessType publicAccessType, IDictionary`2 metadata, CancellationToken cancellationToken)

如果我将连接字符串从 azurite 更改为 127.0.0.1,一切都正常工作。

英文:

UPDATE: I can verify this behavior is fixed in Azure.Storage.Blobs 12.5.1 https://www.nuget.org/packages/Azure.Storage.Blobs https://github.com/Azure/azure-sdk-for-net/issues/9404


How can I connect to azurite using a hostname?

I'm trying to emulate Azure Blob Storage in docker using Azurite for integration tests.

All works well, to the point I have to access Azurite via a hostname (which is AFAIK required for docker networking)

My connection string looks like this (which is the default well-known connection string):

"AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;"

My docker compose part for azurite looks like this:

services:
  azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    hostname: azurite
    command: "azurite-blob --loose --blobHost 0.0.0.0"
    ports:
      - "10000:10000"
    volumes:
      - ./test/azurite:/data
    networks:
      - stillsnet

  images:
    container_name: images
    image: myapp/images
    build:
      context: .
      dockerfile: Dockerfile
    ports:
       - "5000:5000"
       - "5001:5001"
    environment:
      - ASPNETCORE_ENVIRONMENT=Test
      - ASPNETCORE_URLS=http://+:5000
      - imagesStorage__AzureBlobStorage__ConnectionString=AccountName=devstoreaccount1;DefaultEndpointsProtocol=http;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000;
    depends_on:
      - azurite
    links:
      - azurite
    networks:
      - stilssnet

my code looks like this:

private const string ConnectionString ="AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;";

[Fact]
public async Task UploadFile()
{
   var container = new BlobContainerClient(ConnectionString, "images");
   await using var stream = File.OpenRead(@"C:\temp\outputee9bc41-40ea-4d05-b180-e74bd5065622\images
private const string ConnectionString ="AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;";
[Fact]
public async Task UploadFile()
{
var container = new BlobContainerClient(ConnectionString, "images");
await using var stream = File.OpenRead(@"C:\temp\output\3ee9bc41-40ea-4d05-b180-e74bd5065622\images\00000000.jpg");
await container.UploadBlobAsync("test.jpg", stream);
}
000000.jpg"); await container.UploadBlobAsync("test.jpg", stream); }

this will throw an exception:

System.Xml.XmlException : Root element is missing.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
   at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
   at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync_CreateResponse(Response response)
   at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri resourceUri, PublicAccessType access, Nullable`1 timeout, IDictionary`2 metadata, String requestId, Boolean async, String operationName, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.BlobContainerClient.CreateInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken, String operationName)
   at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsAsync(PublicAccessType publicAccessType, IDictionary`2 metadata, CancellationToken cancellationToken)

If I change the connection string from azurite to 127.0.0.1 it all works fine.

答案1

得分: 6

这个网络中主机的名称是azurite,所以您可以使用此连接字符串 UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://azurite

对我来说可行,我认为这是正确的方法。

此外,您还可以使用传统的存储模拟器(包括表格),而不是azurite,您可以将其替换为 docker.host.internal

英文:

The host's name in that network is azurite, so you can use this connection string UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://azurite.

Works for me and I think is the way to do it.

Also you can use the legacy storage emulator (that includes Tables), instead of azurite you put docker.host.internal

答案2

得分: 3

UPDATE: 我可以确认这个问题在 Azure.Storage.Blobs 12.5.1 中已经修复。https://www.nuget.org/packages/Azure.Storage.Blobs
https://github.com/Azure/azure-sdk-for-net/issues/9404


看起来 BlobContainerClient 本身会从 URL 中剥离掉帐户名,如果你使用的不是 localhost 或 IP 地址,所以客户端生成了这个:

PUT /images?restype=container HTTP/1.1" 400 -
而不是
PUT /devstoreaccount1/images?restype=container HTTP/1.1 201

作为一个丑陋的变通办法,我们可以在针对 azurite 进行测试时将帐户名包含在容器名称中:
var container = new BlobContainerClient(ConnectionString, "devstoreaccount1/images");

尽管 await container.CreateIfNotExistsAsync(); 在 azurite 上不能正常工作(当它已经存在时会引发 409 异常...

所以我们要么有:

  • 一个丑陋的黑客
  • 放弃 azurite,选择一个真正的 Blob 存储帐户
  • 放弃 BlobContainerClient,它似乎根据主机名执行了太多的魔法。

这似乎与 Azurite 本身无关,或者理想情况下它应该支持与 Azure Blob 存储兼容的根 URL,而无需指定帐户名前缀。

英文:

UPDATE: I can verify this behavior is fixed in Azure.Storage.Blobs 12.5.1 https://www.nuget.org/packages/Azure.Storage.Blobs
https://github.com/Azure/azure-sdk-for-net/issues/9404


It looks like the BlobContainerClient itself strips away the account name from the URL if you use anything else than localhost or an IP address, so the client generates this:

PUT /images?restype=container HTTP/1.1" 400 -
instead of
PUT /devstoreaccount1/images?restype=container HTTP/1.1 201

As an ugly workaround we can include the account name in the container name when testing against azurite:
var container = new BlobContainerClient(ConnectionString, "devstoreaccount1/images");

Though await container.CreateIfNotExistsAsync(); doesn't work properly against azurite then (throws a 409 Exception when it already exist...

So we either have:

  • an ugly hack
  • dropping azurite in favor of a real blob storage account
  • dropping the BlobContainerClient which seems to perform too much magic based on the host name.

It doesn't seem to be related to Azurite itself, or ideally it should support root URL's that are compatible with the Azure blob store without having to specify the account name prefix.

答案3

得分: 1

问题的根本在于azure-storage-queue库内部如何拆分URL。我的问题通过使用更新版本的连接器来解决。我知道这是C#线程,但在Java中我也遇到了相同的问题。如果C#中的版本号相同,请使用12.6.0-beta.1或更高版本。

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-storage-queue</artifactId>
    <version>12.6.0-beta.1</version>
</dependency>

版本12.0.1似乎无法正常工作。

英文:

Root of the problem is how internals of azure-storage-queue library split URL. My problem was fix by usage of newer version of connector. I know that it's c# thread but in java I had the same problem. Please use 12.6.0-beta.1 or higher if version number is the same in c#.

&lt;dependency&gt;
    &lt;groupId&gt;com.azure&lt;/groupId&gt;
    &lt;artifactId&gt;azure-storage-queue&lt;/artifactId&gt;
    &lt;version&gt;12.6.0-beta.1&lt;/version&gt;
&lt;/dependency&gt;

version 12.0.1 doesn't seem to work properly.

答案4

得分: 0

我用以下命令运行了azurite(来自docker hub页面https://hub.docker.com/_/microsoft-azure-storage-azurite?tab=description)

docker run -p 10000:10000 -p 10001:10001 mcr.microsoft.com/azure-storage/azurite

我的配置文件只有这个:

<add name="BlobStorage" connectionString="UseDevelopmentStorage=true" />

在connectionStrings部分
(来自页面:https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#install-and-run-the-azurite-docker-image)

英文:

I ran the azurite with this command (from the docker hub page https://hub.docker.com/_/microsoft-azure-storage-azurite?tab=description)

docker run -p 10000:10000 -p 10001:10001 mcr.microsoft.com/azure-storage/azurite

my config file is just this:

&lt;add name=&quot;BlobStorage&quot; connectionString=&quot;UseDevelopmentStorage=true&quot; /&gt;

in the connectionStrings section
(from the page:
https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#install-and-run-the-azurite-docker-image)

答案5

得分: 0

I run both Sql server and Azurite. I just use docker compose to start them up. Notice the restart: always. this will start the containers when docker starts.
It's just like running the installed azure storage emulator.

version: "2"

services:

  sql-server-db:
    container_name: sql-server-db
    image: microsoft/mssql-server-linux:2017-latest
    restart: always
    ports:
      - "1433:1433"
      - "1434:1434"
    environment:
      SA_PASSWORD: "<EnterYourPasswordHere!!!>"
      ACCEPT_EULA: "Y"

  azure_storage_emulator:
    container_name: azurite
    image: mcr.microsoft.com/azure-storage/azurite
    restart: always
    ports:
      - "10001:10001"
      - "10000:10000"
英文:

I run both Sql server and Azurite. I just use docker compose to start them up. Notice the restart: always. this will start the containers when docker starts .
It's just like running the installed azure storage emulator.

version: &quot;2&quot;

services:

  sql-server-db:
    container_name: sql-server-db
    image: microsoft/mssql-server-linux:2017-latest
    restart: always
    ports:
      - &quot;1433:1433&quot;
      - &quot;1434:1434&quot;
    environment:
      SA_PASSWORD: &quot;&lt;EnterYourPasswordHere!!!&gt;&quot;
      ACCEPT_EULA: &quot;Y&quot;

  azure_storage_emulator:
    container_name: azurite
    image: mcr.microsoft.com/azure-storage/azurite
    restart: always
    ports:
      - &quot;10001:10001&quot;
      - &quot;10000:10000&quot;

huangapple
  • 本文由 发表于 2020年1月7日 00:09:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/59615330.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定