使用Ubuntu(Linux)主机

时间:2017-10-04 11:08:09

标签: c++ linux ubuntu docker real-time

在开始之前,我有两个想法是否应该在SuperUser或Stackoverflow中提出这个问题 - 如果它位于错误的位置,请提前道歉。

我有一个docker容器(包含C / C ++可执行代码),用于执行音频/视频处理。因此,我想测试使用RT调度约束运行容器的好处。在网上搜索时,我发现了各种各样的信息,但我很难将所有部分放在一起。

系统环境:

  • 主持人:Ubuntu(股票)Zesty 17.04( RT内核补丁,内核:4.10.0-35-genric)
  • Docker版本:17.05.0-ce
  • Docker Images操作系统:Ubuntu Zesty 17.04。

在嵌套在docker镜像/容器中的可执行文件中,执行以下代码以从' SCHED_OTHER'更改调度程序。到' SCHED_FIFO' (见docs):

    struct sched_param sched = {};

    const int nMin = sched_get_priority_min(SCHED_FIFO);
    const int nMax = sched_get_priority_max(SCHED_FIFO);

    const int nHlf = (nMax - nMin) / 2;
    const int nPriority = nMin + nHlf + 1;

    sched.sched_priority = boost::algorithm::clamp(nPriority, nMin, nMax);

    if (sched_setscheduler(0, SCHED_FIFO, &sched) < 0)
        std::cerr << "SETSCHEDULER failed - err = " << strerror(errno) << std::endl;
    else
        std::cout << "Priority set to \"" << sched.sched_priority << "\"" << std::endl;

我一直在阅读使用实时调度程序的各种Docker文档。一个有趣的page州,

  

通过运行 zcat /proc/config.gz |验证Linux内核中是否启用了CONFIG_RT_GROUP_SCHED。 grep CONFIG_RT_GROUP_SCHED 或检查是否存在文件/sys/fs/cgroup/cpu.rt_runtime_us。有关配置内核实时调度程序的指导,请参阅操作系统的文档。

根据上述建议,股票Ubuntu Zesty 17.04 OS似乎未通过这些检查。

第一个问题:我不能使用RT调度程序吗?什么是&CONFIG_RT_GROUP_SCHED&#39;?令我困惑的一件事是,从2010年到2012年,网上有一些关于使用RT补丁修补内核的旧帖子。从那时起,似乎Linux内核中有一些与软RT相关的工作。

引用here引发了我的疑问:

  

从内核版本2.6.18开始,Linux逐渐具备实时功能,其中大部分源自Ingo Molnar,Thomas Gleixner,Steven Rostedt等人开发的以前实时抢占补丁。在补丁完全合并到主线内核之前(预计这将是内核版本2.6.30),必须安装它们才能获得最佳的实时性能。这些补丁命名为:

继续......

阅读了其他信息后,我注意到设置ulimits非常重要。我改变了/etc/security/limits.conf:

#*               soft    core            0
#root            hard    core            100000
#*               hard    rss             10000

# NEW ADDITION
gavin            hard    rtprio          99

第二个问题:可能上面需要启用docker守护程序来运行RT?看起来守护进程是通过systemd控制的。

我继续进行调查,在同一个Docker文档页面上看到以下代码段:

  

要使用实时调度程序运行容器,请运行Docker守护程序,并将--cpu-rt-runtime标志设置为每个运行时间段为实时任务保留的最大微秒数。例如,默认周期为10000微秒(1秒),设置--cpu-rt-runtime = 95000可确保使用实时调度程序的容器每10000微秒可以运行95000微秒,并保留至少5000微秒用于非实时任务。要在使用systemd的系统上永久保留此配置,请参阅使用systemd控制和配置Docker。

关注this page,我发现守护进程有两个参数值得关注:

  --cpu-rt-period int                     Limit the CPU real-time period in microseconds
  --cpu-rt-runtime int                    Limit the CPU real-time runtime in microseconds

同一页面表明可以通过&#39; /etc/docker/daemon.json'指定docker守护程序参数,所以我试过了:

