簡體   English   中英

ASP.NET Core 6 在 docker 容器中運行時無法解析數據庫名稱(在 WSL2 中)

[英]ASP.NET Core 6 cannot resolve database name when running in docker container (in WSL2)

我正在逐步對接 ASP.NET Core 6 應用程序,如下所示:

  • 我已經在 Windows 10 中設置了 WSL2 並安裝了 Racher Desktop。 這允許像在 WSL2 來賓中運行一樣運行 docker 命令
  • 我已經運行了一個 Postgresql 容器,從 Visual Studio 運行時,主機(Windows)pgAdmin 和 ASP.NET 核心都可以訪問它:
docker run -d -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -p 5433:5432 postgres

(在安裝 Postgres 之前,端口 5432 被某些服務劫持,我不得不使用另一個端口)。

從 Visual Studio 運行時,應用程序使用以下連接字符串:

Host=localhost:5433; Database=foo-next; Username=postgres; Password=postgres; Timeout=300; CommandTimeout=300

我為應用程序創建了一個 Dockerfile 和一個 docker 圖像。 運行時我收到以下錯誤:

Unhandled exception. System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name does not resolve
   at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch)
   at System.Net.Dns.<>c.<GetHostEntryOrAddressesCoreAsync>b__33_0(Object s, ValueStopwatch stopwatch)
   at System.Net.Dns.<>c__DisplayClass39_0`1.<RunAsync>b__0(Task <p0>, Object <p1>)
   at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Npgsql.TaskExtensions.ExecuteWithTimeout[TResult](Func`2 func, NpgsqlTimeout timeout, CancellationToken cancellationToken)
   at Npgsql.TaskExtensions.WithCancellation[T](Task`1 task, CancellationToken cancellationToken)
   at Npgsql.TaskExtensions.WithTimeout[T](Task`1 task, NpgsqlTimeout timeout)
   at Npgsql.Internal.NpgsqlConnector.ConnectAsync(NpgsqlTimeout timeout, CancellationToken cancellationToken)
   at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|191_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.UnpooledConnectorSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.ExistsAsync(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)

我將此解釋為應用程序無法解析postgres主機名。 我檢查了 Postgres 容器和 .NET Core 是否在同一個網絡中運行,它們似乎確實如此,但是我的應用程序網絡元數據缺少一些屬性:

Wehn 在容器中運行,應用程序使用以下連接字符串:

Host=postgres:5433; Database=foo-next-docker; Username=postgres; Password=postgres; Timeout=300; CommandTimeout=300
docker inspect postgres -f "{{json .NetworkSettings.Networks }}"
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"343ece236719b94d53df0afe1ab0d405a19102002f67ea60a1914016d4e4f96b","EndpointID":"9c3740b300caaf50f86731f00530dce62b386b56ccc2fe3da96c4cb677dcb42d","Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null}}

docker inspect foonextapp -f "{{json .NetworkSettings.Networks }}"
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"343ece236719b94d53df0afe1ab0d405a19102002f67ea60a1914016d4e4f96b","EndpointID":"","Gateway":"","IPAddress":"","IPPrefixLen":0,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"","DriverOpts":null}}

當顯式運行連接到bridge網絡的容器時,我得到的結果相同:

docker run -p 8080:80 --name fooapp fooapp --network=bridge

不確定它是否提供更多信息,但整個 docker 網絡列表如下:

docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
343ece236719   bridge     bridge    local
df0c354db7cf   host       host      local
6efb481fc02b   minikube   bridge    local
23bdb658109a   none       null      local

關於下一步嘗試什么以使在本地容器中運行的應用程序解析數據庫容器名稱的任何建議?

注意:所有命令都在 Windows 中運行。

您需要指定網絡別名,因為容器的主機名默認為容器的 ID

在 PowerShell 中:

docker network create app
docker run -dp 5433:5432 `
    -v pgdata:/var/lib/postgresql/data `
    -e POSTGRES_PASSWORD=postgres `
    --network app --network-alias postgres `
    postgres
docker run -dp 8080:80 --network app fooapp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM