systemdでユーザーcgroupを作成する方法


14

で非特権lxcコンテナを使用していArch Linuxます。基本的なシステム情報は次のとおりです。

[chb@conventiont ~]$ uname -a
Linux conventiont 3.17.4-Chb #1 SMP PREEMPT Fri Nov 28 12:39:54 UTC 2014 x86_64 GNU/Linux

これは、カスタム/コンパイルされたカーネルuser namespace enabledです:

[chb@conventiont ~]$ lxc-checkconfig 
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

[chb@conventiont ~]$ systemctl --version
systemd 217
+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD +IDN 

残念ながら、現在はsystemdうまく動作しませんlxc。特にcgroups、root以外のユーザー向けのセットアップはうまく機能していないようです。または、これを行う方法があまりにも不慣れです。lxcで必要なcgroupを作成できる場合にのみ、コンテナを非特権モードで起動し/sys/fs/cgroup/XXX/*ます。ただし、これはcgroup階層をにマウントするlxcため不可能です。回避策は次のようにすることです。systemdroot/sys/fs/cgroup/*

for d in /sys/fs/cgroup/*; do
        f=$(basename $d)
        echo "looking at $f"
        if [ "$f" = "cpuset" ]; then
                echo 1 | sudo tee -a $d/cgroup.clone_children;
        elif [ "$f" = "memory" ]; then
                echo 1 | sudo tee -a $d/memory.use_hierarchy;
        fi
        sudo mkdir -p $d/$USER
        sudo chown -R $USER $d/$USER
        echo $$ > $d/$USER/tasks
done

このコードは、非特権ユーザーの階層に対応するcgroupディレクトリを作成しcgroupます。しかし、私には理解できないことが起こります。前述を実行する前に、これが表示されます。

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

上記のコードを実行した後、シェルで表示されます:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/chb
7:net_cls:/chb
6:freezer:/chb
5:devices:/chb
4:memory:/chb
3:cpu,cpuacct:/chb
2:cpuset:/chb
1:name=systemd:/chb

しかし、他のシェルにはまだ表示されます:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

したがって、lxc上記のコードを実行したシェルで非特権コンテナを起動できますが、他のコンテナでは起動できません。

  1. 誰かがこの行動を説明できますか?

  2. 誰かがcgroups現在のバージョンsystemd>= 217)で必要な設定を行うより良い方法を見つけましたか?

回答:


13

より優れた安全なソリューションはcgmanagersystemctl start cgmanagersystemdベースのディストリビューションで)インストールして実行することです。それから、あなたにrootユーザーを持たせることができます。またはsudo、ホストで権限を持っている場合はcgroups、すべてのコントローラーで非特権ユーザー用に以下を作成します。

sudo cgm create all $USER
sudo cgm chown all $USER $(id -u $USER) $(id -g $USER)

特権のないユーザー用に作成されたら、アクセスできるプロセスをcgroupすべてのコントローラーに移動できます:

cgm movepid all $USER $PPID

私が投稿したシェルスクリプトより安全、高速、信頼性が高い。

手動ソリューション:

回答するには1。

for d in /sys/fs/cgroup/*; do
        f=$(basename $d)
        echo "looking at $f"
        if [ "$f" = "cpuset" ]; then
                echo 1 | sudo tee -a $d/cgroup.clone_children;
        elif [ "$f" = "memory" ]; then
                echo 1 | sudo tee -a $d/memory.use_hierarchy;
        fi
        sudo mkdir -p $d/$USER
        sudo chown -R $USER $d/$USER
        echo $$ > $d/$USER/tasks
done

私はそのスクリプトを書いたときに何が起こっていたかについては無知でしたが、これを読んで少し実験することで、何が起こっているのかを理解するのに役立ちました。このスクリプトで基本的に行っていることは、既に説明したようにcgroup、現在のセッション用に新しいセッションを作成するuserことです。私は、現在ではこれらのコマンドを実行すると、shellまたはスクリプトでそれらを実行し、それが現在で評価されますので、それを作るshellではなくsubshell(経由仕事に、このために重要です!)私はちょうどのための新しいセッションを開いていないということですただし、この新しいcgroupで実行されるプロセスとして現在のシェルを追加します。サブシェルでスクリプトを実行することで同じ効果を達成し、次に階層内に降りて使用します. script.usercgroupchb subcgroupecho $$ > tasksのすべてのメンバーに現在のシェルを追加しchb cgroup hierarchyます。

したがって、lxcその現在のシェルで実行すると、私のコンテナーはchb subcgroup、現在のメンバーであるすべてのsのメンバーにもなりshellます。つまり、myはmy containercgroupステータスを継承しますshell。これは、現在chb subcgroupのsの一部ではない他のシェルで動作しない理由も説明します。

私はまだ通り2.ます。おそらく、systemd更新またはさらなるKernel開発のいずれかsystemdが一貫した動作を採用するのを待つ必要がありますが、とにかく手動のセットアップを好むので、何をしているのか理解する必要があります。


cgroups dirを別の場所にマウントすることはできませんか(正直な質問)?Linuxのcgroupsとsystemdをめぐる多くの論争があり、昨年cgroupsメンテナーがsystemd にユーザースペースでのcgroups処理に対する名前と他の同様の無名アプリ権限を与えることを決定したようです。すべてがどうなったかはわかりませんが、ユーザーが1年前にこれを行うことができるかどうかはかなり気にかかっていました。
mikeserv 14

私はおそらくそれを行うことができますが、最初にsystemdがcgroupルートディレクトリをマウントしないようにする必要があります。マシンにログインするたびに、systemdは/ sys / fs / cgroupの下にルートcgroupルート階層をマウントし、ルートcgroupのsystemd部分のみにユーザーcgroupを追加します(上記を参照)。systemdベースのディストリビューションと切り替え前のsystemdベースのディストリビューションの違いは、たとえばUbuntuのcgroup管理がinitデーモンの手にないことです。
lord.garbage 14

代わりに、cgmanagerなどのプログラムによって処理されます。または、上記のkernel.orgへのリンクで提案されているように、手動で行うこともできます。現在、systemd cgroupの管理を十分に理解していないので、現在よりも深くそれをいじることができません。しかし、うまくいけば、これはすぐに変更されます。
lord.garbage 14

1
確かに、私がずっと前に出した答えへのコメントであなたが言ったことを覚えています。私は...お問い合わせう
lord.garbage

1
基本的なトリックは次のとおり sudo systemctl start cgmanager && sudo cgm create all $USER && sudo cgm chown all $USER $(id -u) $(id -g) && sudo cgm movepid all $USER $PPIDです。の新しいcgroupに追加するには、現在のシェルで最後のコマンドを実行する必要があります$USER
lord.garbage 14

0

実際、archlinuxでは、これは、たとえば特権のないユーザーでは機能しません(unpriv。lxcコンテナーを使用する場合に推奨)。すなわち、そのユーザーはsudoを持っていません:)

代わりに、/ etc / cgconfig.confでグループを定義し、cgconfig、cgrules(AURのlibcgroup)をアクティブにし、cgrulesも追加してください。ユーザーも同じ権利を持ちます。

systemd 218(いつ、私は知りませんが、cgconfigの方法で作成されたときに設定されていないため、さらに2つの条件を追加する必要があるようです):

cat /etc/cgconfig.conf

group lxcadmin {
perm {
    task {
        uid = lxcadmin;
        gid = lxcadmin;
    }
    admin {
        uid = lxcadmin;
        gid = lxcadmin;
    }
}
cpu { }
memory { memory.use_hierarchy = 1; }  
blkio { }
cpuacct { }
cpuset { 
    cgroup.clone_children = 1;
    cpuset.mems = 0;
    cpuset.cpus = 0-3; 
}
devices { }
freezer { }
hugetlb { }
net_cls { }
}

cat /etc/cgrules.conf
lxcadmin        *       lxcadmin/

名前空間がカーネルでコンパイルされていると仮定します。

これはテンプレートであり、cpusは使用しているコアの数に応じて、memは実際の値などに設定できます。

編集2:最後に、systemdでは、そのような非特権ユーザーで自動起動を使用したい場合は、次のことができます:

cp /usr/lib/systemd/system/lxc{,admin}\@.service、次にUser = lxcadminを追加します

lolz systemctl enable lxcadmin @ lolzと呼ばれるlxcadminのコンテナに対して有効にします。


あなた@Anthonをありがとう、私が今までのコードを取得することができませんでし、Xこれらのウェブサイトに右のフォーマット
マリナサリナ

ありがとうございました。返事が遅れて申し訳ありません。あなたの最初のポイント、「実はarchlinuxでは、これは例えば、A非特権ユーザー(unprivを使用している場合、推奨。LXCコンテナ)で動作しません。ユーザーはsudoを持っていない、すなわちこと:)」あなただけの必要があるとして、我慢しないrootと、管理者にchownあなたとすべてのcgroupコントローラーを作成します。これは完全に安全です。権利movepidなしで行うことができるrootため、非特権。ユーザーにはsudo権限は必要ありません。(ところで、libcgroupもう使用することは想定されていません
。RHEL

@ブラウナー。起動時にどのように自動起動しますか?実際にリストされているソリューションは、sudoユーザーだけで機能(および暗示)されています。私はしませんでした。あなたはそれを修正する方法を尋ねました。とにかく、更新が行われたばかりで、cgconfig設定の前にuser.slicesが自動的に追加されるため、cgconfigの起動に失敗します。これらにはユーザー権限がありません(おそらく回帰バグで、現在調査中です)。私はそれが最善の解決策だとは言いませんでした。それはあなたの問い合わせに対する解決策でし。:)しかし、私のコンテナは起動時に起動しません、grrr。
マリナサリーナ

systemctl enable lxcadmin @ containerをリストした理由は、ブート時にrootがunprivコンテナーを実行することを決定できるようにするためでした。ユーザー自身が--user(land)でそれを使用する場合、ログイン時にのみ起動し、サーバーにはあまり役立ちません。そして、あなたのコメントに関するメモ。ユーザーをすべてのコントローラーにチャネリングすると、そのユーザーがpidをホストスペースに移動できるようになります。これは非常にセキュリティ上のリスクです。
マリナサリーナ

一見あなたはそれがUbuntuのパッケージ化にsystemdだ場合でも、これであなたの最初は私が推測記載された方法が、表情で何をしていたかであるERM、bugs.launchpad.net/ubuntu/+source/systemd/+bug/1413927しかし、何かが中に更新されました過去数日間、ロジックを変更しました。私はそれを追跡しようとしています。
マリナサリーナ

0

そのため、CentOS 7でLXC非特権コンテナーを動作させようとすると、同じ問題に遭遇しましたcgmanager。絶対に必要でない場合、追加のサービスを導入したくないので、使いたくありませんでした。代わりに私がやったことは、ubuntuパッケージのいくつかのパッチと1つのカスタムパッチを使用してsystemdにパッチを当て、cgroupコントローラのリストを拡張することです。https://github.com/CtrlC-Root/rpmdistで GitHubアカウントにRPMを構築するために必要なソースがあります。また、shadow-utils(subuidsおよびsubgids用)およびpam(loginuid用)のパッチバージョンもあります。これらのRPMをインストールし、非特権コンテナーを実行するようにユーザーを構成した後(subuidsとsubgidsの割り当て、lxc-usernetでのvethペアの割り当て、.config / lxc / default.confの作成など)、LXC非特権コンテナーを正常に実行できます。

編集:cgmanagerを使用したくないもう1つの理由は、通常のユーザーにsudoをまったく使用させたくないからです。通常のユーザーはログインでき、すべてが箱から出して「正常に動作」するはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.