Podman: How to check if a process is running inside podman (OCI) container

Created on 17 Jul 2019  Â·  10Comments  Â·  Source: containers/podman

/kind feature

Description

What is the right way to detect if a process is running inside OCI or podman container? Multiply ways to detect that a process is running in docker container were suggested, including inspecting /proc/1/cgroup. As I don't really understand the contents of /proc/1/cgroup I can not be sure it will work cross-platform.

On Fedora 30 from podman.

~ podman run -it yakshaveinc/snapcraft:core18-edge cat /proc/1/cgroup
11:memory:/user.slice/user-1000.slice/session-3.scope
10:cpu,cpuacct:/
9:devices:/user.slice
8:hugetlb:/
7:pids:/user.slice/user-1000.slice/session-3.scope
6:perf_event:/
5:net_cls,net_prio:/
4:blkio:/
3:cpuset:/
2:freezer:/
1:name=systemd:/user.slice/user-1000.slice/session-3.scope
0::/user.slice/user-1000.slice/session-3.scope

Without podman.

~ cat /proc/1/cgroup                                                    
11:memory:/init.scope
10:cpu,cpuacct:/
9:devices:/init.scope
8:hugetlb:/
7:pids:/init.scope
6:perf_event:/
5:net_cls,net_prio:/
4:blkio:/
3:cpuset:/
2:freezer:/
1:name=systemd:/init.scope
0::/init.scope

Output of podman version:

Version:            1.4.4
RemoteAPI Version:  1
Go Version:         go1.12.6
OS/Arch:            linux/amd64

Most helpful comment

From inside container I haven't found references to /var/lib/containers from /proc/self/mounts. But I found /run/.containerenv documented at https://github.com/containers/libpod/blob/master/docs/podman-run.1.md as an official flag to detect that a program is in a container. Thanks for the pointers.


✗ podman run -it -v $PWD:/src:Z -w /src yakshaveinc/snapcraft:core18 cat /proc/self/mounts | grep container
tmpfs /dev tmpfs rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,size=65536k,mode=755,uid=1000,gid=1000 0 0
devpts /dev/pts devpts rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,noexec,relatime,gid=100004,mode=620,ptmxmode=666 0 0
shm /dev/shm tmpfs rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,nodev,noexec,relatime,size=64000k,uid=1000,gid=1000 0 0
tmpfs /run/.containerenv tmpfs rw,seclabel,nosuid,nodev,relatime,size=786412k,mode=700,uid=1000,gid=1000 0 0
tmpfs /sys/fs/cgroup tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,nodev,noexec,relatime,mode=755,uid=1000,gid=1000 0 0
devpts /dev/console devpts rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,noexec,relatime,gid=100004,mode=620,ptmxmode=666 0 0
tmpfs /proc/acpi tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /proc/scsi tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /sys/firmware tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /sys/fs/selinux tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0

All 10 comments

One pragmatic way is to check the mount point for /, e.g. by checking the content of /proc/PID/mounts. If it refers to a rootfs inside /var/lib/containers/storage, then it should be a podman container.

E.g.:

$ cat /proc/29839/mounts| grep -w "/" 
/dev/sda3 / btrfs rw,relatime,ssd,space_cache,subvolid=24283,subvol=/@/var/lib/containers/storage/btrfs/subvolumes/de3c075de092df2e78eb5c3fd88c942d811cea1de18d86a6fdb4a08a967bfe8b 0

If you need to find out what's the podman container ID, you may need to search for that rootfs path in the runtime. E.g. if you think the OCI runtime is runc:

$ sudo grep -r -l de3c075de /run/runc
/run/runc/362fe56af3e003a487f8d9603540703d3713012f48c89d671c48acdf56c13848/state.json

Once you got the ID, you can inspect it with podman:

$ sudo podman inspect 362fe56af3e003a487f8d9603540703d3713012f48c89d671c48acdf56c13848
````

Or the OCI runtime itself:

$ sudo runc state 362fe56af3e003a487f8d9603540703d3713012f48c89d671c48acdf56c13848
```

I use SELinux to check.
ps -eZ | grep container_t

Tells me processes running in a container, but this does not tell you which container engine launched the container process.

grep container=podman /proc/12642/environ
Binary file /proc/12642/environ matches

Assuming we know the PID on the host, we can make a quick lookup via Podman:

[~]$ podman ps -a --format "{{.ID}}" | while read -a LINE; do podman top $LINE hpid; done | grep -v HPID
25094
25045
24996
24947
24895
24843

The command above prints a list of PIDs of container processes in the host's PID NS.

From inside container I haven't found references to /var/lib/containers from /proc/self/mounts. But I found /run/.containerenv documented at https://github.com/containers/libpod/blob/master/docs/podman-run.1.md as an official flag to detect that a program is in a container. Thanks for the pointers.


✗ podman run -it -v $PWD:/src:Z -w /src yakshaveinc/snapcraft:core18 cat /proc/self/mounts | grep container
tmpfs /dev tmpfs rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,size=65536k,mode=755,uid=1000,gid=1000 0 0
devpts /dev/pts devpts rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,noexec,relatime,gid=100004,mode=620,ptmxmode=666 0 0
shm /dev/shm tmpfs rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,nodev,noexec,relatime,size=64000k,uid=1000,gid=1000 0 0
tmpfs /run/.containerenv tmpfs rw,seclabel,nosuid,nodev,relatime,size=786412k,mode=700,uid=1000,gid=1000 0 0
tmpfs /sys/fs/cgroup tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,nodev,noexec,relatime,mode=755,uid=1000,gid=1000 0 0
devpts /dev/console devpts rw,context="system_u:object_r:container_file_t:s0:c317,c958",nosuid,noexec,relatime,gid=100004,mode=620,ptmxmode=666 0 0
tmpfs /proc/acpi tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /proc/scsi tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /sys/firmware tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0
tmpfs /sys/fs/selinux tmpfs ro,context="system_u:object_r:container_file_t:s0:c317,c958",relatime,uid=1000,gid=1000 0 0

grep container=podman /proc/12642/environ

I see $container set to oci, not podman. podman version 1.7.0.

EDIT: this was on a fedora:31 image

This can be overridden by images, podman run --env, etc

I'm fairly certain that we don't set oci explicitly anywhere in Podman itself.

(Unfortunately, this does mean that it's difficult to rely on the environment variable being set to any specific value - images in particular can override us)

Correct, container=oci, is being set by some Red Hat images, I believe.
Bottom line is checking if container is set, should be valid for thinking you are running inside of a container. What it is set to can vary..

As it was mentioned on https://github.com/cockpit-project/cockpit-container/issues/20 : Merely testing that $container is non-empty or oci is wrong for detecting podman. Docker on RHEL 7 sets container=oci.

We make a guarantee that the container environment variable will be set inside of a Podman container, and that if not overridden by the container or user it will be set to podman. Red Hat images happen to override by default, which is somewhat annoying.

The best check for container=oci being Docker or Podman would be to look for /run/.containerenv (Podman) vs /run/.dockerenv (Docker)

Was this page helpful?
0 / 5 - 0 ratings