How to check if a process is running inside docker container

后端 未结 8 1233
逝去的感伤
逝去的感伤 2020-11-30 23:08

[Updated1] I have a shell which will change TCP kernel parameters in some functions, but now I need to make this shell run in Docker container, that means, the shell need to

相关标签:
8条回答
  • 2020-11-30 23:22

    Based on Dan Walsh's comment about using SELinux ps -eZ | grep container_t, but without requiring ps to be installed:

    $ podman run --rm fedora:31 cat /proc/1/attr/current
    system_u:system_r:container_t:s0:c56,c299
    $ podman run --rm alpine cat /proc/1/attr/current
    system_u:system_r:container_t:s0:c558,c813
    $ docker run --rm fedora:31 cat /proc/1/attr/current
    system_u:system_r:container_t:s0:c8,c583
    $ cat /proc/1/attr/current
    system_u:system_r:init_t:s0
    

    This just tells you you're running in a container, but not which runtime.

    Didn't check other container runtimes but https://opensource.com/article/18/2/understanding-selinux-labels-container-runtimes provides more info and suggests this is widely used, might also work for rkt and lxc?

    0 讨论(0)
  • 2020-11-30 23:23

    To check inside a Docker container if you are inside a Docker container or not can be done via /proc/1/cgroup. As this post suggests you can to the following:

    Outside a docker container all entries in /proc/1/cgroup end on / as you can see here:

    vagrant@ubuntu-13:~$ cat /proc/1/cgroup
    11:name=systemd:/
    10:hugetlb:/
    9:perf_event:/
    8:blkio:/
    7:freezer:/
    6:devices:/
    5:memory:/
    4:cpuacct:/
    3:cpu:/
    2:cpuset:/
    

    Inside a Docker container some of the control groups will belong to Docker (or LXC):

    vagrant@ubuntu-13:~$ docker run busybox cat /proc/1/cgroup
    11:name=systemd:/
    10:hugetlb:/
    9:perf_event:/
    8:blkio:/
    7:freezer:/
    6:devices:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
    5:memory:/
    4:cpuacct:/
    3:cpu:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
    2:cpuset:/
    
    0 讨论(0)
  • 2020-11-30 23:28

    We needed to exclude processes running in containers, but instead of checking for just docker cgroups we decided to compare /proc/<pid>/ns/pid to the init system at /proc/1/ns/pid. Example:

    pid=$(ps ax | grep "[r]edis-server \*:6379" | awk '{print $1}')
    if [ $(readlink "/proc/$pid/ns/pid") == $(readlink /proc/1/ns/pid) ]; then
       echo "pid $pid is the same namespace as init system"
    else
       echo "pid $pid is in a different namespace as init system"
    fi
    

    Or in our case we wanted a one liner that generates an error if the process is NOT in a container

    bash -c "test -h /proc/4129/ns/pid && test $(readlink /proc/4129/ns/pid) != $(readlink /proc/1/ns/pid)"
    

    which we can execute from another process and if the exit code is zero then the specified PID is running in a different namespace.

    0 讨论(0)
  • 2020-11-30 23:29

    I've created a small python script. Hope someone finds it useful. :-)

    #!/usr/bin/env python3
    #@author Jorge III Altamirano Astorga 2018
    import re
    import math
    
    total = None
    meminfo = open('/proc/meminfo', 'r')
    for line in meminfo:
        line = line.strip()
        if "MemTotal:" in line:
            line = re.sub("[^0-9]*", "", line)
            total = int(line)
    meminfo.close()
    print("Total memory: %d kB"%total)
    
    procinfo = open('/proc/self/cgroup', 'r')
    for line in procinfo: 
        line = line.strip()
        if re.match('.{1,5}:name=systemd:', line):
            dockerd = "/sys/fs/cgroup/memory" + \
                re.sub("^.{1,5}:name=systemd:", "", line) + \
                "/memory.stat"
            #print(dockerd)
            memstat = open(dockerd, 'r')
            for memline in memstat:
                memline = memline.strip()
                if re.match("hierarchical_memory_limit", memline):
                    memline = re.sub("[^0-9]*", \
                        "", memline)  
                    total = math.floor(int(memline) / 2**10)
            memstat.close()
    procinfo.close()
    print("Total available memory to the container: %d kB"%total)
    
    0 讨论(0)
  • 2020-11-30 23:33

    Docker creates .dockerenv and .dockerinit (removed in v1.11) files at the top of the container's directory tree so you might want to check if those exist.

    Something like this should work.

    #!/bin/bash
    if [ -f /.dockerenv ]; then
        echo "I'm inside matrix ;(";
    else
        echo "I'm living in real world!";
    fi
    
    0 讨论(0)
  • 2020-11-30 23:35

    We use the proc's sched (/proc/$PID/sched) to extract the PID of the process. The process's PID inside the container will differ then it's PID on the host (a non-container system).

    For example, the output of /proc/1/sched on a container will return:

    root@33044d65037c:~# cat /proc/1/sched | head -n 1
    bash (5276, #threads: 1)
    

    While on a non-container host:

    $ cat /proc/1/sched  | head -n 1
    init (1, #threads: 1)
    

    This helps to differentiate if you are in a container or not. eg you can do:

    if [[ ! $(cat /proc/1/sched | head -n 1 | grep init) ]]; then {
        echo in docker
    } else {
        echo not in docker
    } fi
    
    0 讨论(0)
提交回复
热议问题