web-dev-qa-db-ja.com

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

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

[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 

残念ながら、現在systemdlxcとうまく連携していません。特にroot以外のユーザー用にcgroupsを設定するとうまくいかないように見えるか、これを行う方法にあまり慣れていません。 lxcは、必要なcgroupを/sys/fs/cgroup/XXX/*に作成できる場合にのみ、コンテナーを非特権モードで起動します。ただし、これはlxcでは不可能です。systemdroot cgroup階層を/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>= 217)で必要なsystemdを設定するより良い方法を誰かが見つけましたか?

14
lord.garbage

より適切で安全な解決策は、cgmanagerをインストールし、systemctl 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

そのスクリプトを書いたとき、何が起こっているのか正確にはわかりませんでしたが、 this を読んで少し実験すると、何が起こっているのかを理解するのに役立ちました。このスクリプトで基本的に実行しているのは、現在のcgroupに対して新しいuserセッションを作成することです。これは、すでに前述したとおりです。これらのコマンドを現在のShellで実行するか、スクリプトで実行して、Shellではなく現在のsubshellで評価されるようにします(. script.が機能するためには重要です!)は、userの新しいセッションを開くだけでなく、現在のシェルをこの新しいcgroupで実行されるプロセスとして追加することです。スクリプトをサブシェルで実行し、cgroupchbsubcgroup階層に降り、echo $$ > tasksを使用して現在のchb cgroup hierarchyのすべてのメンバーにシェルします。

したがって、その現在のシェルでlxcを実行すると、私のコンテナも現在のchbがメンバーであるすべてのsubcgroupShellsのメンバーになります。つまり、私のcontainerは、私のcgroupShellステータスを継承します。これは、現在のchbsubcgroupsに含まれていない他のシェルでも機能しない理由も説明しています。

私はまだ2.を通過します。 systemdの更新またはKernelの開発がsystemdに一貫した動作を採用するまで待つ必要がありますが、とにかく手動で設定することをお勧めします。あなたが何をしているのか理解してください。

13
lord.garbage

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

編集:cgmanagerを使用したくなかったもう1つの理由は、通常のユーザーがSudoを使用する必要がまったくなかったためです。通常のユーザーはログインできる必要があり、すべてが箱から出してすぐに「うまくいく」はずです。

0
ctrlc-root

実際のところ、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/

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

これはテンプレートです。CPUはコアの数に応じて、memは実際の値に設定できます。

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

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

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

0
Malina Salina