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
残念ながら、現在systemd
はlxc
とうまく連携していません。特にroot以外のユーザー用にcgroups
を設定するとうまくいかないように見えるか、これを行う方法にあまり慣れていません。 lxc
は、必要なcgroupを/sys/fs/cgroup/XXX/*
に作成できる場合にのみ、コンテナーを非特権モードで起動します。ただし、これはlxc
では不可能です。systemd
はroot
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
コンテナを起動できますが、他のコンテナでは起動できません。
誰かがこの行動を説明できますか?
現在のバージョンのcgroups
(>= 217
)で必要なsystemd
を設定するより良い方法を誰かが見つけましたか?
より適切で安全な解決策は、cgmanager
をインストールし、systemctl start cgmanager
(systemd
ベースのディストリビューション上)で実行することです。 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で実行されるプロセスとして追加することです。スクリプトをサブシェルで実行し、cgroup
chb
のsubcgroup
階層に降り、echo $$ > tasks
を使用して現在のchb cgroup hierarchy
のすべてのメンバーにシェルします。
したがって、その現在のシェルでlxc
を実行すると、私のコンテナも現在のchb
がメンバーであるすべてのsubcgroup
Shell
sのメンバーになります。つまり、私のcontainer
は、私のcgroup
のShell
ステータスを継承します。これは、現在のchb
subcgroup
sに含まれていない他のシェルでも機能しない理由も説明しています。
私はまだ2.
を通過します。 systemd
の更新またはKernel
の開発がsystemd
に一貫した動作を採用するまで待つ必要がありますが、とにかく手動で設定することをお勧めします。あなたが何をしているのか理解してください。
したがって、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を使用する必要がまったくなかったためです。通常のユーザーはログインできる必要があり、すべてが箱から出してすぐに「うまくいく」はずです。
実際のところ、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のコンテナーに対してそれを有効にします。