[英]C# and Docker - Can't connect to containerized MySQL server from containerized .NET Core 3.1 Web API
[英]Can't connect to docker sql server from NET Core 2.2 Web API
在收集結合 docker 編寫 .NET Core Web API 的知識時,我遇到了一個無法解決的錯誤。 我已經在互聯網上進行了研究,但不知何故,提供的解決方案都不適合我。
我有一個名為Catalog.API
的 Web 服務(類似於 Microsoft 的 eShopOnContainers 項目),其中有一個名為CatalogController
的控制器。
這是控制器的代碼:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Catalog.API.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Catalog.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class CatalogController : ControllerBase
{
private readonly CatalogItemContext _context;
public CatalogController(CatalogItemContext context)
{
_context = context;
}
public async Task<List<CatalogItem>> GetItemsAsync()
{
var items = await _context.CatalogItems.Where(model => model.Id < 10).ToListAsync();
return items;
}
}
}
如您所見,我只有一種方法可以從外部數據庫中返回 id 小於 10 的所有項目。
數據庫添加到Startup.cs
:
namespace Catalog.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CatalogItemContext>(builder =>
{
builder.UseSqlServer(Configuration.GetConnectionString("Default"));
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
appsettings.json
看起來像這樣:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Default": "Server=localhost,1433;Initial Catalog=Test.Services.CatalogDb;User Id=sa;Password=Pass@word"
}
}
為了構建這個 Web 服務,我創建了一個從docker-compose.yml
調用docker-compose.yml
:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY src/Services/Catalog/Catalog.API/Catalog.API.csproj /src/csproj-files/
WORKDIR ./csproj-files
RUN dotnet restore
WORKDIR /src
COPY . .
WORKDIR /src/src/Services/Catalog/Catalog.API/
RUN dotnet publish -c Release -o /app
FROM build AS publish
FROM base as final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Catalog.API.dll"]
docker-compose.yml
如下所示:
version: '3.4'
services:
sqldata:
ports:
- 1433:1433
image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Pass@word
catalog.api:
ports:
- 80:80
build:
context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
depends_on:
- sqldata
如前所述,除了 Catalog.API Web 服務之外,我還在 docker 容器中運行 SQL Server 數據庫。 出於開發目的,我使用 localhost 或我的機器 ip 作為主機地址( localhost
或192.168.2.101
)從 DataGrip 連接到此 SQL Server。 兩種方式都可以正常工作,我可以在 DataGrip 內部建立連接而不會出現問題。
我的問題是我無法從我的CatalogController
的 docker 容器內部連接到 SQL Server,在 localhost:80 上運行。 通常,當我調用localhost:80/api/catalog
,我應該從數據庫中取出所有項目(請參閱開頭的控制器),但不知何故,我收到此錯誤:
失敗:Microsoft.EntityFrameworkCore.Database.Connection[20004]
使用與服務器 'localhost,1433' 上的數據庫 'Test.Services.CatalogDb' 的連接時發生錯誤。
System.Data.SqlClient.SqlException (0x80131904):建立與 SQL Server 的連接時發生與網絡相關或特定於實例的錯誤。 服務器未找到或無法訪問。 驗證實例名稱是否正確以及 SQL Server 是否配置為允許遠程連接。 (提供程序:TCP 提供程序,錯誤:40 - 無法打開與 SQL Server 的連接)在 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransient accessTokenHandling)
在 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
在 System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
在 System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
在 System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- 從上一個拋出異常的位置開始的堆棧跟蹤結束 ---在 Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancelationToken) ClientConnectionId:00000000-0000-0000-0000-000000000000
我已經嘗試使用多個 ips(本地主機,我的機器 ip + docker inspect 中的 ip),但沒有一個工作正常。
Server=192.168.2.101,1433;Initial Catalog=Test.Services.CatalogDb;User Id=sa;Password=Pass@word
我願意接受一切可以解決我的問題的幫助。 提前致謝。
SQL Server 實例不在本地主機上。 在 Web 應用的上下文中,localhost 是運行 Web 應用的容器,它與 SQL Server 所在的容器不同。
使用 Docker Compose 時,服務名稱以主機名結尾,這意味着您可以簡單地連接到sqldata,1433
。
添加服務名稱而不是 IP 有效,但是每當我使用“dotnet ef migrations add xyz”和“dotnet ef database update”遷移數據庫時,我都會收到錯誤消息。 它說,找不到或無法訪問服務器.. 所以現在我可以連接,但不能使用 dotnet ef。
主機名僅在運行 docker 容器的 vlan 內有效,這與您的台式機所在的 vlan 不同。要訪問 SQL Server 容器,您必須將docker container exec
到其中一個容器中並運行命令從那里( sqldata
主機名將存在的地方)或者您必須使用容器的 IP 地址,您可以通過運行docker container ls
來獲取容器 id (guid),然后運行docker inspect {container id}
。 IP 地址將在生成的 JSON 的NetworkSettings
部分中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.