Làm cách nào để sử dụng các nhóm để giới hạn tất cả các quy trình ngoại trừ danh sách trắng cho một CPU?


26

Có một hướng dẫn về các nhóm từ Red Hat có thể là loại hữu ích (nhưng không trả lời câu hỏi này).

Tôi biết cách giới hạn một quy trình cụ thể cho một CPU cụ thể, trong lệnh để bắt đầu quá trình đó, bằng cách:

Đầu tiên, đặt * sau /etc/cgconfig.conf:

mount {
  cpuset =  /cgroup/cpuset;
  cpu =     /cgroup/cpu;
  cpuacct = /cgroup/cpuacct;
  memory =  /cgroup/memory;
  devices = /cgroup/devices;
  freezer = /cgroup/freezer;
  net_cls = /cgroup/net_cls;
  blkio =   /cgroup/blkio;
}

group cpu0only {
  cpuset {
    cpuset.cpus = 0;
    cpuset.mems = 0;
  }
}

Và sau đó bắt đầu một quy trình và chỉ định cụ thể cho nhóm đó bằng cách sử dụng:

cgexec -g cpuset:cpu0only myprocessname

Tôi có thể tự động giới hạn tất cả các phiên bản của một tên quy trình cụ thể bằng cách (tôi nghĩ rằng điều này là chính xác) đưa các mục sau vào /etc/cgrules.conf:

# user:process  controller  destination
*:myprocessname cpuset      cpu0only

Câu hỏi của tôi là: Làm thế nào tôi có thể làm ngược lại ?

Nói cách khác, Làm thế nào tôi có thể chỉ định tất cả các quy trình ngoại trừ một tập hợp các quy trình được liệt kê trong danh sách trắng và con cái của chúng cho một nhóm hạn chế?


Dựa trên những gì tôi đã nghiên cứu, nhưng chưa được thử nghiệm, tôi tin rằng một giải pháp một phần sẽ là:

Thêm một nhóm "không giới hạn":

group anycpu {
  cpuset {
    cpuset.cpus = 0-31;
    cpuset.mems = 0;  # Not sure about this param but it seems to be required
  }
}

Chỉ định rõ ràng quy trình của tôi cho nhóm không bị hạn chế và mọi thứ khác cho nhóm bị hạn chế:

# user:process  controller  destination
*:myprocessname cpuset      anycpu
*               cpuset      cpu0only

Tuy nhiên, sự cảnh báo về điều này dường như là (từ việc đọc các tài liệu, không phải từ thử nghiệm, vì vậy hạt muối) mà những đứa trẻ của myprocessnamesẽ được gán lại cho nhóm hạn chế cpu0only.

Một cách tiếp cận thay thế khả thi sẽ là tạo một người dùng để chạy myprocessnamevà tất cả các quy trình của người dùng đó không bị hạn chế và mọi thứ khác đều bị hạn chế. Tuy nhiên, trong trường hợp sử dụng thực tế của tôi, quy trình cần phải được chạy bằng root và có những quy trình khác cũng phải được chạy bởi root nên bị hạn chế.

Làm thế nào tôi có thể thực hiện điều này với các nhóm?


Nếu điều này là không thể với các nhóm (mà bây giờ tôi nghi ngờ là trường hợp này), ý tưởng của tôi về các giải pháp một phần có đúng không và liệu chúng có hoạt động như tôi nghĩ không?

* Tuyên bố miễn trừ trách nhiệm: Đây có lẽ không phải là một ví dụ mã tối thiểu; Tôi không hiểu tất cả các phần nên tôi không biết cái nào không cần thiết.

Câu trả lời:


30

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 libcgroupviệ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 /cgrouphệ 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/tasksvà các nhiệm vụ dường như kỳ diệu khác libcgroupthự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 /cgrouphệ 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 cgconfigchươ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 cgclearlà 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 cpusetlà 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 startchkconfig 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.conftệp để phản ánh thiết lập của mình bằng cách sử dụng cgsnapshotvớ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 cgexeccgclassifyhỗ trợ --stickycờ, điều này cũng ngăn chặn việc cgredgá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 cpu0onlyanycpucgroup 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 cpu0onlyquy 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ì cgredkhô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.


ồ mát mẻ. Làm thế nào điều này có 0 phiếu?
mikeerv

@mikeerv, cảm ơn. :) Trả lời câu hỏi của bạn: kiểm tra ngày tháng; Tôi chỉ viết câu trả lời này ngày hôm qua.
tự đại diện

1
tôi đã thấy điều đó nhưng đó là 24 giờ trước. có lẽ nguyên nhân của nó dài. những thứ tốt đôi khi có thể bị bỏ qua như thế. và dù sao đi nữa, những câu trả lời với rất nhiều phiếu bầu thực sự rất hiếm khi là những câu trả lời hay - thông tin không thể hữu ích nếu rất nhiều người biết điều đó. đây là một trong những cái tốt cgroups là friggin bí ẩn.
mikeerv
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.