Cách tạo nhóm người dùng với systemd


14

Tôi sử dụng lxccontainer không có đặc quyền trong Arch Linux. Dưới đây là các thông tin hệ thống cơ bản:

[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

Đó là một kernel tùy chỉnh / biên dịch với 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 

Thật không may, systemdhiện tại không chơi tốt lxc. Đặc biệt là thiết lập cgroupscho một người dùng không root có vẻ không hoạt động tốt hoặc tôi quá lạ lẫm làm thế nào để làm điều này. lxcsẽ chỉ bắt đầu một container trong chế độ không có đặc quyền khi nó có thể tạo các nhóm cần thiết trong /sys/fs/cgroup/XXX/*. Tuy nhiên điều này là không thể lxcsystemdgắn kết roothệ thống phân cấp cgroup /sys/fs/cgroup/*. Một cách giải quyết có vẻ là để làm như sau:

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

Mã này tạo các thư mục tương ứng cgrouptrong cgrouphệ thống phân cấp cho người dùng không có đặc quyền. Tuy nhiên, điều mà tôi không hiểu xảy ra. Trước khi thực hiện những điều đã nói ở trên, tôi sẽ thấy điều này:

[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

Sau khi thực thi mã đã nói ở trên, tôi thấy trong trình bao, tôi chạy nó vào:

[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

Nhưng trong bất kỳ vỏ nào khác tôi vẫn thấy:

[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

Do đó, tôi có thể bắt đầu vùng lxcchứa không có đặc quyền của mình trong trình bao Tôi đã thực thi mã được đề cập ở trên nhưng không phải trong bất kỳ mã nào khác.

  1. Ai đó có thể giải thích hành vi này?

  2. Có ai đó tìm thấy một cách tốt hơn để thiết lập yêu cầu cgroupsvới phiên bản hiện tại của systemd( >= 217) không?

Câu trả lời:


13

Một giải pháp tốt hơn và an toàn hơn là cài đặt cgmanagervà chạy nó với systemctl start cgmanager(trên một bản phân systemdphối dựa trên cơ sở). Bạn có thể có rootngười dùng của mình hoặc nếu bạn có sudoquyền trên máy chủ tạo cgroupscho người dùng không có đặc quyền của bạn trong tất cả các bộ điều khiển với:

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

Khi chúng đã được tạo cho người dùng không có đặc quyền của bạn, cô ấy / anh ấy có thể di chuyển các quy trình mà anh ấy có quyền truy cập vào cgroupcho mọi bộ điều khiển bằng cách sử dụng:

cgm movepid all $USER $PPID

An toàn hơn, nhanh hơn, đáng tin cậy hơn so với kịch bản shell tôi đã đăng.

Giải pháp thủ công:

Để trả lời 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

Tôi đã không biết gì về những gì đang diễn ra chính xác khi tôi viết kịch bản đó nhưng đọc và thử nghiệm một chút đã giúp tôi hiểu những gì đang xảy ra. Những gì tôi về cơ bản đang làm trong kịch bản này là tạo ra một cgroupphiên mới cho hiện tại user, đó là những gì tôi đã nêu ở trên. Khi tôi chạy các lệnh này trong hiện tại shellhoặc chạy chúng trong một tập lệnh và làm cho nó để nó được đánh giá trong hiện tại shellvà không phải trong một subshell(thông qua . scriptĐiều .quan trọng là nó hoạt động!) Là tôi không chỉ mở một phiên mới cho usernhưng thêm shell hiện tại như là một quá trình chạy trong cgroup mới này. Tôi có thể đạt được hiệu quả tương tự bằng cách chạy tập lệnh trong một lớp con và sau đó đi xuống cgrouphệ thống phân cấp trong chb subcgroupvà sử dụngecho $$ > tasksđể thêm shell hiện tại cho mọi thành viên của chb cgroup hierarchy.

Do đó, khi tôi chạy lxctrong lớp vỏ hiện tại, container của tôi cũng sẽ trở thành thành viên của tất cả các chb subcgroups mà hiện tại shelllà thành viên. Đó là để nói rằng tôi containerthừa hưởng cgrouptình trạng của tôi shell. Điều này cũng giải thích tại sao nó không hoạt động trong bất kỳ shell nào khác không phải là một phần của chb subcgroups hiện tại .

Tôi vẫn vượt qua tại 2.. Có lẽ chúng ta sẽ cần chờ systemdcập nhật hoặc Kernelphát triển thêm để systemdáp dụng một hành vi nhất quán nhưng tôi vẫn thích thiết lập thủ công hơn vì nó buộc bạn phải hiểu những gì bạn đang làm.


bạn có thể không chỉ gắn kết các nhóm cgroups ở một nơi khác (câu hỏi trung thực) ? đã có rất nhiều tranh cãi về các nhóm linux và systemd năm ngoái khi người bảo trì cgroups rõ ràng đã quyết định trao cho systemd theo tên và các ứng dụng không tên khác tương tự đối với việc xử lý các nhóm trong không gian người dùng. không chắc chắn làm thế nào tất cả hóa ra, nhưng tôi biết rằng nó thật tuyệt vời cho dù người dùng có thể làm điều này một năm trước hay không.
mikeerv

Tôi có thể làm điều đó nhưng tôi sẽ phải ngăn systemd gắn thư mục gốc cgroup ở vị trí đầu tiên. Bất cứ khi nào tôi đăng nhập vào máy systemd của tôi sẽ gắn kết phân cấp gốc của cgroup gốc trong / sys / fs / cgroup và chỉ thêm một nhóm người dùng dưới phần systemd của cgroup gốc (Bạn có thể thấy điều này ở trên.). Sự khác biệt giữa các phân phối dựa trên systemd và các distro không dựa trên systemd trước khi chúng chuyển đổi là ví dụ như trong quản lý nhóm Ubuntu không nằm trong tay của daemon init.
lord.garbage

Thay vào đó, nó được xử lý bởi một chương trình như cgmanager. Hoặc bạn có thể làm điều đó bằng tay như được đề xuất trong liên kết đến kernel.org tôi đã đăng ở trên. Hiện tại tôi không có đủ hiểu biết sâu sắc về quản lý nhóm hệ thống để hiểu sâu hơn về vấn đề này. Nhưng hy vọng điều này sẽ sớm thay đổi.
lord.garbage

1
Đúng, tôi nhớ bạn nói rằng trong một bình luận cho một câu trả lời tôi đã đưa ra từ lâu. Tôi sẽ hỏi ...
lord.garbage

1
Thủ thuật cơ bản là : sudo systemctl start cgmanager && sudo cgm create all $USER && sudo cgm chown all $USER $(id -u) $(id -g) && sudo cgm movepid all $USER $PPID. Lệnh cuối cùng cần được chạy trong shell hiện tại để thêm nó vào cgroup mới cho $USER.
lord.garbage

0

Trên thực tế trong archlinux, điều này sẽ không hoạt động với người dùng không có quyền (được khuyến nghị khi sử dụng các thùng chứa lxc không được cấp phép). tức là người dùng không có sudo :)

Thay vào đó, hãy xác định nhóm trong /etc/cgconfig.conf, kích hoạt cgconfig, cgrules (libcgroup trong AUR), thêm cgrules, thực hiện .. unpriv. người dùng cũng sẽ có quyền tương tự.

Trong systemd 218 (Tôi không biết khi nào, nhưng dường như người ta phải thêm hai điều kiện nữa vì chúng không được đặt khi được tạo từ cách 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/

Giả sử không gian tên được biên dịch trong kernel.

Đây là một mẫu, cpus có thể theo số lượng lõi bạn có, mem có thể được đặt thành một số giá trị thực tế, v.v.

EDIT 2: Cuối cùng, trong systemd, nếu bạn muốn sử dụng tự động bắt đầu với một người dùng không có đặc quyền như vậy, bạn có thể làm:

cp /usr/lib/systemd/system/lxc đũa,admin Bolog\@.service, sau đó thêm Người dùng = lxcadmin

và kích hoạt nó cho container của lxcadmin được gọi là lolz systemctl kích hoạt lxcadmin @ lolz.


Cảm ơn bạn @Anthon, tôi không bao giờ có thể nhận được định dạng mã ngay trong các trang web này, x
Malina Salina

Cảm ơn bạn. Xin lỗi vì hồi âm muộn. Điểm đầu tiên của bạn, "Trên thực tế trong archlinux, điều này sẽ không hoạt động với người dùng không có đặc quyền (được khuyến nghị khi sử dụng các thùng chứa lxc không được cấp phép). Tức là người dùng đó không có sudo :)" không phải vì bạn chỉ cần rootquản trị viên của mình tạo và chownbạn vào tất cả các cgroupbộ điều khiển. Điều này là hoàn toàn tốt và an toàn. movepidcó thể được thực hiện mà không có rootquyền và do đó, không được phép. người dùng không cần bất kỳ sudoquyền. (Btw, libcgroupkhông được sử dụng nữa. RHEL và những người khác đã không dùng nó nữa.)
lord.garbage

@Brauner. Làm thế nào để bạn tự khởi động khi khởi động, các thùng chứa người dùng không có đặc quyền của bạn sau đó? Trên thực tế, các giải pháp của bạn được liệt kê chỉ hoạt động (và ngụ ý) một người dùng sudo. Của tôi thì không. Bạn hỏi cách khắc phục. Dù sao, vừa có một bản cập nhật và cgconfig bây giờ không khởi động được, vì user.slices được thêm tự động, trước các cài đặt cgconfig có vẻ như. Đây là thiếu bất kỳ quyền người dùng (có thể là một lỗi hồi quy, hiện đang xem xét nó). Tôi không nói đó là giải pháp tốt nhất . Đó là / một giải pháp cho yêu cầu của bạn. :) Nhưng container của tôi không bắt đầu khởi động bây giờ, grrr.
Malina Salina

Lý do tôi liệt kê systemctl cho phép lxcadmin @ container là root có thể quyết định chạy một container không tải khi khởi động. Nếu người dùng tự sử dụng nó trong --user (đất), nó sẽ chỉ khởi động khi anh ta đăng nhập, không hữu ích cho máy chủ. Và một ghi chú về bình luận của bạn. Tôi tin rằng việc đưa người dùng vào tất cả các bộ điều khiển, cho phép người dùng đó bắt đầu di chuyển pid vào không gian máy chủ, tôi tin rằng đây là một rủi ro bảo mật.
Malina Salina

Erm, có vẻ như đó là những gì bạn đang làm với phương pháp của bạn được liệt kê ban đầu tôi đoán, nhưng hãy nhìn vào điều này, ngay cả khi đó là gói hệ thống Ubuntu bị lỗi.launchpad.net / ubfox / + source / systemd / +bug / 14393927 Nhưng một cái gì đó đã được cập nhật trong những ngày qua thay đổi logic .. Tôi đang cố gắng theo dõi nó.
Malina Salina

0

Vì vậy, tôi đã gặp phải vấn đề tương tự khi cố gắng để các container không có khả năng LXC hoạt động trên CentOS 7. Tôi không muốn sử dụng cgmanagervì tôi không muốn giới thiệu bất kỳ dịch vụ bổ sung nào nếu không thực sự cần thiết. Thay vào đó, những gì tôi đã làm thay vào đó là vá systemd bằng cách sử dụng một số bản vá từ gói ubfox và một bản vá tùy chỉnh để mở rộng danh sách các bộ điều khiển cgroup. Tôi có các nguồn cần thiết để tạo RPM trên tài khoản GitHub của mình tại https://github.com/CtrlC-Root/rpmdist . Tôi cũng đã vá các phiên bản của bóng tối (cho subuids và subgids) và pam (cho loginuid). Sau khi tôi cài đặt các RPM này và định cấu hình người dùng để chạy các thùng chứa không được cấp phép (gán các giá trị con & phụ, phân bổ các cặp veth trong lxc-usernet, tạo .config / lxc / default.conf, v.v.) Tôi có thể chạy các container không có đặc quyền LXC.

EDIT: Một lý do khác khiến tôi không muốn sử dụng cgmanager là vì tôi không muốn người dùng thường xuyên phải sử dụng sudo. Người dùng thông thường sẽ có thể đăng nhập và mọi thứ sẽ "chỉ hoạt động" ra khỏi hộp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.