Cara membuat grup pengguna dengan systemd

14

Saya menggunakan lxcwadah yang tidak terjangkau di Arch Linux. Berikut adalah informasi sistem dasar:

[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

Ini kernel yang dikustomisasi / dikompilasi dengan 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 

Sayangnya, systemdtidak bermain dengan baik lxcsaat ini. Terutama pengaturan cgroupsuntuk pengguna non-root tampaknya tidak berfungsi dengan baik atau saya tidak terlalu terbiasa bagaimana melakukan ini. lxchanya akan memulai sebuah wadah dalam mode tidak privat ketika itu dapat membuat cgroup yang diperlukan di /sys/fs/cgroup/XXX/*. Namun ini tidak mungkin lxckarena me systemd-mount roothierarki cgroup di /sys/fs/cgroup/*. Solusi tampaknya untuk melakukan hal berikut:

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

Kode ini membuat cgroupdirektori yang sesuai dalam cgrouphierarki untuk pengguna yang tidak memiliki hak. Namun, sesuatu yang saya tidak mengerti terjadi. Sebelum mengeksekusi di atas saya akan melihat ini:

[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

Setelah mengeksekusi kode yang tadi saya lihat di shell saya menjalankannya:

[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

Tetapi di shell lain saya masih melihat:

[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

Oleh karena itu, saya dapat memulai lxcwadah yang tidak terjangkau di shell saya menjalankan kode yang disebutkan di atas tetapi tidak di yang lain.

  1. Adakah yang bisa menjelaskan perilaku ini?

  2. Adakah yang menemukan cara yang lebih baik untuk menyiapkan yang diperlukan cgroupsdengan versi systemd( >= 217) saat ini?

Tuan. Sampah
sumber

Jawaban:

13

Solusi yang lebih baik dan lebih aman adalah menginstal cgmanagerdan menjalankannya dengan systemctl start cgmanager(pada systemddistro berbasis). Anda dapat memilikiroot pengguna , atau jika Anda memiliki sudohak atas host yang dibuat cgroupsuntuk pengguna Anda yang tidak berhak di semua pengontrol dengan:

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

Setelah mereka dibuat untuk pengguna Anda yang tidak mampu, ia dapat memindahkan proses yang dapat diaksesnya cgroupuntuk setiap pengontrol dengan menggunakan:

cgm movepid all $USER $PPID

Lebih aman, lebih cepat, lebih dapat diandalkan daripada skrip shell yang saya posting.

Solusi manual:

Untuk menjawab 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

Saya tidak tahu tentang apa yang sebenarnya terjadi ketika saya menulis naskah itu tetapi membaca ini dan bereksperimen sedikit membantu saya untuk memahami apa yang sedang terjadi. Apa yang pada dasarnya saya lakukan dalam skrip ini adalah membuat cgroupsesi baru untuk saat userini yang sudah saya nyatakan di atas. Ketika saya menjalankan perintah ini di saat ini shellatau menjalankannya dalam skrip dan membuatnya sehingga dievaluasi saat ini shelldan tidak dalam subshell(melalui . scriptThe .penting untuk ini berfungsi!) Adalah bahwa saya tidak hanya membuka sesi baru untuk usertetapi tambahkan shell saat ini sebagai proses yang berjalan di cgroup baru ini. Saya dapat mencapai efek yang sama dengan menjalankan skrip dalam subkulit dan kemudian turun kecgroup hierarki dichb subcgroup dan menggunakanecho $$ > tasks untuk menambahkan shell saat ini ke setiap anggota chb cgroup hierarchy .

Oleh karena itu, ketika saya menjalankan lxcshell saat ini wadah saya juga akan menjadi anggota dari semua chb subcgroupyang saat ini shelladalah anggota. Artinya saya containermewarisi cgroupstatus saya shell. Ini juga menjelaskan mengapa itu tidak bekerja di shell lain yang bukan bagian dari aruschb subcgroup s .

Saya masih lulus 2.. Kami mungkin harus menunggu baik untuk systemdpembaruan atau Kernelperkembangan lebih lanjut untuk systemdmengadopsi perilaku yang konsisten, tetapi saya lebih suka pengaturan manual karena memaksa Anda untuk memahami apa yang Anda lakukan.

Tuan. Sampah
sumber
tidak bisakah kamu memasang mount cgroups di tempat lain (pertanyaan jujur) ? ada banyak kontroversi mengenai cgroup linux dan systemd tahun lalu ketika pengelola cgroup rupanya memutuskan untuk memberikan systemd dengan nama dan otoritas aplikasi yang tidak disebutkan namanya serupa lainnya terkait penanganan cgroup di userspace. tidak yakin bagaimana semuanya berubah, tetapi saya tahu bahwa itu cukup di udara apakah pengguna dapat melakukan ini sama sekali setahun yang lalu.
mikeserv
Saya mungkin bisa melakukan itu tetapi saya harus mencegah systemd dari pemasangan direktori root cgroup di tempat pertama. Setiap kali saya masuk ke mesin saya systemd akan me-mount hierarki root cgroup root di / sys / fs / cgroup dan menambahkan cgroup pengguna hanya di bawah bagian systemd dari cgroup root (Anda dapat melihat ini di atas.). Perbedaan antara distro-distro berbasis systemd dan tidak-distro-distro berbasis systemd sebelum mereka berganti adalah bahwa misal dalam manajemen cgroup Ubuntu tidak ada di tangan daemon init.
lord.garbage
Ini sebaliknya ditangani oleh program seperti misalnya cgmanager. Atau Anda dapat melakukannya dengan tangan seperti yang disarankan dalam tautan ke kernel.org yang saya posting di atas. Saat ini saya tidak memiliki pemahaman yang cukup mendalam tentang manajemen cgroup systemd untuk bermain lebih dalam dari yang saya lakukan sekarang. Tapi semoga ini akan segera berubah.
lord.garbage
1
Benar, saya ingat Anda menyatakan itu dalam komentar atas jawaban yang saya berikan sejak lama. Saya akan menanyakan ...
lord.garbage
1
Caranya dasarnya adalah: sudo systemctl start cgmanager && sudo cgm create all $USER && sudo cgm chown all $USER $(id -u) $(id -g) && sudo cgm movepid all $USER $PPID. Perintah terakhir harus dijalankan di shell saat ini untuk menambahkannya ke cgroup baru $USER.
lord.garbage
0

Sebenarnya di archlinux, ini tidak akan berfungsi dengan misalnya pengguna yang tidak memiliki hak pribadi (disarankan saat menggunakan wadah yang tidak diprivasi. Lxc). yaitu pengguna yang tidak memiliki sudo :)

Sebagai gantinya, tentukan grup di /etc/cgconfig.conf, aktifkan cgconfig, cgrules (libcgroup di AUR), tambahkan juga cgrules, selesai .. unpriv. pengguna juga akan memiliki hak yang sama.

Dalam systemd 218 (saya tidak tahu kapan, tetapi tampaknya kita harus menambahkan dua kondisi lagi karena tidak diatur ketika dibuat dari cara 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/

Dengan asumsi namespace dikompilasi dalam kernel.

Ini adalah templat, cpus dapat sesuai dengan berapa banyak inti yang Anda miliki, mem dapat diatur ke beberapa nilai aktual, dll.

EDIT 2: Akhirnya, di systemd, jika Anda ingin menggunakan auto-start dengan pengguna yang tidak memiliki privasi, Anda dapat melakukan:

cp /usr/lib/systemd/system/lxc{,admin}\@.service, lalu tambahkan Pengguna = lxcadmin

dan mengaktifkannya untuk wadah lxcadmin yang disebut lolz systemctl aktifkan lxcadmin @ lolz.

Malina Salina
sumber
Terima kasih @Anthon, saya tidak pernah bisa mendapatkan pemformatan kode yang benar di situs-situs ini, x
Malina Salina
Terima kasih. Maaf atas jawaban yang terlambat. Poin pertama Anda, "Sebenarnya di archlinux, ini tidak akan berfungsi dengan mis. Pengguna yang tidak berhak (disarankan saat menggunakan kontainer yang tidak diprivasi. Lxc). Mis. Pengguna itu tidak memiliki sudo :)" tidak berlaku karena Anda hanya perlu rootadministrator untuk buat dan chownAnda menjadi semua cgrouppengendali. Ini sangat baik dan aman. movepiddapat dilakukan tanpa roothak dan karenanya, undriv. pengguna tidak membutuhkan sudohak apa pun . (Btw, libcgrouptidak seharusnya digunakan lagi. RHEL dan yang lainnya telah menghentikannya.)
lord.garbage
@Buner. Bagaimana Anda melakukan autostart saat boot, wadah pengguna Anda yang tidak berpengalaman? Sebenarnya solusi Anda yang tercantum hanya berfungsi (dan tersirat) sebagai pengguna sudo. Milik saya tidak. Anda bertanya bagaimana cara memperbaikinya. Lagi pula, baru saja ada pembaruan, dan cgconfig sekarang gagal untuk memulai, karena user.slices ditambahkan secara otomatis, di depan pengaturan cgconfig tampaknya. Ini tidak memiliki izin pengguna apa pun (mungkin bug regresi, sedang mencari ke dalamnya sekarang). Saya tidak mengatakan itu adalah solusi terbaik . Itu adalah / solusi untuk pertanyaan Anda. :) Tapi kontainer saya tidak mulai saat boot, grrr.
Malina Salina
Alasan saya mendaftar systemctl mengaktifkan lxcadmin @ container adalah agar root dapat memutuskan untuk menjalankan container unpriv saat boot. Jika pengguna sendiri menggunakannya di --user (land), itu hanya bisa boot ketika dia masuk, tidak terlalu berguna untuk server. Dan catatan tentang komentar Anda. mengunyah pengguna ke semua pengontrol, memungkinkan pengguna untuk mulai memindahkan pid ke ruang host, saya percaya, yang merupakan risiko keamanan yang cukup.
Malina Salina
Erm, sepertinya itu yang Anda lakukan dengan metode yang semula terdaftar, saya rasa, tetapi lihat ini, meskipun itu adalah paket ubuntu systemd paket bugs.launchpad.net/ubuntu/+source/systemd/+bug/1413927 Tapi ada sesuatu yang diperbarui di beberapa hari terakhir mengubah logika .. Saya mencoba melacaknya.
Malina Salina
0

Jadi saya mengalami masalah yang sama ketika mencoba untuk mendapatkan LXC kontainer yang tidak digunakan bekerja pada CentOS 7. Saya tidak ingin menggunakan cgmanagerkarena saya tidak suka memperkenalkan layanan tambahan jika tidak benar-benar diperlukan. Yang akhirnya saya lakukan adalah menambal systemd menggunakan beberapa tambalan dari paket ubuntu dan satu tambalan khusus untuk memperluas daftar pengontrol cgroup. Saya memiliki sumber yang diperlukan untuk membuat RPM di akun GitHub saya di https://github.com/CtrlC-Root/rpmdist . Saya juga telah menambal versi shadow-utils (untuk subuids dan subgids) dan pam (untuk loginuid). Setelah saya menginstal RPM ini dan mengonfigurasi pengguna untuk menjalankan wadah yang tidak diprivatisasi (tetapkan subuids & subgids, alokasikan pasangan veth di lxc-usernet, buat .config / lxc / default.conf, dll.) Saya dapat menjalankan kontainer tidak berprivasi LXC dengan baik.

EDIT: Alasan lain saya tidak ingin menggunakan cgmanager adalah karena saya tidak ingin pengguna reguler saya harus menggunakan sudo sama sekali. Pengguna biasa harus bisa masuk dan semuanya harus "hanya berfungsi" di luar kotak.

ctrlc-root
sumber