cgroupsを使用して、ホワイトリストを除くすべてのプロセスを単一のCPUに制限する方法は?


26

Red Hatのcgroupsのガイドがありますが、これは一種の役に立つかもしれません(ただし、この質問には答えていません)

特定のプロセスを開始するコマンドの実行中に、特定のプロセスを特定のCPUに制限する方法を知っています。

まず、以下を*に入れます/etc/cgconfig.conf

mount {
  cpuset =  /cgroup/cpuset;
  cpu =     /cgroup/cpu;
  cpuacct = /cgroup/cpuacct;
  memory =  /cgroup/memory;
  devices = /cgroup/devices;
  freezer = /cgroup/freezer;
  net_cls = /cgroup/net_cls;
  blkio =   /cgroup/blkio;
}

group cpu0only {
  cpuset {
    cpuset.cpus = 0;
    cpuset.mems = 0;
  }
}

そして、プロセスを開始し、次を使用してそのcgroupにそれを明確に割り当てます:

cgexec -g cpuset:cpu0only myprocessname

特定のプロセス名のすべてのインスタンスを自動的に制限するには、(これは正しいと思います)に以下を入力し/etc/cgrules.confます。

# user:process  controller  destination
*:myprocessname cpuset      cpu0only

私の質問は、どのようにを行うことができますか?

つまり、ホワイトリストに登録された特定のプロセスとその子除くすべてのプロセスを制限されたcgroup に割り当てるにどうすればよいですか?


私が研究したが、テストしていないことに基づいて、部分的な解決策は次のようになると信じています:

「無制限の」cgroupを追加します。

group anycpu {
  cpuset {
    cpuset.cpus = 0-31;
    cpuset.mems = 0;  # Not sure about this param but it seems to be required
  }
}

プロセスを無制限のグループに明示的に割り当て、それ以外のすべてを制限されたグループに割り当てます。

# user:process  controller  destination
*:myprocessname cpuset      anycpu
*               cpuset      cpu0only

ただし、これに関する警告は(テストからではなくドキュメントを読むことから、塩の粒から)の子はmyprocessname制限されたcpu0onlycgroupに再割り当てされるようです。

可能な代替アプローチは、実行するユーザーを作成し、そのユーザーのmyprocessnameすべてプロセスを無制限にし、他のすべてを制限することです。ただし、実際の使用例では、プロセスはルートで実行する必要があり、制限する必要があるルートで実行する必要がある他のプロセスがあります。

cgroupsでこれを達成するにはどうすればよいですか?


これがcgroupで不可能な場合(今ではそうだと思う)、部分的な解決策の私の考えは正しいですか?

*免責事項:これはおそらく最小限のコード例ではありません。すべての部分を理解ていないので、どれが不要かはわかりません。

回答:


30

更新:以下の回答はRHEL 6に適用されることに注意してください。RHEL7では、ほとんどのcgroupはsystemdによって管理されており、libcgroupは非推奨です。


この質問を投稿しているので、私は上記にリンクされていることを全体のガイドだけでなく、大多数の研究しているcgroups.txtドキュメントとcpusets.txtを。私は今までcgroupについて学ぶと思っていた以上のことを知っているので、ここで自分の質問に答えます。

あなたが取ることができる複数のアプローチがあります。Red Hat(テクニカルアーキテクト)での当社の連絡先は、より宣言的なアプローチに優先して、すべてのプロセスの全面的な制限に対して推奨しました。具体的に制限したいプロセスのみを制限します。これに関する理由は、この件に関する彼の声明によると、システムコールは、制限されるとシステムの速度を低下させる可能性があるユーザースペースコード(LVMプロセスなど)に依存する可能性があるためです。そのため、具体的に名前が付けられたいくつかのプロセスを制限し、他のすべてをそのままにしてしまいました。

さらに、質問を投稿したときに欠落していたcgroupの基本データについても言及したいと思います。


Cgroupsはインストールされていることに依存しませlibcgroup ただし、これはcgroupの設定とcgroupへのプロセスの割り当てを自動的に処理するためのツールセットであり、非常に役立ちます。

libcgroupパッケージは、cgroup の実際のカーネルレベルの実装とは若干異なるcgroupの使用に関する抽象化と仮定の独自のセットに基づいて構築されているため、libcgroupツールも誤解を招く可能性があることがわかりました。(例を挙げることはできますが、少し手間がかかります。興味があればコメントしてください。)

