Ubuntu 16.04(まもなく18.04になる)でsystemdサービスとしていくつかの.NETCoreプロセスを実行しています。次のようなsystemd構成ファイル(/lib/systemd/system/[email protected]
)があります。
[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
totalこのサービスのインスタンスが使用できるRAM that allインスタンスの量を制限したい。=を制限したくないRAM個々のインスタンスの場合はそれ未満になるため、MemoryHigh
やMemoryMax
などの設定は役に立ちません。
Systemdがサービステンプレートのcgroupを作成することを知っているので、そのcgroupのメモリ制限を何らかの方法で変更したいと思います。
Ubuntu 18.04では、/sys/fs/cgroup/memory/system.slice/system-myservice.slice/memory.limit_in_bytes
を手動で編集できます。これは基本的に私が望むことを行います(合計メモリ使用量が制限を超えるとプロセスが強制終了されます)が、このアプローチにはいくつかの問題があります。
systemctl daemon-reload
が呼び出されるたびにこのファイルが上書きされます。write error: Device or resource busy
が返されることがあります。(Ubuntu 16.04では、サービスが開始されるたびに制限がリセットされるように見えるため、効果はありません。)
Systemd自体にこの値を設定させる方法があるので、それと戦う必要はありませんか?または、プロセスのグループの合計メモリ使用量を制限する他の方法はありますか?それらはすべて同じユーザーとして実行されるため、たとえば、そのユーザーが使用するRAMを制限しても問題ありません。
手動でcgroup(cgcreate -t myservice:myservice -g memory:mycgroup
)を作成してから、サービス構成のExecStart
を/usr/bin/cgexec -g memory:mycgroup /opt/dotnet/dotnet My.Service.dll
に変更してみましたが、これもまた一種の作業ですが、確実ではありません。 memory.limit_in_bytes
がどこかでリセットされましたが、いつ、なぜかわかりません.
私はついにこれを機能させました!秘訣は、次のように、独自のスライスを作成してサービスファイルに設定することでした。
[Service]
# Everything else as in the original question
Slice=my_service_limit.slice
そして、次のようなスライスユニットファイル/lib/systemd/system/my_service_limit.slice
を作成します。
[Unit]
Description=Slice that limits memory for all my services
[Slice]
# MemoryHigh works only in "unified" cgroups mode, NOT in "hybrid" mode
MemoryHigh=500M
# MemoryMax works in "hybrid" cgroups mode, too
MemoryMax=600M
注:-
は階層区切り文字であるため、スライスの名前には注意してください。 https:/ /systemd.io/CGROUP_DELEGATION -これを構成しようとする人にとって非常に役立つページ。 systemctl status myservice
の出力を見ると、サービスが実際に構成されたスライスを使用しているかどうかを確認できます。
CGroup: /my_service_limit.slice/[email protected]
MemoryMaxが機能するためにsystemd.unified_cgroup_hierarchy=1
(松本竜太郎の答えによる)を設定する必要はありませんでしたが、MemoryHighに必要でした-「ハイブリッド」モード(Ubuntu 18.04のデフォルト)でも、暗黙的に無視されます。
また、これらは物理的なRAM使用済み-使用されるスワップスペースを含まない含まない)にのみ適用されることにも注意してください(別のMemorySwapMax設定があります。しかし、MemorySwapHighはないようです。)
nified and Legacy Control Group Hierarchies で説明されているように、「unifiedcgrouphierarchy」を使用する必要があるかもしれません。
この機能を有効にするには、systemd.unified_cgroup_hierarchy = 1をGRUB_CMDLINE_LINUX_DEFAULT
の/etc/default/grub
に追加し、update-grub
を実行して、Linuxを再起動します。
systemd.unified_cgroup_hierarchy
は systemd unified cgroup hierarchy
で説明されています。
次に、systemdユニットファイルの[Service]
セクションに次の行を追加し、systemctl daemon-reload
を実行します。
Delegate=memory
MemoryHigh=8G (if you choose 8 gigabytes as the limit)
「MemoryHigh」の説明は systemd.resource-control
にあります。