CẬP NHẬT: Lưu ý rằng câu trả lời dưới đây áp dụng cho RHEL 6. Trong RHEL 7, hầu hết các nhóm được quản lý bởi systemd và libcgroup không được dùng nữa.
Kể từ khi đăng câu hỏi này, tôi đã nghiên cứu toàn bộ hướng dẫn mà tôi liên kết với trên, cũng như phần lớn các cgroups.txt tài liệu và cpusets.txt . Bây giờ tôi biết nhiều hơn tôi từng mong đợi để tìm hiểu về các nhóm, vì vậy tôi sẽ trả lời câu hỏi của riêng tôi ở đây.
Có nhiều cách tiếp cận bạn có thể thực hiện. Liên hệ của công ty chúng tôi tại Red Hat (Kiến trúc sư kỹ thuật) đã đề xuất chống lại việc hạn chế tất cả các quy trình theo hướng tiếp cận khai báo hơn, chỉ giới hạn các quy trình mà chúng tôi đặc biệt muốn hạn chế. Lý do cho điều này, theo các tuyên bố của ông về chủ đề này, là có thể các cuộc gọi hệ thống phụ thuộc vào mã không gian người dùng (chẳng hạn như các quy trình LVM) mà nếu bị hạn chế có thể làm chậm hệ thống xuống ngược lại với hiệu ứng dự định. Vì vậy, tôi đã kết thúc việc hạn chế một số quy trình được đặt tên cụ thể và để mọi thứ khác một mình.
Ngoài ra, tôi muốn đề cập đến một số dữ liệu cơ bản của nhóm mà tôi đã thiếu khi tôi đăng câu hỏi của mình.
Cgroups không phụ thuộc vào libcgroup
việc được cài đặt. Tuy nhiên, đó là một bộ công cụ để tự động xử lý cấu hình cgroup và xử lý các bài tập cho các nhóm và có thể rất hữu ích.
Tôi thấy rằng các công cụ libcgroup cũng có thể được gây hiểu lầm, bởi vì các gói libcgroup được xây dựng trên nó riêng bộ trừu tượng và giả định về việc sử dụng cgroups, đó là hơi khác so với việc thực hiện mức kernel thực tế của cgroups. (Tôi có thể đưa ra các ví dụ nhưng sẽ mất một số công việc; nhận xét nếu bạn quan tâm.)
Do đó, trước khi sử dụng công cụ libcgroup (ví dụ như /etc/cgconfig.conf
, /etc/cgrules.conf
, cgexec
, cgcreate
, cgclassify
, vv) Tôi rất khuyên bạn nên nhận rất quen thuộc với /cgroup
hệ thống tập tin ảo riêng của mình, và tự tạo cgroups, phân cấp cgroup (bao gồm cả hệ thống phân cấp với nhiều hệ thống phụ kèm theo, mà libcgroup lén lút và tóm tắt leakily đi), phân công lại các quy trình cho các nhóm khác nhau bằng cách chạy echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasks
và các nhiệm vụ dường như kỳ diệu khác libcgroup
thực hiện dưới mui xe.
Một khái niệm cơ bản khác mà tôi đã thiếu là nếu /cgroup
hệ thống tệp ảo được gắn trên hệ thống của bạn (hoặc chính xác hơn, nếu bất kỳ hệ thống con cgroup nào được gọi là "bộ điều khiển" được gắn kết), thì mọi quy trình trên toàn bộ hệ thống của bạn đều nằm trong một nhóm Không có thứ gọi là "một số quy trình nằm trong một nhóm và một số thì không".
Có cái được gọi là nhóm gốc cho một hệ thống phân cấp nhất định, sở hữu tất cả tài nguyên của hệ thống cho các hệ thống con đính kèm. Ví dụ: hệ thống phân cấp cgroup có hệ thống con cpuset và blkio được đính kèm, sẽ có một nhóm gốc sở hữu tất cả các cpus trên hệ thống và tất cả các blkio trên hệ thống và có thể chia sẻ một số tài nguyên đó với các nhóm con . Bạn không thể hạn chế nhóm gốc vì nó sở hữu tất cả tài nguyên của hệ thống của bạn, vì vậy việc hạn chế nhóm này thậm chí sẽ không có ý nghĩa.
Một số dữ liệu đơn giản khác tôi đã thiếu về libcgroup:
Nếu bạn sử dụng /etc/cgconfig.conf
, bạn nên đảm bảo rằng các chkconfig --list cgconfig
chương trình cgconfig
được thiết lập để chạy khi khởi động hệ thống.
Nếu bạn thay đổi /etc/cgconfig.conf
, bạn cần chạy service cgconfig restart
để tải các thay đổi. (Và các vấn đề về việc dừng dịch vụ hoặc chạy cgclear
là rất phổ biến khi đánh lừa kiểm tra. Để gỡ lỗi tôi khuyên bạn, ví dụ lsof /cgroup/cpuset
, nếu cpuset
là tên của hệ thống phân cấp cgroup bạn đang sử dụng.)
Nếu bạn muốn sử dụng /etc/cgrules.conf
, bạn cần đảm bảo "trình nền công cụ quy tắc cgroup" ( cgrulesengd
) đang chạy: service cgred start
và chkconfig cgred on
. (Và bạn nên biết về một điều kiện chủng tộc có thể nhưng không thể xảy ra đối với dịch vụ này, như được mô tả trong Hướng dẫn quản lý tài nguyên của Red Hat trong phần 2.8.1 ở cuối trang.)
Nếu bạn muốn đánh lừa thủ công và thiết lập các nhóm của mình bằng hệ thống tệp ảo (mà tôi khuyên dùng lần đầu tiên), bạn có thể làm như vậy và sau đó tạo một cgconfig.conf
tệp để phản ánh thiết lập của mình bằng cách sử dụng cgsnapshot
với các tùy chọn khác nhau.
Và cuối cùng, phần thông tin chính tôi đã thiếu khi tôi viết như sau:
Tuy nhiên, sự cảnh báo về điều này dường như là ... rằng những đứa trẻ của my Processname sẽ được gán lại cho nhóm cpu0only bị hạn chế.
Tôi đã đúng, nhưng có một lựa chọn mà tôi không biết.
cgexec
là lệnh để bắt đầu một quá trình / chạy một lệnh và gán nó cho một nhóm.
cgclassify
là lệnh để gán một quá trình đã chạy cho một nhóm.
Cả hai điều này cũng sẽ ngăn cgred
( cgrulesengd
) gán lại quy trình đã chỉ định cho một nhóm khác dựa trên /etc/cgrules.conf
.
Cả hai cgexec
và cgclassify
hỗ trợ --sticky
cờ, điều này cũng ngăn chặn việc cgred
gán lại các quy trình con dựa trên /etc/cgrules.conf
.
Vì vậy, câu trả lời cho câu hỏi khi tôi viết nó (mặc dù không phải là thiết lập mà tôi đã thực hiện, vì lời khuyên từ Kiến trúc sư kỹ thuật Red Hat của chúng tôi đã đề cập ở trên) là:
Làm cho cpu0only
và anycpu
cgroup như mô tả trong câu hỏi của tôi. (Đảm bảo cgconfig
được đặt để chạy khi khởi động.)
Thực hiện các * cpuset cpu0only
quy tắc như mô tả trong câu hỏi của tôi. (Và đảm bảo cgred
được thiết lập để chạy khi khởi động.)
Bắt đầu bất kỳ quy trình tôi muốn không bị hạn chế với : cgexec -g cpuset:anycpu --sticky myprocessname
.
Các quy trình đó sẽ không bị hạn chế và tất cả các quy trình con của chúng cũng sẽ không bị hạn chế. Mọi thứ khác trên hệ thống sẽ bị giới hạn ở CPU 0 (một khi bạn khởi động lại, vì cgred
không áp dụng các cgrules cho các quy trình đã chạy trừ khi chúng thay đổi EUID của chúng). Điều này không hoàn toàn được khuyến khích, nhưng đó là những gì tôi yêu cầu ban đầu và nó có thể được thực hiện với các nhóm.