在systemd下的Debian上,默认情况下,libvirt下的KVM虚拟机被分配给"machine.slice“片。
然后,如果我用cset和一些定制的CPU集为这个切片添加一个cpuset,并启动一个VM,那么VM就会添加到适当的cpuset中,即
user@host ~ $ sudo cset set --list --recurse
cset:
Name CPUs-X MEMs-X Tasks Subs Path
------------ ---------- - ------- - ----- ---- ----------
root 0-31 y 0 y 610 1 /
machine.slice 2-15,18-31 n 0 n 0 1 /machine.slice
machine-qemu\x2d1\x2dweb1.scope 2-15,18-31 n 0 n 0 5 /ma....scope
vcpu1 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu1
vcpu2 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu2
vcpu0 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu0
emulator 2-15,18-31 n 0 n 82 0 /machine.sli...1.scope/emulator
vcpu3 2-15,18-31 n 0 n 1 0 /machine.sli...web1.scope/vcpu3我想要做的是用一个单独的切片和cpuset来复制这种行为。然而,它似乎不起作用。
首先,我创建了cset:
user@host ~ $ sudo cset set -c 0-1,16-17 osd.slice
cset: --> created cpuset "osd.slice"然后设置我想要使用的服务:
user@host ~ $ diff -u /lib/systemd/system/ceph-osd@.service /etc/systemd/system/ceph-osd@.service
--- /lib/systemd/system/ceph-osd@.service 2021-05-27 06:04:21.000000000 -0400
+++ /etc/systemd/system/ceph-osd@.service 2022-11-08 17:20:32.515087642 -0500
@@ -6,6 +6,7 @@
Wants=network-online.target local-fs.target time-sync.target remote-fs-pre.target ceph-osd.target
[Service]
+Slice=osd.slice
LimitNOFILE=1048576
LimitNPROC=1048576
EnvironmentFile=-/etc/default/ceph然后我开始其中一项服务。如果我检查服务状态,就会发现它位于正确的片段/cgroup中:
user@host ~ $ systemctl status ceph-osd@0.service
● ceph-osd@0.service - Ceph object storage daemon osd.0
Loaded: loaded (/etc/systemd/system/ceph-osd@.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2022-11-08 17:22:32 EST; 1s ago
Process: 251238 ExecStartPre=/usr/lib/ceph/ceph-osd-prestart.sh --cluster ${CLUSTER} --id 0 (code=exited, status=0/SUCCESS)
Main PID: 251245 (ceph-osd)
Tasks: 25
Memory: 29.5M
CPU: 611ms
CGroup: /osd.slice/ceph-osd@0.service
└─251245 /usr/bin/ceph-osd -f --cluster ceph --id 0 --setuser ceph --setgroup ceph为了保持清醒,如果我检查VM临时服务,它看起来基本上是一样的:
$ systemctl status machine-qemu\\x2d1\\x2dweb1.scope
● machine-qemu\x2d1\x2dweb1.scope - Virtual Machine qemu-1-web1
Loaded: loaded (/run/systemd/transient/machine-qemu\x2d1\x2dweb1.scope; transient)
Transient: yes
Active: active (running) since Tue 2022-11-08 17:03:57 EST; 22min ago
Tasks: 87 (limit: 16384)
Memory: 1.7G
CPU: 4min 33.514s
CGroup: /machine.slice/machine-qemu\x2d1\x2dweb1.scope
└─234638 /usr/bin/kvm -name guest=web1,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-web1/master-key.aes -machine pc-i440fx-2.7,accel=kvm,usb=off,dump-guest-core=off,memory-ba>但是,这就是我陷入困境的地方:如果我再次检查cset,“任务”不会像我所期望的那样分配给片cset;相反,它们是root cset的一部分,而片cset有0任务和0子:
user@host ~ $ sudo cset set --list --recurse
cset:
Name CPUs-X MEMs-X Tasks Subs Path
------------ ---------- - ------- - ----- ---- ----------
root 0-31 y 0 y 622 2 /
osd.slice 0-1,16-17 n 0 n 0 0 /osd.slice我看不出machine.slice是如何做到这一点的,在实际的machine.slice单元文件中没有引用它,在瞬态scope单元中也看不到任何东西。
我如何才能得到这个新的、自定义的切片/cgroup来模仿machine.slice正在做的事情,并将其下的任何东西强制放到这个cpuset中呢?
作为“为什么”/X-to-my-Y的补充,我尝试使用ceph-osd命令手动在cset中生成cset proc --exec进程,但这并不可靠(有时它完全失败而“无法移动”),即使它工作了,即使主进程被移动,它的线程最终也会卡在根cset中。因此,我似乎需要一种方法,在实际进程启动之前,使systemd将整个单元作为cset的一部分(不像cset proc命令生成它、分叉它、然后修改它),这看起来就像在这里使用machine.slice所做的那样。
发布于 2022-11-12 09:00:20
最后,我放弃了cset,因为它是实现这一目标的理想方法。事实上,它需要旧的v1 cgroup层次结构,并且多年来没有进行重大的更新,这在很大程度上起到了作用,特别是这个bug使我更多地研究了systemd的选项。
然后,我找到了systemd的Integrated合金化the指令,它似乎也完全符合我的要求,尤其是在片级部署时。
按照这种方式,我在/etc/systemd/system中为我想要隔离的每个子系统创建了几个插入片单元(system.slice用于大多数任务到一个cpuset,osd.slice用于我的OSD进程,machine.slice用于VM),每个单元都设置了一个具有指定限制的专用VMs,并使代表能够确定。稍后重新启动一次,据我所知,它正按预期的方式工作。
https://serverfault.com/questions/1115179
复制相似问题