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루트가 아닌 사용자를 설정하면 제대로 작동하지 않는 것 같거나이 작업을 수행하는 방법이 너무 익숙하지 않습니다. 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

더 안전하고 안전한 솔루션은 ( 기반 배포판에서) 설치 cgmanager하고 실행하는 것입니다 . 사용자는 다음과 같은 권한을 가진 모든 컨트롤러에서 권한이없는 사용자를 위해 호스트에 대한 권한 이 있거나 호스트에 대한 권한을 가질 수 있습니다 .systemctl start cgmanagersystemdrootsudocgroups

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(통해 . script(가) .작업이 중요하다!) 난 그냥에 대한 새로운 세션을 열 수없는 것입니다 user그러나 현재 쉘을이 새로운 cgroup에서 실행되는 프로세스로 추가하십시오. 나는 서브 쉘에서 스크립트를 실행하여 동일한 효과를 달성하고로 내려 다음 수 cgroup에서 계층 구조 chb subcgroup및 사용echo $$ > tasks의 모든 멤버에 현재 쉘을 추가합니다 chb cgroup hierarchy.

내가 실행할 때 따라서, lxc전류 쉘 내 용기는 또한 모든 회원이 될 것이다 chb subcgroup전류가 있음을의 shell의 구성원입니다. 즉 , 내 상태는 내 상태를 container상속받습니다 . 이것은 또한 현재 의 일부가 아닌 다른 쉘에서 작동하지 않는 이유를 설명합니다 .cgroupshellchb subcgroup

나는 아직도 통과 2.합니다. 일관된 동작 을 채택 하기 위해 systemd업데이트 또는 추가 Kernel개발 을 기다려야 할 수도 systemd있지만 어쨌든 수동 설정은 사용자가 수행중인 작업을 이해하도록 강제하기 때문에 선호합니다.


cgroups 디렉토리를 다른 곳에 마운트 할 수 있습니까 (정직한 질문) ? 작년에 cgroups 관리자 가 사용자 공간에서 cgroups 처리에 대한 이름 및 기타 유사한 명명되지 않은 응용 프로그램 권한으로 systemd를 제공하기로 결정했을 때 Linux cgroup에 대해 많은 논쟁이 있었고 작년에 체계화되었습니다 . 어떻게 모든 것이 나왔는지 확실하지 않지만 사용자가 1 년 전에이 작업을 수행 할 수 있는지 여부는 공중에 꽤 있다는 것을 알고 있습니다.
mikeserv

아마 그렇게 할 수는 있지만 systemd가 cgroup 루트 디렉토리를 처음에 마운트하지 못하게해야합니다. 시스템에 로그인 할 때마다 systemd는 / sys / fs / cgroup 아래에 루트 cgroup 루트 계층 구조를 마운트하고 루트 cgroup의 시스템 부분에만 사용자 cgroup을 추가합니다 (위에서 볼 수 있습니다). 시스템 기반 배포판과 시스템 기반 배포판이 전환되기 전의 차이점은 예를 들어 Ubuntu cgroup 관리가 init 데몬의 손에 있지 않다는 것입니다.
lord.garbage

대신 cgmanager와 같은 프로그램으로 처리됩니다. 또는 위에 게시 한 kernel.org 링크에서 제안한대로 직접 할 수도 있습니다. 현재 체계화 된 cgroup 관리에 대해 지금보다 더 깊이 이해하기에 충분한 지식이 없습니다. 그러나 이것이 곧 바뀔 것입니다.
lord.garbage

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

0

실제로 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/

네임 스페이스가 커널에서 컴파일되었다고 가정합니다.

이것은 템플릿이며 cpus는 코어 수에 따라 달라질 수 있으며 mem은 실제 값 등으로 설정할 수 있습니다.

편집 2 : 마지막으로 systemd에서 권한이없는 사용자와 자동 시작을 사용하려면 다음을 수행하십시오.

cp /usr/lib/systemd/system/lxc{,admin}\@.service를 추가 한 다음 User = lxcadmin을 추가하십시오.

lolz systemctl enable lxcadmin @ lolz라는 lxcadmin의 컨테이너에 대해 활성화하십시오.


@Anthon에게 감사합니다.이 웹 사이트에서 코드 형식을 절대 얻을 수는 없습니다. x
Malina Salina

감사합니다. 늦은 답변 죄송합니다. 첫 번째 요점은 "실제로 archlinux에서는 권한이없는 사용자 (unpriv. lxc 컨테이너를 사용할 때 권장 됨)에서는 작동하지 않습니다. 즉, 사용자가 sudo를 가지고 있지 않습니다")는 root관리자 만 필요로하기 때문에 서 있지 않습니다. chown모든 cgroup컨트롤러에 당신을 만듭니다 . 이것은 완벽하고 안전합니다. 권리 movepid없이 root, 그리고 사악 하지 않은 일을 할 수 있습니다 . 사용자는 sudo권리 가 필요하지 않습니다 . (Btw, libcgroup더 이상 사용되지 않습니다. RHEL 및 다른 사람들은 더 이상 사용하지 않습니다.)
lord.garbage

@ 브라우 너. 권한이없는 사용자의 컨테이너를 부팅 할 때 어떻게 자동 시작합니까? 실제로 나열된 솔루션은 sudo 사용자에게만 유효하고 암시 적입니다. 광산은하지 않았다. 문제를 해결하는 방법을 물었습니다. 어쨌든 방금 업데이트가 있었고 cgconfig 설정보다 user.slices가 자동으로 추가되어 cgconfig가 시작되지 않습니다. 이것에는 사용자 권한이 없습니다 (회귀 버그 일 수 있습니다). 나는 그것이 최선의 해결책 이라고 말하지 않았다 . 귀하의 문의에 대한 해결책 이었습니다 . :)하지만 컨테이너가 부팅 할 때 시작하지 않습니다, grrr.
말 리나 살리나

내가 systemctl enable lxcadmin @ container를 나열한 이유는 root가 부팅시 unpriv 컨테이너를 실행하도록 결정할 수 있기 때문입니다. 사용자가 --user (land)에서 사용하는 경우, 로그인 할 때만 부팅되며 서버에는 그다지 유용하지 않습니다. 그리고 당신의 의견에 대한 메모. 사용자를 모든 컨트롤러에 배치하면 사용자가 pid를 호스트 공간으로 옮길 수 있습니다. 보안 상 위험합니다.
말 리나 살리나

겉으로는 당신이 우분투 패키지 systemd 경우에도,이에서 당신의 처음에 내가 생각 나열 방법,하지만 표정으로 무엇을하고 있는지이다 음, bugs.launchpad.net/ubuntu/+source/systemd/+bug/1413927 그러나 뭔가에 업데이트 된 지난 일 논리를 변경 .. 나는 그것을 추적하려고합니다.
말 리나 살리나

0

따라서 CentOS 7에서 LXC 권한이없는 컨테이너를 가져 오려고 할 때도 동일한 문제가 발생했습니다 cgmanager. 절대적으로 필요하지 않은 경우 추가 서비스를 도입하는 것을 좋아하지 않기 때문에 사용하고 싶지 않았습니다. 내가 대신 한 것은 우분투 패키지의 일부 패치와 하나의 사용자 정의 패치를 사용하여 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를 사용하고 싶지 않은 또 다른 이유는 일반 사용자가 sudo를 전혀 사용하지 않기를 원했기 때문입니다. 일반 사용자는 로그인 할 수 있어야하며 모든 것이 즉시 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.