问题描述
我正在尝试在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_RT
从PREEMPT
发展而来,是一组旨在使内核完全可抢占的补丁,即使在关键部分(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,我已经通过cyclicytest
s观察到了对照组的情况。
这意味着您可以编译内核(有关详细信息,请参阅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实时运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!