나는 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
잘 작동하지 않는 것 같거나, 어떻게 해야 하는지 너무 익숙하지 않습니다. lxc
컨테이너가 에 있을 수 있는 경우에만 가능합니다 . 그러나 cgroup 계층 구조가 에 마운트되어 있으므로 /sys/fs/cgroup/XXX/*
이는 불가능합니다 . 해결 방법은 다음과 같습니다.lxc
systemd
root
/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
현재 버전systemd
( )에 필요한 사항을 설정하는 더 좋은 방법을 찾은 사람이 있습니까>= 217
?
답변1
더 좋고 더 안전한 솔루션은 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
그 대본을 썼을 때는 정확히 무슨 일이 일어나고 있는지 몰랐지만, 읽어보니cgroup 문서몇 가지 실험은 무슨 일이 일어나고 있는지 이해하는 데 도움이 되었습니다. 이 스크립트에서 내가 하는 일은 기본적으로 cgroup
현재 세션에 대한 새 세션을 생성하는 것인데 user
, 이는 위에서 이미 말한 것입니다. 이 명령을 현재에서 실행 shell
하거나 스크립트에서 실행하고 shell
in 대신 현재에서 평가하도록 하면 subshell
( . script
이것이 .
작동하는 데 중요합니다!) 새 세션을 여는 것이 아니라 user
현재 쉘을 다음과 같이 추가합니다. 이 프로세스는 새 cgroup에서 실행됩니다. 하위 셸에서 스크립트를 실행한 다음 cgroup
계층 구조 로 드릴다운 chb
subcgroup
하고 echo $$ > tasks
각 멤버를 사용하여 현재 셸을 chb cgroup hierarchy
.
따라서 lxc
현재 셸에서 실행하면 내 컨테이너도 chb
subcgroup
현재 셸이 shell
속한 모든 의 멤버가 됩니다. 즉, 나의 지위를 container
물려받은 것입니다 . 이는 또한 현재 s의 일부가 아닌 다른 쉘에서는 작동 하지 않는 이유를 설명합니다 .cgroup
shell
chb
subcgroup
나는 아직도 통과했다 2.
. 일관된 동작을 채택하려면 systemd
업데이트나 추가 Kernel
개발을 기다려야 할 수도 있지만 systemd
, 그럼에도 불구하고 나는 수행 중인 작업을 사용자가 알 수 있도록 수동 설정을 선호합니다.
답변2
실제로 Archlinux에서는 권한이 없는 사용자에게는 작동하지 않습니다(unpriv.lxc 컨테이너를 사용할 때 권장됨). 즉, 이 사용자에게는 sudo가 없습니다 :)
대신 /etc/cgconfig.conf에서 그룹을 정의하고, cgconfig, cgrules(AUR의 libcgroup)를 활성화하고, cgrules를 추가하고, unpriv를 완료합니다. 사용자도 동일한 권리를 갖습니다.
systemd 218에서(언제인지는 모르겠지만 cgconfig 모드에서 생성할 때 설정되지 않았기 때문에 두 조건을 모두 추가해야 했던 것 같습니다):
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을 추가합니다.
그리고 lxcadmin의 컨테이너인 Lolz systemctl 활성화 lxcadmin@lolz에 대해 활성화합니다.
답변3
그래서 CentOS 7에서 LXC 비특권 컨테이너를 실행하려고 시도했을 때 동일한 문제가 발생했습니다. cgmanager
꼭 필요한 것이 아니라면 추가 서비스를 도입하는 것을 좋아하지 않기 때문에 사용하고 싶지 않습니다 . 내가 한 일은 ubuntu 패키지의 일부 패치와 cgroup 컨트롤러 목록을 확장하는 사용자 정의 패치를 사용하여 systemd를 패치하는 것이었습니다. RPM을 구축하는 데 필요한 리소스는 내 GitHub 계정에서 사용할 수 있습니다.https://github.com/CtrlC-Root/rpmdist. 또한 Shadow-utils(subuid 및 subgids용) 및 pam(loginuid용) 버전도 패치했습니다. 이러한 RPM을 설치하고 권한이 없는 컨테이너를 실행하도록 사용자를 구성한 후(subuid 및 subgid 할당, lxc-usernet에 veth 쌍 할당, .config/lxc/default.conf 생성 등), LXC 권한이 없는 컨테이너를 제대로 실행할 수 있습니다.
편집: cgmanager를 사용하고 싶지 않은 또 다른 이유는 일반 사용자가 sudo를 사용해야 하는 것을 원하지 않기 때문입니다. 일반 사용자는 로그인할 수 있어야 하며 모든 것이 즉시 작동해야 합니다.