如何用Puppet配置已存在的cgroup v2资源控制器(如cpu.max)
如何通过Puppet配置已存在cgroup的cgroup v2控制器(如
cpu.max) 在Shell环境中,我们可以直接写入cgroup虚拟文件系统的接口文件完成配置,例如设置cpu.max:
echo "19200000 100000" > /sys/fs/cgroup/system.slice/existing-group/cpu.max
但直接使用Puppet的file资源设置content属性会失败——因为Puppet默认会创建临时文件并与目标文件交换,而cgroup虚拟文件系统不支持这种操作。例如以下资源定义:
file { '/sys/fs/cgroup/system.slice/existing-group/cpu.max': content => "19200000 100000\n", ; }
会触发权限错误,具体报错如下:
Notice: /Stage[main]/MyModule::Resource/File[/sys/fs/cgroup/system.slice/existing-group/cpu.max]/content: --- /sys/fs/cgroup/system.slice/existing-group/cpu.max 2025-06-24 19:48:16.022215949 +0200 +++ /tmp/puppet-file20250624-212062-ico87p 2025-06-24 19:50:59.628083549 +0200 @@ -1 +1 @@ -max 100000 +19200000 100000 Error: Permission denied @ rb_sysopen - /sys/fs/cgroup/system.slice/existing-group/cpu.max20250624-212062-1tugk2r Error: /Stage[main]/MyModule::Resource/File[/sys/fs/cgroup/system.slice/existing-group/cpu.max]/content: change from '{sha256}04afe0d058a8924a172509ae2f711347aca93cbca3879c64bd8d3d1b2e559ee7' to '{sha256}c987d0dfaf6ae53cd6df8e04c69756e356a924577c893a747088be76fb78da67' failed: Permission denied @ rb_sysopen - /sys/fs/cgroup/system.slice/existing-group/cpu.max20250624-212062-1tugk2r
针对这个问题,有两种可行的替代方案:
方案1:使用exec资源直接写入
通过exec资源模拟Shell的写入操作,同时添加onlyif条件判断,仅当当前值与期望值不一致时才执行命令,避免无意义的重复操作:
exec { 'set_cpu_max_for_existing_group': command => 'echo "19200000 100000" > /sys/fs/cgroup/system.slice/existing-group/cpu.max', path => ['/bin', '/usr/bin'], onlyif => 'test "$(cat /sys/fs/cgroup/system.slice/existing-group/cpu.max)" != "19200000 100000"', }
command:执行实际的写入命令onlyif:检查目标文件的当前内容,确保仅在需要时执行修改
方案2:自定义Puppet类型(长期优雅方案)
如果需要管理多个cgroup接口文件,自定义Puppet类型可以封装状态检查和写入逻辑,让代码更简洁、符合Puppet的资源模型。
步骤1:创建自定义类型
在Puppet模块的lib/puppet/type/目录下创建cgroup_v2_setting.rb文件,内容如下:
Puppet::Type.newtype(:cgroup_v2_setting) do ensurable newparam(:name) do desc '路径到cgroup接口文件(例如:/sys/fs/cgroup/system.slice/existing-group/cpu.max)' isnamevar end newproperty(:value) do desc 'cgroup设置的期望值' def retrieve File.read(resource[:name]).strip end def sync File.write(resource[:name], "#{value}\n") end end end
步骤2:使用自定义类型
在模块的manifest中直接调用该类型:
cgroup_v2_setting { '/sys/fs/cgroup/system.slice/existing-group/cpu.max': value => '19200000 100000', }
这种方式会自动检查当前值是否符合期望,仅在不一致时执行写入,无需手动编写条件判断。
内容的提问来源于stack exchange,提问作者MisterMiyagi
相关产品推荐
相关产品推荐

