繁体   English   中英

Dotnet Core Docker 容器泄漏 Linux 上的 RAM 并导致 OOM

[英]Dotnet Core Docker Container Leaks RAM on Linux and causes OOM

我在 Docker 的 Linux 容器中运行 Dotnet Core 2.2。

我尝试了许多不同的配置/环境选项 - 但我一直回到内存不足的相同问题(“docker events”报告 OOM)。

在生产中,我在 Ubuntu 上托管。 对于开发,我在 Windows 的 Docker 上使用 Linux 容器 (MobyLinux)。

我已经回去运行 Web API 模板项目,而不是我的实际应用程序。 我实际上是在返回一个字符串而不做其他任何事情。 如果我从 curl 调用它大约 1,000 次,容器就会死亡。 垃圾收集器似乎根本没有工作。

尝试在 docker-compose 中设置以下环境变量:

DOTNET_RUNNING_IN_CONTAINER=true
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
ASPNETCORE_preventHostingStartup=true

还在 docker-compose 中尝试了以下内容:

mem_reservation: 128m
mem_limit: 256m
memswap_limit: 256m

(这些只会让它死得更快)

尝试将以下设置为 true 或 false,没有区别:

ServerGarbageCollection

我试过作为 Windows 容器运行,这不是 OOM - 但它似乎也不尊重内存限制。

我已经排除了使用 HttpClient 和 EF Core - 因为我什至没有在我的示例中使用它们。 我读过一些关于侦听端口 443 的问题 - 因为我可以让容器整天闲置,如果我在一天结束时检查 - 它消耗了更多内存(不是大量的,但它增长)。

我的 API 中的内容示例:

// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "You said: " + id;
}

使用 Curl 调用示例:

curl -X GET "https://localhost:44329/api/values/7" -H  "accept: text/plain" --insecure

(重复 1,000 次左右)

预期:对于非常原始的请求,RAM 使用率保持较低

实际:RAM 使用量继续增长直到出现故障

完整的 Dockerfile:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM microsoft/dotnet:2.2-sdk 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

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

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

docker-compose.yml

version: '2.3'

services:
  webapplication1:
    image: ${DOCKER_REGISTRY-}webapplication1
    mem_reservation: 128m
    mem_limit: 256m
    memswap_limit: 256m
    cpu_percent: 25
    build:
      context: .
      dockerfile: WebApplication1/Dockerfile

docker-compose.override.yml

version: '2.3'

services:
  webapplication1:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_HTTPS_PORT=44329
      - DOTNET_RUNNING_IN_CONTAINER=true
      - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
      - ASPNETCORE_preventHostingStartup=true
    ports:
      - "50996:80"
      - "44329:443"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

我在 Windows 上运行 Docker CE Engine 18.0.9.1,在 Ubuntu 上运行 18.06.1。 确认 - 我也在 Dotnet Core 2.1 中尝试过。

我还在 IIS Express 中尝试了它 - 进程达到大约 55MB,这实际上是用多个线程向它发送垃圾邮件,等等。

当它们全部完成时,它会下降到大约 29-35MB。

这可能是因为未执行垃圾回收 (GC)。

看看这个未解决的问题,它看起来非常相似:

https://github.com/dotnet/runtime/issues/851

使Ubuntu 18.04.4在虚拟机上运行的一种解决方案是使用工作站垃圾收集 (GC):

<PropertyGroup>
    <ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>

https://github.com/dotnet/runtime/issues/851#issuecomment-644648315

https://github.com/dotnet/runtime/issues/851#issuecomment-438474207

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/workstation-server-gc

这是另一个发现:

经过进一步调查,我注意到我的服务器之间在可用逻辑 CPU 数量上存在很大差异(80 对 16)。 经过一番谷歌搜索后,我发现了这个主题dotnet/runtime#622 ,它引导我对 CPU/GC/Threads 设置进行实验。

我在堆栈文件中使用--cpus 约束 runtimeconfig.template.json文件中明确设置System.GC.Concurrent=true , System.GC.HeapCount=8 , System.GC.NoAffinitize=true , System.Threading.ThreadPool.MaxThreads=16 将图像更新为3.1.301-bionic sdk3.1.5-bionic asp.net 运行时——我以各种组合制作了所有这些东西,所有这些都没有效果。 应用程序只是挂起,直到被 OOMKilled。

使其与服务器 GC --cpuset-cpus工作的唯一因素是--cpuset-cpus约束。 当然,可用处理器的显式设置不是 docker swarm 模式的选项。 但是我正在尝试使用可用的 CPU 来找到任何规律。 在这里,我得到了一些有趣的事实。

有趣的是,之前我已经将 3 个其他后端服务迁移到一个新的服务器集群,并且它们在默认设置下都运行良好。 它们的内存限制设置为600 Mb但实际上它们需要大约400 Mb才能运行。 只有消耗内存的应用程序才会出错(我有两个),它需要3 Gb来构建内存结构并在6 Gb约束下运行。

它在[1, 35]可用 CPU 之间的任何范围内保持工作,并在 cpus 计数为36时挂起。

https://github.com/dotnet/runtime/issues/851#issuecomment-645237830

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM