在centos7使用了docker,而我们的部署程序中,有直接部署在宿主机上的,并且程序的需要,需要设置调度为SCHED_RR的CPU调度模式,结果在没有部署docker的设备中,可以正常运行为RR模式;而在运行了docker的设备上,则会被改变成了TS模式。因此怀疑是因为docker的引入后,导致程序设置为RR模式异常。
我们要看是否可以设置为RR模式,可以通过chrt命令来查看。
chrt -r 80 ps -e -o class,rtprio,pri,nice,cmd RR 80 120 - ps -e -o class,rtprio,pri,nice,cmd
默认chrt是修改为RR模式,如果有修改成功,则会看到是RR 优先级为80.
而如果centos7启用了docker的话,则不能设置成功,会有如下的报错。
chrt -r 80 ps -e -o class,rtprio,pri,nice,cmd chrt: failed to set pid 0's policy: Operation not permitted
这时候也就切换失败了。我们知道docker其实是基于cgroups以及namespase的技术的。关键就在于cgroups技术,centos7下,内核是开启RT_GROUP的,这点可以通过以下命令确定:
cat /boot/config-`uname -r` | grep -i rt_group CONFIG_RT_GROUP_SCHED=y
也就是有开启了RT_GROUP的调度策略,而我测试了下,使用Ubuntu的话,则不会有这个问题,因为Ubuntu这个参数是关闭的。
再来看看cgroup,我们要查看系统的cgroup的一些配置,首先要知道其挂载的情况:
mount -t cgroup cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
而CPU相关的,我们看/sys/fs/cgroup/cpu,cpuacct中的配置项,centos的没开启docker的配置项如下:
ls /sys/fs/cgroup/cpu,cpuacct/ cgroup.clone_children cgroup.procs cpuacct.stat cpuacct.usage_percpu cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat release_agent cgroup.event_control cgroup.sane_behavior cpuacct.usage cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release tasks
其中与RT_GROUP的CPU调度的配置文件有两个,一个是cpu.rt_runtime_us另一个是cpu.rt_period_us
cat /sys/fs/cgroup/cpu,cpuacct/cpu.rt_period_us 1000000 cat /sys/fs/cgroup/cpu,cpuacct/cpu.rt_runtime_us 950000
这两的单位是微秒,rt_period_us表示是实时进程调度的单位CPU时间 是1 秒;rt_runtime_us表示是实时进程在单位时间内(目前配置也就是1秒)实际占用的CPU时间, 0.95秒。
而当启动了docker之后,在cpu,cpuacct目录中会多出以下的一些文件夹。
ls /sys/fs/cgroup/cpu,cpuacct/ cgroup.clone_children cgroup.sane_behavior cpuacct.usage_percpu cpu.rt_period_us cpu.stat release_agent user.slice cgroup.event_control cpuacct.stat cpu.cfs_period_us cpu.rt_runtime_us docker system.slice cgroup.procs cpuacct.usage cpu.cfs_quota_us cpu.shares notify_on_release tasks
多了docker,user.slice,system.slice;也就是说,cgroup被细分了。而chrt我们是直接使用命令行的形式,因此是属于user.slice的。因此我们看看user.slice中cpu.rt_runtime_us以及cpu.rt_period_us的配置是如何的。
cat /sys/fs/cgroup/cpu,cpuacct/user.slice/cpu.rt_runtime_us 0 cat /sys/fs/cgroup/cpu,cpuacct/user.slice/cpu.rt_period_us 1000000
rt_period_us是一样的,但是rt_runtime_us为0,也就是禁用的CPU调度的相关策略,因此我们将rt_runtime_us 修改为默认的950000:
echo 950000 > /sys/fs/cgroup/cpu,cpuacct/user.slice/cpu.rt_runtime_us
然后再支持下chrt命令:
chrt -r 80 ps -e -o class,rtprio,pri,nice,cmd RR 80 120 - ps -e -o class,rtprio,pri,nice,cmd
可以成功切换为RR,因此这个问题也就得到了解决!
参考资料:
【求助】sched_setscheduler(): Operation not permitted
转载请注明: 转载自elkPi.com
本文链接地址: CentOS7 docker开启后设置SCHED_RR出现Operation not permitted的问题