非特权 LXC (proxmox) 中的 Debian 12.2。现在已经是当地时间上午 11 点 45 分左右了。早上 5:00,cron 启动了一个脚本:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jan 26633 0.0 0.0 8500 2056 ? S 05:00 0:00 /usr/sbin/CRON -f
我正在使用 pgrep pgrep -f CRON -O 600
,并且我希望 pgrep 返回 PID 26633,因为该进程的历史远远超过 600 秒。但 pgrep 什么也没返回。如果我省略-O
,它会正确返回 PID。
在主机上(即 LXC 之外)执行相同操作,它可以正常工作。
由于 pgrep 使用 procps,所以我查看了那里。
ps -o etime -p $pid
在 LXC 中:(441077225-02:04:48
错误,因为从 5:00 开始,~6:45 过去了)
ps -o etime -p $pid
在主机上:(06:43:29
正确)
这是 procps 中的错误还是与 LXC 有关?
答案1
LXC 安装一个假的/proc/uptime
来模拟容器的正常运行时间而不是主机的正常运行时间,因为该属性没有命名空间。在(根)LXC 容器上:
# findmnt /proc/uptime
TARGET SOURCE FSTYPE OPTIONS
/proc/uptime lxcfs[/proc/uptime] fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other
但是,并没有为每个进程的stat
伪文件做出这样的规定/proc/PID/stat
。
因此,当比较时间时,电流和磁场pgrep
之间存在差异,如下所述/proc/uptime
starttime
/proc/PID/stat
proc(5)
和道具来源:
PIDS_TIME_ELAPSED, // real * derived from stat: (/proc/uptime - start_time) / hertz
由于容器/proc/uptime
是被LXC伪造的(我猜是通过使用主机的/proc/uptime
减去LXC容器的pid 1启动时间),最终结果得到容器的启动时间减去,导致最初为负值(并且在一段时间内,但如果/当它后来变成正数时仍然是错误的),这是意想不到的,因为系统正常运行时间应该大于目标的进程 start_time (可能通过一个因子进行调整)$(getconf CLK_TCK)
)。过程工具无法正确处理这个问题。
我不知道解决方法:如果/proc/uptime
恢复到其主机值,则pgrep -O
或ps -o etime -p
将计算正确的值,但任何使用系统正常运行时间的工具现在都将获取主机的正常运行时间,而不是容器的(伪造的)正常运行时间。