{
    "cpu-rt-period": 92500,
    "cpu-rt-runtime": 100000
}

注意:文档未在Linux&#39;上指定上述选项作为允许的配置选项。我想我会试一试。

重启时

Docker守护程序输出:

-- Logs begin at Wed 2017-10-04 09:58:38 BST, end at Wed 2017-10-04 10:01:32 BST. --
Oct 04 09:58:47 gavin systemd[1]: Starting Docker Application Container Engine...
Oct 04 09:58:47 gavin dockerd[1501]: time="2017-10-04T09:58:47.885882588+01:00" level=info msg="libcontainerd: new containerd process, pid: 1531"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.053986072+01:00" level=warning msg="failed to rename /var/lib/docker/tmp for background deletion: %!s(<nil>).
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.161303803+01:00" level=info msg="[graphdriver] using prior storage driver: aufs"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.303409053+01:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.304002725+01:00" level=warning msg="Your kernel does not support swap memory limit"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.304078792+01:00" level=warning msg="Your kernel does not support cgroup rt period"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.304201239+01:00" level=warning msg="Your kernel does not support cgroup rt runtime"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.305534113+01:00" level=info msg="Loading containers: start."
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.730193030+01:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemo
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.784938130+01:00" level=info msg="Loading containers: done."
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.888035017+01:00" level=info msg="Daemon has completed initialization"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.888104120+01:00" level=info msg="Docker daemon" commit=89658be graphdriver=aufs version=17.05.0-ce
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.903280645+01:00" level=info msg="API listen on /var/run/docker.sock"
Oct 04 09:58:48 gavin systemd[1]: Started Docker Application Container Engine.

特定的兴趣点:

Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.304078792+01:00" level=warning msg="Your kernel does not support cgroup rt period"
Oct 04 09:58:48 gavin dockerd[1501]: time="2017-10-04T09:58:48.304201239+01:00" level=warning msg="Your kernel does not support cgroup rt runtime"

鉴于我之前的发现,这并不奇怪。

最后一个问题:当这个问题最终起作用时,我怎样才能确定我的容器是否真正在RT调度中运行?喜欢顶级&#39;足够?

编辑:我在github上通过moby运行了一个内核诊断scriptfound。这是输出:

warning: /proc/config.gz does not exist, searching other paths for kernel config ...
info: reading kernel config from /boot/config-4.10.0-35-generic ...

Generally Necessary:
- cgroup hierarchy: properly mounted [/sys/fs/cgroup]
- apparmor: enabled and tools installed
- CONFIG_NAMESPACES: enabled
- CONFIG_NET_NS: enabled
- CONFIG_PID_NS: enabled
- CONFIG_IPC_NS: enabled
- CONFIG_UTS_NS: enabled
- CONFIG_CGROUPS: enabled
- CONFIG_CGROUP_CPUACCT: enabled
- CONFIG_CGROUP_DEVICE: enabled
- CONFIG_CGROUP_FREEZER: enabled
- CONFIG_CGROUP_SCHED: enabled
- CONFIG_CPUSETS: enabled
- CONFIG_MEMCG: enabled
- CONFIG_KEYS: enabled
- CONFIG_VETH: enabled (as module)
- CONFIG_BRIDGE: enabled (as module)
- CONFIG_BRIDGE_NETFILTER: enabled (as module)
- CONFIG_NF_NAT_IPV4: enabled (as module)
- CONFIG_IP_NF_FILTER: enabled (as module)
- CONFIG_IP_NF_TARGET_MASQUERADE: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_ADDRTYPE: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_CONNTRACK: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_IPVS: enabled (as module)
- CONFIG_IP_NF_NAT: enabled (as module)
- CONFIG_NF_NAT: enabled (as module)
- CONFIG_NF_NAT_NEEDED: enabled
- CONFIG_POSIX_MQUEUE: enabled

Optional Features:
- CONFIG_USER_NS: enabled
- CONFIG_SECCOMP: enabled
- CONFIG_CGROUP_PIDS: enabled
- CONFIG_MEMCG_SWAP: enabled
- CONFIG_MEMCG_SWAP_ENABLED: missing
    (cgroup swap accounting is currently not enabled, you can enable it by setting boot option "swapaccount=1")
