判断一个 Linux 进程是否运行在容器Docker、K8s、containerd 等里最可靠的是看cgroup 路径、PID 命名空间、根目录 / 挂载信息。检查 cgroup容器进程的/proc/pid/cgroup会包含容器运行时标识Docker/docker/、/docker/容器IDKubernetes/kubepods/、/kubepods.slice/containerd / cri-o/kubepods/、/cri-containerd-、/crio-用法# 检查当前进程 cat /proc/self/cgroup # 检查指定 PID如 1234 cat /proc/1234/cgroup判断出现docker、kubepods、cri-containerd、lxc→在容器里只有/、/user.slice、/system.slice→宿主机进程检查 PID 命名空间判断是否独立 PID 空间容器会创建独立 PID namespace宿主机 initPID1的 namespace inodestat /proc/1/ns/pid目标进程 namespace inodestat /proc/pid/ns/pid用法# 对比当前进程与宿主机 init 的 PID ns [ $(stat -c %i /proc/self/ns/pid) $(stat -c %i /proc/1/ns/pid) ] \ echo 宿主进程 || echo 容器进程 # 检查指定 PID 1234 [ $(stat -c %i /proc/1234/ns/pid) $(stat -c %i /proc/1/ns/pid) ] \ echo 宿主进程 || echo 容器进程判断inode相同→ 同属宿主 PID 命名空间 →宿主进程inode不同→容器进程PID 命名空间 inode 不一样 ≠ 一定在容器容器只是创建新 PID NS 的场景之一很多非容器场景也会独立新建 PID 命名空间这是关键误区。为什么 PID NS 不同但不是容器Linux 原生就支持手动 / 程序调用unshare()/clone(CLONE_NEWPID)独立创建 PID 命名空间和 Docker/containerd 无关。1. 常见非容器、独立 PID NS 场景systemd 私有进程、systemd 服务隔离systemd 很多单元会默认开启PrivatePIDyes进程拥有独立 PID NS宿主机 PID 1 ns 不一样但完全不是容器。手动 unshare 命令创建隔离环境unshare --pid --mount /bin/bash新建独立 PID NS无容器运行时、无 cgroup 容器标记、无 overlay 挂载纯原生隔离。自研隔离程序、沙箱、合规隔离工具安全审计、轻量沙箱、权限隔离程序只用到CLONE_NEWPID不使用容器镜像 / 运行时。LXC/LXD 轻量虚拟机 / 系统容器属于系统级隔离和 Docker 应用容器形态不同很多场景业务上不视作 “容器”。嵌套宿主机进程、部分虚拟化宿主代理进程云厂商宿主机内部代理独立 NS 做隔离不属于业务容器。区分「单纯 PID NS 隔离」和「完整容器」标准容器Docker/K8s必备组合满足多项隔离叠加独立PID NS独立Mount NSrootfs 隔离、overlay2/aufs 挂载独立UTS/IPC/Net/User NScgroup 归属容器切片docker/kubepods/cri-containerd根文件系统被 chroot/overlay 隔离单纯 PID NS 隔离非容器只满足仅PID NS 不同Mount NS、Net NS、UTS 完全和宿主机一致cgroup 是宿主机system.slice/user.slice无容器专属挂载、无 chroot 隔离精准判断排除「假容器」只 PID NS 不同步骤 1PID NS 不同只是前置条件不能作为依据步骤 2叠加多维度校验缺一才判定为容器1. 检查 Mount 命名空间核心# 对比进程与宿主机1号进程 mount ns inode ls -i /proc/1/ns/mount ls -i /proc/$PID/ns/mountmount ns inode 相同→ 一定不是容器mount ns 不同才需要继续判断2. 检查 Cgroup最强容器标识cat /proc/$PID/cgroup无docker/kubepods/crio/cri-containerd/lxc→ 排除容器3. 检查根目录是否隔离ls -ld /proc/$PID/root如果/proc/$PID/root就是宿主机真实根目录无 overlay 层 → 非容器4. 检查网络 / UTS 命名空间ls -i /proc/$PID/ns/net ls -i /proc/1/ns/net网络 NS 一致基本可以判定非容器检查根目录与挂载/proc/pid/root、/proc/pid/mountinfo容器有独立根文件系统与挂载表# 看根目录是否指向容器层 ls -ld /proc/1234/root # 看挂载信息是否有 overlay2 / docker / kubepods grep -E overlay|docker|kubepods /proc/1234/mountinfo最终精准判断脚本逻辑if PID_NS ! 宿主机1号进程 MOUNT_NS ! 宿主机1号进程 cgroup 包含容器标识(docker/kubepods/cri) 存在容器联合挂载(overlay2) then 判定为容器 else 仅单独PID隔离 / 非容器环境 fi从宿主机反查PID 属于哪个容器# Docker docker ps -q | xargs docker inspect --format {{.State.Pid}} {{.Id}} {{.Name}} | grep PID # containerd / crictl (K8s) crictl ps -q | xargs crictl inspect --output go-template \ --template {{.info.pid}} {{.status.id}} {{.status.metadata.name}} | grep PID常见边界与例外systemd 容器 / 轻量隔离可能只有 namespace 隔离、cgroup 不明显 → 以PID ns为准特权容器privileged依然是容器进程只是权限放开cgroup v2路径格式不同但仍含docker/kubepods关键字嵌套容器多层 namespace上述方法依然有效总结PID 命名空间是最小隔离单元不是容器专属只有多 Namespace 隔离 cgroup 容器分组 根文件系统隔离同时满足才是真正的容器生产环境判断容器禁止只用 PID NS 对比必须结合mount ns cgroup 挂载信息组合校验。