Linux系统调用clock_settime(...)失败,Docker容器中出现EPERM

时间:2018-12-12 17:48:19

标签: c linux docker ubuntu time

Tl; dr:当我尝试在Ubuntu 18.04容器中执行clock_settime(...)linux syscall时,即使程序以root身份运行,它也会失败并显示EPERM错误。在Ubuntu 18.04上,与根目录完全相同的程序可以在容器外部运行。

程序如下:

/*  main.c: This program sets the clock forward 1 day. */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

int main( void )
{
    struct timespec stime;

    if( clock_gettime( CLOCK_REALTIME, &stime) == -1 ) {
        perror( "getclock" );
        exit( EXIT_FAILURE );
    }

    stime.tv_sec += (60*60)*24L;  /* Add one day */
    stime.tv_nsec = 0;

    if( clock_settime( CLOCK_REALTIME, &stime) == -1 ) {
        perror( "setclock" );
        exit( EXIT_FAILURE );
    }

    return( EXIT_SUCCESS );
}

(取自https://users.pja.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_settime.html

在容器外运行时,日期已成功更新:

# gcc main.c -o pushtime
# date && ./pushtime && date
Wed Dec 12 09:38:36 PST 2018
Tue Dec 11 09:38:38 PST 2018

在容器内部运行时,会引发EPERM错误:

# gcc main.c -o pushtime
# docker run -it -v `pwd`:/workspace ubuntu:bionic /workspace/pushtime
setclock: Operation not permitted

鉴于命令是以root身份运行的,我很困惑为什么权限会出错,而我在Docker文档中还没有找到任何能解释原因的信息。

编辑:我刚刚意识到,对该错误的更简单演示如下:

root@host:~# sudo docker run -it ubuntu:bionic /bin/bash
root@container:/# date -s '2018-02-01 21:39'
date: cannot set date: Operation not permitted
Thu Feb  1 21:39:00 UTC 2018

1 个答案:

答案 0 :(得分:0)

哈哈,简短的答案是运行容器时需要传递--privileged标志。

来自Docker文档:

  

完整的容器功能(-特权)

     

$ docker run -t -i --rm ubuntu bash

     

root @ bc338942ef20:/#mount -t tmpfs none / mnt

     

mount:权限被拒绝

     

这是行不通的,因为默认情况下,会删除大多数潜在危险的内核功能;包括cap_sys_admin(挂载文件系统所需)。但是,--privileged标志将允许它运行...