web-dev-qa-db-ja.com

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

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

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

# user:process  controller  destination
*:myprocessname cpuset      cpu0only

私の質問は、どうすればreverseを実行できますか?

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


私が研究したがテストしていないことに基づいて、私はbelievepartialソリューションは次のようになると考えます:

「無制限」の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の子が制限されたcpu0only cgroupに再割り当てされることのようです。

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

Cgroupsでこれをどのように達成できますか?


これがcgroups で不可能である場合(私は現在そうだと思います)、部分的なソリューションの私のアイデアは正しいですか、彼らは私が思うように機能しますか?

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

27
Wildcard

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


この質問を投稿して以来、私は上記にリンクしたガイド全体、および cgroups.txt のドキュメントと cpusets.txt の大部分を調査しました。今ではcgroupについて学習することを予想していた以上のことがわかったので、ここで自分の質問に答えます。

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

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


Cgroupは、インストールされているlibcgroupに応じてnotに依存します。ただし、これは自動的にcgroupの構成とcgroupへのプロセス割り当ての処理は非常に役立ちます。

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

したがって、libcgroupツール(/etc/cgconfig.conf/etc/cgrules.confcgexeccgcreatecgclassifyなど)を使用する前に、次のことに慣れることをお勧めしますhighly/cgroup仮想ファイルシステム自体、およびcgroups、cgroup階層(複数のサブシステムが接続された階層を含み、libcgroupがこっそりと漏洩して抽象化する)を手動で作成し、echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasksを実行してプロセスを別のcgroupに再割り当てし、_libcgroupフードの下で実行します。


私が見逃していたもう1つの基本的な概念は、/cgroup仮想ファイルシステムがシステムにマウントされている場合(より正確には、「コントローラー」とも呼ばれるcgroupサブシステムのいずれかがマウントされている場合)、everyシステム全体のプロセスis incgroup。 「一部のプロセスはcgroupにあり、一部はそうでない」というようなものはありません。

接続されたサブシステム用のシステムのリソースallを所有する、指定された階層のrootcgroupと呼ばれるものがあります。たとえば、cpusetサブシステムとblkioサブシステムが接続されているcgroup階層には、システム上のallcpusとシステム上のすべてのblkioを所有し、childcgroupsを持つリソース。ルートcgroupはシステムのリソースallを所有しているため制限できません。制限しても意味がありません。


Libcgroupについて欠落していた他のいくつかの単純なデータ:

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

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

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

手動で操作し、仮想ファイルシステム(初めて使用することをお勧めします)を使用してcgroupを設定したい場合は、そうすることができます。次に、cgsnapshotとさまざまなオプションを使用して、cgconfig.confファイルを作成し、セットアップをミラーリングできます。 。


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

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

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

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

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

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

cgexeccgclassifyの両方が--stickyフラグをサポートし、additionallycgredによるchildの再割り当てを防止します/etc/cgrules.confに基づくプロセス


それで、私が書いた質問への答え(ただし、Red Hatテクニカルアーキテクトからのアドバイスにより、私が最終的に実装した設定ではありません上記)は:

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

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

unrestrictedで必要なプロセスをcgexec -g cpuset:anycpu --sticky myprocessnameで開始します。

これらのプロセスは無制限になり、そのすべての子プロセスも同様に無制限になります。 システム上のその他すべてはCPU 0に制限されます(再起動すると、cgredはcgruleをすでに実行中のプロセスに適用しないため、 EUIDを変更します)。これは完全に推奨されるわけではありませんが、それは私が最初に要求したものであり、cgroupでcan行うことができます。

31
Wildcard