dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

MaxWorkingSet has wrong value when setting container memory limit #81372

Closed glucaci closed 3 months ago

glucaci commented 1 year ago

Description

When trying to use the Process.GetCurrentProcess().MaxWorkingSet on a linux host, it's using underlining the cgroup V1 or V2. In code and also on the Kubernetes docs it's only specify cgroup2fs and tmpfs.

When I did a test on our AKS cluster I receive as DriverFormat the sharefs which make than the MaxWorkingSet will be always long.MaxValue.

Trying to debug it locally in a normal container on Docker it's also sharefs.

Following the Kubernetes docs to identify the cgroup version it's tmpfs.

image

Reproduction Steps

Create new console app, add docker support for linux, add docker run args --memory=1g and use the following code:

internal class Program
{
   private const string SysFsCgroupFileSystemPath = "/sys/fs/cgroup";

   static void Main(string[] args)
   {
      var driveInfo = new DriveInfo(SysFsCgroupFileSystemPath);
      Console.WriteLine($"DriverFormat {driveInfo.DriveFormat}");
      Console.WriteLine($"MaxWorkingSet: {Process.GetCurrentProcess().MaxWorkingSet}");
      Console.ReadLine();
   }
}

Expected behavior

MaxWorkingSet should be equal with the output from cat /sys/fs/cgroup/memory/memory.limit_in_bytes

Actual behavior

MaxWorkingSet is falling back to long.MaxValue because sharefs is not supported. Interop.cgroups.cs

Regression?

No response

Known Workarounds

No response

Configuration

.NET 7

AKS with Kubernetes v1.24.6 Docker Desktop 4.15.0

base image used for demo application mcr.microsoft.com/dotnet/runtime:7.0

Other information

No response

dotnet-issue-labeler[bot] commented 1 year ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

glucaci commented 1 year ago

Only by mapping the sharefs also to cgroup V1

return new DriveInfo(SysFsCgroupFileSystemPath).DriveFormat switch
{
   "cgroup2fs" => CGroupVersion.CGroup2,
   "tmpfs" or "sharefs" => CGroupVersion.CGroup1,
   _ => CGroupVersion.None,
};

seams everything to work as expected.

DriveFormat: sharefs
MaxWorkingSet: 1073741824
glucaci commented 1 year ago

There are any news?

janvorli commented 3 months ago

This should have been fixed by #99508 in .NET 9 Preview 6.