Skip to main content
edited tags
Link
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i

[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll

[Install]
WantedBy=multi-user.target
[Unit]
Description=My Service %i
    
[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll
    
[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll and this again sort of works, but not reliably: the memory limit I wrote to memory.limit_in_bytes got reset at some point and I don't know when or why.

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i

[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll

[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll and this again sort of works, but not reliably: the memory limit I wrote to memory.limit_in_bytes got reset at some point and I don't know when or why.

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i
    
[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll
    
[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll and this again sort of works, but not reliably: the memory limit I wrote to memory.limit_in_bytes got reset at some point and I don't know when or why.

deleted 2 characters in body
Source Link
EM0
  • 515
  • 5
  • 18

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i

[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll

[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll and this again sort of works, but the process is not killed when it reachesreliably: the memory limit, even though according I wrote to ps ax -o pid,command,cgroup it has the cgroup memory:mycgroup.limit_in_bytes got reset at some point and I don't know when or why.

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i

[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll

[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll but the process is not killed when it reaches the memory limit, even though according to ps ax -o pid,command,cgroup it has the cgroup memory:mycgroup.

I'm running some .NET Core processes as systemd services under Ubuntu 16.04 (soon to be 18.04). I have a systemd configuration file (/lib/systemd/system/[email protected]) that looks like this:

[Unit]
Description=My Service %i

[Service]
Type=simple
User=myservice
EnvironmentFile=/etc/environment
WorkingDirectory=/home/myservice/instances/%i
ExecStart=/opt/dotnet/dotnet My.Service.dll

[Install]
WantedBy=multi-user.target

I want to limit the total amount of RAM that all instances of this service can use. I don't want to limit the RAM for any individual instance to less than that, so settings like MemoryHigh and MemoryMax aren't helpful.

I know that systemd creates a cgroup for the service template, so I want to change the memory limit for that cgroup somehow.

On Ubuntu 18.04 I can manually edit /sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes and this basically does what I want (processes get killed when the total memory usage exceeds the limit), but there are some issues with this approach:

  • This file doesn't always exist on boot until the service is started.
  • On Ubuntu 18.04 this file gets overwritten whenever systemctl daemon-reload is called.
  • Trying to write to the file sometimes returns write error: Device or resource busy

(Under Ubuntu 16.04 the limit seems to be reset whenever my service starts, so it has no effect.)

Is there some way to get systemd itself to set this value, so I don't have to fight against it? Or some other way to limit the total memory use for a group of processes? They all run as the same user, so it would be OK to limit the RAM used by that user, for example.

I even tried manually creating a cgroup (cgcreate -t myservice:myservice -g memory:mycgroup) and then changing ExecStart in the service configuration to /usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll and this again sort of works, but not reliably: the memory limit I wrote to memory.limit_in_bytes got reset at some point and I don't know when or why.

added 387 characters in body
Source Link
EM0
  • 515
  • 5
  • 18
Loading
Source Link
EM0
  • 515
  • 5
  • 18
Loading