Docker容器环境检测方法总结

某些情况下,需要对当前主机系统运行环境做检测,区分实体机/虚拟机/容器。下面对 Docker Runtime 检测做一下整理总结。又因 Docker 版本等一系列因素,会导致不同的各个检测方式存在差异,因此要从多个维度的检测结果来进行评估。

1. /proc

Linux 内核初始化后最后一步是启动 init 进程,这是系统第一个进程(超级进程),pid 为 1,负责产生其他所有用户进程,在 Docker 中也不例外。但 LXC/Docker 中 /proc/<pid>/cgroup、/proc/<pid>/cpuset 会存在 /lxc/<container-id> 或者 /docker/<container-id> 字段,因此可以通过检测 /proc/1/cgroup 和 /proc/1/cpuset 来对比差异,如:

另外,可以通过 /proc/<pid>/sched 来提取进程 pid 信息,但容器中的进程 pid 跟宿主机(a non-container system)的 pid 存在差异,如:

2. /.dockerenv

Docker 会在容器内部根目录下创建 .dockerenv 文件,如:

3. shell 检测脚本

#!/bin/bash
function determin_docker_runtime()
    # echo "1. cat /proc/1/cgroup | grep '/docker/'"
    cgroup_info=$(cat /proc/1/cgroup | grep '/docker/' | grep -v grep | head -1)
    if [ -n "$cgroup_info" ]; then
        echo "(/proc/1/cgroup)========>find docker tag:$cgroup_info"
    # echo "2. cat /proc/1/cgroup | grep '/docker/'"
    cpuset_info=$(cat /proc/1/cpuset | grep '/docker/' | grep -v grep | head -1)
    if [ -n "$cpuset_info" ]; then
        echo "(/proc/1/cpuset)========>find docker tag:$cpuset_info"
    # echo "3. cat /proc/1/sched | head -1"
    sched_info=$(cat /proc/1/sched | head -1)
    x=$(echo $sched_info | grep '1, #threads: 1' | grep -v grep)
    if [ -z "$x" ]; then
        echo "(/proc/1/sched )========>find differ pid:$sched_info"
    # echo "4. [ -f /.dockerenv ]"