したがって、libcgroupツールを使用する前に(例えば/etc/cgconfig.conf/etc/cgrules.confcgexeccgcreatecgclassify、など)私は非常に精通取得お勧め/cgroup仮想ファイルシステム自体、及び手動こそこそlibcgroupのcgroup、添付の複数のサブシステムを有する階層を含むのcgroup階層(、及びleakily要約作成します離れて)、実行して異なるのcgroupにプロセスを再割り当てecho $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasks、および他の一見魔法のタスクそのlibcgroupフードの下で行います。


私が行方不明になったもう一つの基本的な概念であることが確認された場合の/cgroup仮想ファイルシステムは、すべてのシステムに搭載されている(またはより正確に、別名「コントローラ」は、全てに取り付けられているのcgroupサブシステムのいずれかがあれば)、その後、すべてのあなたの全体のシステム上のプロセスがである A cgroup。 「一部のプロセスはcgroupにあり、一部はそうではない」というようなことはありません。

特定の階層にはルート cgroup と呼ばれるものがあり、接続されたサブシステムのすべてのシステムリソースを所有します。たとえば、cpusetおよびblkioサブシステムが接続されたcgroup階層には、システム上のすべてのcpusとシステム上のすべてのblkio を所有するルートcgroupがあり、それらのリソースの一部を cgroupと共有できます。ルートcgroupはシステムのすべてのリソースを所有ているため、制限することはできません。


libcgroupについて不足している他のいくつかの簡単なデータ:

を使用する場合、システム起動時に実行するように設定され/etc/cgconfig.confchkconfig --list cgconfigいることを確認する必要がありcgconfigます。

を変更する場合は、変更をロード/etc/cgconfig.confするために実行service cgconfig restartする必要があります。(そしてcgclear、テストをだますとき、サービスを停止したり実行したりする問題は非常に一般的です。例えば、使用しているcgroup階層の名前がのlsof /cgroup/cpuset場合、デバッグすることをお勧めcpusetします。)

を使用する場合は/etc/cgrules.conf、「cgroupルールエンジンデーモン」(cgrulesengd)が実行されていることを確認する必要がservice cgred startありchkconfig cgred onます。(そして、ページの下部にあるセクション2.8.1のRed Hatリソース管理ガイドで説明されているように、このサービスに関しては可能性がありそうもない競合状態に注意する必要があります。)

手動でだまし、仮想ファイルシステムを使用してcgroupsをセットアップする場合(最初の使用をお勧めします)、それを実行cgconfig.confcgsnapshotてから、さまざまなオプションを使用してセットアップをミラーリングするファイルを作成できます。


そして最後に、私が以下を書いたときに欠けていた重要な情報:

ただし、これに関する注意点は... myprocessnameの子が制限されたcpu0only cgroupに再割り当てされることです。

私は正しかったのですが、知らなかったオプションがあります。

cgexec プロセスを開始する/コマンドを実行してcgroupに割り当てるコマンドです。

cgclassify すでに実行中のプロセスをcgroupに割り当てるコマンドです。

これらの両方は、cgredcgrulesengd)に基づいて指定されたプロセスを異なるcgroupに再割り当てするのも防ぎます/etc/cgrules.conf

両方cgexecおよびcgclassifyサポート--stickyフラグ、付加的に防止cgred再割当てからに基づいてプロセスを/etc/cgrules.conf


そのため、私が書いた質問に対する答えは(上記のRed Hatテクニカルアーキテクトからのアドバイスのために、私が実装したセットアップではありませんが):

私の質問で説明されているように、cpu0onlyおよびanycpucgroupを作成します。(cgconfig起動時に実行するように設定されていることを確認してください。)

作る* cpuset cpu0only私の質問に記載されたルールを。(そしてcgred、起動時に実行するように設定されていることを確認してください。)

無制限にしたいプロセスを開始します:cgexec -g cpuset:anycpu --sticky myprocessname

これらのプロセスは制限されず、すべての子プロセスも同様に制限されません。 システム上の他のすべては CPU 0に制限されます(再起動すると、cgredEUIDを変更しない限り、すでに実行中のプロセスにcgrulesを適用しないため)。これは完全にお勧めではありませんが、それは私が最初に要求したものであり、cgroupsで実行できます。


ワオ。クール。これはどのように0票を持っていましたか?
mikeserv

@mikeserv、ありがとう。:)質問への回答:日付を確認してください。昨日この答えを書きました。
ワイルドカード

1
私はそれを観た。しかし、それは24時間前でした。おそらくその原因は長い。良いものは時々そのように見落とされることがあります。とにかく、すぐに多くの票を投じた答えが非常にまれに良いものになることはほとんどありません。ただし、これは良いものの1つです。cgroupは不思議です。
mikeserv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.