本文介绍了在ubuntu内核中启用cgroup CPU实时运行时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Ubuntu 18.04上运行的停靠容器中使用实时调度。

我已经按照here的方法安装了一个实时内核。我已经选择了内核版本5.2.9及其相关的RT补丁。

uname -a的输出确认实时内核已正确安装并运行:

Linux myLaptop 5.2.9-rt3 #1 SMP PREEMPT RT ...

要运行我的容器,我发出以下命令:

docker run --cpu-rt-runtime=95000 
    --ulimit rtprio=99 
    --ulimit memlock=102400 
    --cap-add=sys_nice 
    --privileged 
    -it 
    myimage:latest

但是,我得到的输出是:

docker: Error response from daemon: Your kernel does not support cgroup cpu real-time runtime.

我已经看到,这可以链接到问题here中详细说明的缺失的CONFIG_RT_GROUP_SCHED。实际上,如果我运行this page中提供的脚本来检查内核与Docker的兼容性,我会得到:

- CONFIG_RT_GROUP_SCHED: missing

这似乎证实了Docker正在使用它进行实时调度,但内核中没有提供,尽管打了补丁以实现实时。

从那里,我试图找到一个解决方案,但没有成功。我不太精通内核配置,不知道是否需要使用特定选项编译它,以及选择哪个选项来添加缺失的CONFIG_RT_GROUP_SCHED

事先非常感谢您的建议和帮助。

推荐答案

在谈到实时linux时,有不同的方法,从单内核方法(如PREEMPT_RT)到dual-kernel approaches(如Xenomai)。您可以将具有实时功能的Docker与所有这些功能相结合(显然,您的主机的内核必须匹配)来生成具有实时功能的系统,但方法有所不同。在您的情况下,您混淆了两种不同的方法:您按照与PREEMPT_RT不兼容的control groups指南安装了PREEMPT_RT


默认Linux内核可以使用不同级别的抢占能力进行编译(例如,请参阅Reghenzani et al. - "The real-time Linux kernel: a Survey on PREEMPT_RT"):

  • PREEMPT_NONE无法强制抢占
  • PREEMPT_VOLUNTARY某些位置可以抢占以减少延迟
  • PREEMPT其中抢占可以发生在内核的任何部分(不包括spinlocks和其他临界区)

通过设置CONFIG_RT_GROUP_SCHED=y during kernel compilation,可以将这些功能与control groups (cgroups for short)的功能结合起来,为某个(自定义)组的进程预留一定比例的CPU时间。

PREEMPT_RTPREEMPT发展而来,是一组旨在使内核完全可抢占的补丁,即使在关键部分(PREEMPT_RT_FULL)。为此,例如spinlocks are largely replaced by mutexes。从2021年起,它将slowly merged into the mainline向公众开放,无需为内核打补丁。如上所述,herePREEMPT_RT目前不能与CONFIG_RT_GROUP_SCHED一起编译,因此不能与对照组一起使用(参见here for a comparison)。据我所知,这是由于high latency spikes,我已经通过cyclicytests观察到了对照组的情况。

这意味着您可以编译内核(有关详细信息,请参阅Ubuntu manual)

  • 没有PREEMPT_RT,但有CONFIG_RT_GROUP_SCHED(详见this post),关注Docker guide on real-time with control groups以及我的帖子here。从我的经验来看,这具有相当高的延迟峰值,这对于实时系统来说是不可取的,因为在实时系统中,最坏情况下的延迟比平均延迟重要得多。

  • PREEMPT_RT不带CONFIG_RT_GROUP_SCHED(也可以从this one这样的Debian包安装)。在这种情况下,只需使用选项--privileged --net=host或等效的Docker-Composeprivileged: true network_mode: host来执行Docker就足够了。然后Docker内部的任何进程都可以设置实时优先级rtprio(例如,从代码内部调用::pthread_setschedparam或从命令行使用chrt)。

    如果您是not using the root as user inside the Docker,您还必须为自己指定一个用户名,该用户名属于在您的主机上具有实时权限的组(请参见$ ulimit -r)。这可以通过相应地配置PAM limits(/etc/security/limits.conf文件)来完成(如here所述),方法是复制@realtime用户组的部分并创建新组(例如@some_group)或直接添加用户(例如some_user):

    @some_group     soft    rtprio          99
    @some_group     soft    priority        99
    @some_group     hard    rtprio          99
    @some_group     hard    priority        99
    
    在此上下文中rtprio是非特权进程允许的最大实时优先级。hard限制是soft限制可以设置到的实际限制。hard限制由超级用户设置并由内核强制执行。用户无法将其代码提升为以高于hard限制的优先级运行。另一方面,soft限制是由hard限制的默认值。有关更多信息,请参见here

我对实时机器人应用程序使用后一种选项,未观察到使用Docker和不使用Docker在延迟方面的任何差异。

这篇关于在ubuntu内核中启用cgroup CPU实时运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 07:50