- CONFIG_LEGACY_VSYSCALL_EMULATE: enabled
- CONFIG_BLK_CGROUP: enabled
- CONFIG_BLK_DEV_THROTTLING: enabled
- CONFIG_IOSCHED_CFQ: enabled
- CONFIG_CFQ_GROUP_IOSCHED: enabled
- CONFIG_CGROUP_PERF: enabled
- CONFIG_CGROUP_HUGETLB: enabled
- CONFIG_NET_CLS_CGROUP: enabled (as module)
- CONFIG_CGROUP_NET_PRIO: enabled
- CONFIG_CFS_BANDWIDTH: enabled
- CONFIG_FAIR_GROUP_SCHED: enabled
- CONFIG_RT_GROUP_SCHED: missing
- CONFIG_IP_VS: enabled (as module)
- CONFIG_IP_VS_NFCT: enabled
- CONFIG_IP_VS_RR: enabled (as module)
- CONFIG_EXT4_FS: enabled
- CONFIG_EXT4_FS_POSIX_ACL: enabled
- CONFIG_EXT4_FS_SECURITY: enabled
- Network Drivers:
  - "overlay":
    - CONFIG_VXLAN: enabled (as module)
      Optional (for encrypted networks):
      - CONFIG_CRYPTO: enabled
      - CONFIG_CRYPTO_AEAD: enabled
      - CONFIG_CRYPTO_GCM: enabled (as module)
      - CONFIG_CRYPTO_SEQIV: enabled
      - CONFIG_CRYPTO_GHASH: enabled (as module)
      - CONFIG_XFRM: enabled
      - CONFIG_XFRM_USER: enabled (as module)
      - CONFIG_XFRM_ALGO: enabled (as module)
      - CONFIG_INET_ESP: enabled (as module)
      - CONFIG_INET_XFRM_MODE_TRANSPORT: enabled (as module)
  - "ipvlan":
    - CONFIG_IPVLAN: enabled (as module)
  - "macvlan":
    - CONFIG_MACVLAN: enabled (as module)
    - CONFIG_DUMMY: enabled (as module)
  - "ftp,tftp client in container":
    - CONFIG_NF_NAT_FTP: enabled (as module)
    - CONFIG_NF_CONNTRACK_FTP: enabled (as module)
    - CONFIG_NF_NAT_TFTP: enabled (as module)
    - CONFIG_NF_CONNTRACK_TFTP: enabled (as module)
- Storage Drivers:
  - "aufs":
    - CONFIG_AUFS_FS: enabled (as module)
  - "btrfs":
    - CONFIG_BTRFS_FS: enabled (as module)
    - CONFIG_BTRFS_FS_POSIX_ACL: enabled
  - "devicemapper":
    - CONFIG_BLK_DEV_DM: enabled
    - CONFIG_DM_THIN_PROVISIONING: enabled (as module)
  - "overlay":
    - CONFIG_OVERLAY_FS: enabled (as module)
  - "zfs":
    - /dev/zfs: missing
    - zfs command: missing
    - zpool command: missing

Limits:
- /proc/sys/kernel/keys/root_maxkeys: 1000000

意义重点:

- CONFIG_RT_GROUP_SCHED: missing

1 个答案:

答案 0 :(得分:6)

在容器中进行RT调度有两种选择:

  1. 添加SYS_NICE功能

    docker run --cap-add SYS_NICE ...

  2. 使用特权模式--privileged flag

    docker run --privileged ...

  3. 特权模式据说是不安全的,因此选项1最好只添加您需要的功能。

    如果以root用户身份运行(Docker容器的默认设置),您可能还必须在sysctl中启用实时调度:

    sysctl -w kernel.sched_rt_runtime_us=-1
    

    制作永久版(更新图片):

    echo 'kernel.sched_rt_runtime_us=-1' > /etc/sysctl.conf
    

    https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities