Docker 中 EF 上下文无响应

3

我刚将我的Web API应用程序升级到了.NET Core 3.0,在IIS Express的调试模式下一切正常,但是在Docker容器中无论是在服务器上还是在VS调试时,上下文没有响应。没有抛出任何错误,只是永远不响应。

我尝试将更新后的映像部署到服务器上,这是我首次注意到此问题。然后我尝试在VS中以Docker方式运行进行调试。 我已经更新了所有NuGet包并将框架设置为.NET Core 3.0或.NET Standard 2.1。 我在调试中检查了上下文连接字符串,它似乎是正确的。我回滚到使用.NET Core 2.2的早期映像,并使用相同的启动参数,一切都按预期工作。 我创建了一个不使用上下文的测试方法,在服务器和VS Docker调试中返回正确的值。 我尝试将方法更改为同步调用上下文,但行为没有任何改变。 测试数据库非常小,只有查询表中的3条记录。

    public async Task<List<SendingSystemInfoResponse>> getSendingSystemInfoList()
    {
        try
        {
            return await _context.EmailSendingSystem.Where(m => !m.Deleted && m.Active == true).Select(m => new SendingSystemInfoResponse
            {
                SystemId = m.EmailSendingSystemId,
                SystemName = m.Title,
                SystemDescription = m.Description

            }).ToListAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, string.Format("EmailDataAccess: Exception retrieving EmailSendingSystem List"));
            throw;
        }
    }

如果连接SQL Server时出现错误,或者SQL请求超时,我期望会触发catch块的代码,但这从未发生过。

以下是docker文件的内容,我不确定我的基础镜像和构建镜像的目标是否正确。它们似乎可以工作,但可能是我的问题的原因。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["EmailAutomation.API/EmailAutomation.API.csproj", "EmailAutomation.API/"]
COPY ["EmailAutomation.API/NuGet.Config", "/src"]
RUN dotnet restore "EmailAutomation.API/EmailAutomation.API.csproj"
COPY . .
WORKDIR "/src/EmailAutomation.API"
RUN dotnet build "EmailAutomation.API.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "EmailAutomation.API.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "EmailAutomation.API.dll"]

------更新------ 今天我一直在做这件事,有一些信息可能会帮助其他人指导我朝正确的方向。 我创建了一个简单的测试Web API项目,并使用.NET Core 3.0和最新的NuGet软件包连接到我本地 PC 上运行的 SQL Server的EF连接,同时还启用了SQL Server本地运行的TCP/IP连接。我成功连接到数据库并返回了值。

接下来,我在我的本地 SQL Server 上创建了测试数据库的副本。这也是有效的,原始问题中运行于 Docker 中的 Web API 连接并返回了数据。 然后,我将连接字符串更改为指向测试 SQL Server,并且在同样的位置挂起,没有错误。 接下来,我尝试使用仍然指向测试 SQL Server 的连接但在 IIS Express 而不是 Docker 中运行进行测试。一切都符合预期。

然后,我尝试运行先前发布的使用 .NET Core 2.2 的 Docker 镜像,它也从测试 SQL Server 返回数据。

为什么当所有其他组合都正常工作时,我无法使用 .NET Core 3.0 在 Docker 中通过IP连接到测试 SQL Server 呢?

------更新 2----- 我在 Test SQL Server 上为我的新的简单测试Web API项目创建了必要的数据库,并更改了简单的Web API项目连接字符串。当作为Docker运行时,这个新的、干净的、简单的.NET Core 3项目也没有连接到Test SQL Server,但是当在IIS Express上运行时它可以正常工作。当以 Docker 的形式运行并通过 IP 连接到我的本地数据库时,也可以正常工作。

.NET Core 3 在 Docker 中发生了变化,阻止它连接到外部数据库服务器。有人有任何关于我需要做什么来解决这个问题的想法吗?

--更新 3 ----- 感谢 MATT!读完MATT的回复后,我无法通过docker文件中的RUN命令解决问题,但将基础图像改为bionic确实起作用了。我也一直在与 Microsoft 支持团队合作,他们还指向了 Matt 提供的链接。 也许我只是没有在正确的位置放置 RUN 命令,所以如果有人可以提供一个使用 RUN 命令来解决此问题的示例 Docker 文件,我将不胜感激。 这里是一个来自一个简单测试项目的更新的 Docker 文件:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-bionic AS base
    WORKDIR /app
    EXPOSE 80

    FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
    WORKDIR /src
    COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
    RUN dotnet restore "WebApplication1/WebApplication1.csproj"
    COPY . .
    WORKDIR "/src/WebApplication1"
    RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build

    FROM build AS publish
    RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish

    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "WebApplication1.dll"]

--- 最终更新 -----

我再次尝试使用Docker文件中的RUN命令,这次做对了。以下是那个版本的Docker文件。

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
    WORKDIR /app
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
    EXPOSE 80

    FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
    WORKDIR /src
    COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
    RUN dotnet restore "WebApplication1/WebApplication1.csproj"
    COPY . .
    WORKDIR "/src/WebApplication1"
    RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build

    FROM build AS publish
    RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish

    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "WebApplication1.dll"]

感谢您更新此问题。可以确认最终更新确实解决了该问题。但是,要注意@Matt Thalman所说的 - 这并不是一个长期的解决方案。 - Terrance00
1个回答

2
我相信你遇到的问题在这里有记录:https://github.com/dotnet/SqlClient/issues/222。正如你所说,.NET Core 3 发生了一些变化,因为这些 Docker 镜像默认基于 Debian Buster。Buster 的最小 TLS 协议配置为 1.2,这是与之前版本不同的更改(请参见 https://www.debian.org/releases/stable/amd64/release-notes/ch-information.en.html#openssl-defaults)。
可以通过将以下内容添加到 Dockerfile 中来暂时解决此问题:
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf

这并不是一个好的解决方案,因为它本质上是降低了TLS版本。更好的长期解决方案是在SQL Server上启用TLS 1.2(请参见https://support.microsoft.com/zh-cn/help/3135244/tls-1-2-support-for-microsoft-sql-server)。


1
将Matt的回答标记为答案。我找不到正确的方法将两个RUN命令放入docker文件中以使其正常工作,但是GitHub链接确实提到了使用aspnet:3.0-bionic镜像并将我的基础镜像更改为此镜像对我有用。 - David Violett
在Dockerfile中是否有特定的位置应该放置它?或者它可以放置在文件的任何位置? - Tim
我在问题的末尾添加了示例dockerfile,其中包含适用于不同基础镜像和运行命令降级TLS的放置方式。 - David Violett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接