Cómo determinar si un proceso se ejecuta dentro de lxc/Docker?

Hay alguna forma para determinar si un proceso (secuencia de comandos) se ejecuta dentro de un lxc contenedor (~ ventana acoplable tiempo de ejecución)? Sé que algunos programas son capaces de detectar si se ejecuta en una máquina virtual, es algo similar disponible para lxc/ventana acoplable?

  • Puede parecer pedante, pero sería mejor para reformular su pregunta para describir un problema y la pregunta de cómo resolverlo, sin que, la pregunta se levanta una mayor probabilidad de ser cerrado. En muchos casos es difícil hacer ese cambio, pero en el tuyo no iba a ser duro simplemente para decirlo en otras palabras, si lo desea.
  • hay una interesante respuesta a la hora de emitir este comando, mientras que en el interior de un contenedor : el tiempo de actividad
InformationsquelleAutor Mate Varga | 2013-11-15

14 Kommentare

  1. 155

    La forma más fiable es comprobar /proc/1/cgroup. Se le dirá que los grupos de control del proceso init, y cuando se no en un contenedor, que será / para todas las jerarquías. Cuando se dentro de un contenedor, podrá ver el nombre del punto de anclaje. Con LXC/ventana acoplable contenedores, va a ser algo así como /lxc/<containerid> o /docker/<containerid> respectivamente.

    • ventana acoplable ahora utiliza docker en lugar de lxc en esos caminos
    • No funciona para lxd/lxc contenedores, pero stackoverflow.com/a/20010626/170230 hace.
    • Con las versiones posteriores de systemd parece que no se puede confiar en el proceso 1 el uso de / para todos los cgroups; en mi Debian 9 (sistema de systemd 232) sólo tres de los diez cgroups (3:cpuset, 4:perf_event y 7:freezer) están en la raíz; el resto están bajo /init.scope. Dicho esto, creo que la búsqueda de ese archivo :/docker/ es, probablemente, el más fiable de la heurística en el momento.
    • grep 'docker\|lxc' /proc/1/cgroup me funciona en la ventana acoplable 18.09.
    • He aquí una más estrecha (extended) regex que supone un sha256 hash en el basename posición: grep -Eq '/(lxc|docker)/[[:xdigit:]]{64}' /proc/1/cgroup
    • La combinación de dos respuestas para una mayor robustez: if [[ -f /.dockerenv ]] || grep -Eq '(lxc|docker)' /proc/1/cgroup; then echo True; else echo False; fi (Aunque no sé si cgroup archivo está en todos los linux, es posible Que se quieren agregar comprobaciones extra)
    • No funciona para mí. Host Ubuntu 19.04, invitado Ubuntu 18.04 utilizando LXC privilegiada contenedor. /proc/1/cgroup NO contiene el lxc cadena.

  2. 150

    Ventana acoplable crea un .dockerenv archivo en la raíz del árbol de directorios dentro del contenedor.
    Puede ejecutar esta secuencia de comandos para comprobar

    #!/bin/bash
    if [ -f /.dockerenv ]; then
        echo "I'm inside matrix ;(";
    else
        echo "I'm living in real world!";
    fi

    MÁS:
    Ubuntu, en realidad tiene un script de bash: /bin/running-in-container y que en realidad se puede devolver el tipo de envase en que se ha invocado en. Podría ser útil.
    No sé acerca de otras de las principales distros, aunque.

    • Nota importante: el .dockerinit archivo sido eliminado en las versiones recientes de la ventana acoplable, por lo que este método no funciona más. A partir de este escrito, el .dockerenv archivo aún se mantienen alrededor, así que tal vez que podría ser utilizado en su lugar.
    • En Debian /bin/running-in-container es proporcionada por upstart. Con la transición a systemd es posible que desaparezca. Espero que no suene muy útil!
    • «en la parte superior del árbol de directorios», ¿qué significa eso? donde es eso?
    • Otros han señalado que la comprobación de .dockerenv es no se recomienda
    • Para mí .dockerenv es más como el borde del mundo «piso 13».
    • Nota: la prueba de .dockerenv sólo funciona si el tiempo de ejecución es la ventana acoplable demonio. Si usted está usando podman o algo falla.

  3. 19

    Un nuevo ubuntu 16.04 sistema, y el nuevo systemd & lxc 2.0

    sudo grep -qa container=lxc /proc/1/environ
  4. 15

    Una manera concisa para comprobar la ventana acoplable en un script de bash es:

    #!/bin/bash
    if grep docker /proc/1/cgroup -qa; then
       echo I'm running on docker.
    fi
  5. 13

    Práctico de la función de Python para comprobar si se ejecuta en la ventana acoplable:

    def in_docker():
        """ Returns: True if running in a Docker container, else False """
        with open('/proc/1/cgroup', 'rt') as ifh:
            return 'docker' in ifh.read()
    • Nota Importante! Esto no parece funcionar cuando el contenedor está ejecutando en kubernetes. En su lugar, reemplace la última línea con ‘kubepod’ en lugar de ‘ventana acoplable’. (O, poner en una «o» la afirmación de que los controles de ambos ;))
    • Es kubepods supongo.
  6. 9

    Utilizamos el proc de sched (/proc/$PID/sched) para extraer el PID del proceso. El proceso del PID en el interior del contenedor se diferencian entonces es el PID en el host (un no-sistema de contenedor).

    Por ejemplo, la salida de /proc/1/sched en un contenedor
    regresará:

    [email protected]:~# cat /proc/1/sched | head -n 1
    bash (5276, #threads: 1)

    Mientras que en un no-contenedor de host:

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

    Esto ayuda a diferenciar si está en un recipiente o no.

    • Dependiendo del sistema operativo, «init» puede ser que necesite ser reemplazada por la de «systemd». Más información sobre systemd aquí.
    • Sí, pero el punto no era el nombre del proceso init, el punto era el número de proceso.
    • Esto parece sólo trabajar en la ventana acoplable. En un LXC contenedor Es volver Systemd PID 1
  7. 7

    La manera más fácil sería para comprobar el medio ambiente. Si usted tiene el container=lxc variable, que están dentro de un contenedor.

    De lo contrario, si eres root, puedes probar a realizar mknod o mount operación, si falla, lo más probable es que en un recipiente con caer capacidades.

    • Este uno trabaja no sólo para la ventana acoplable (yo no comprobar que), pero lo más importante para lxd/lxc contenedores (comprobado), donde /proc/1/cgroup no permite detectar que.
    • No trabajo para la ventana acoplable. La variable no está configurado.
    • puede editar la respuesta con el código de lugar de pseudocódigo? «contenedor=lxc» ?no es nada adecuado. ¿te refieres a algo como si [[ «lxc» = «$contenedor» ]] ?
    • Quiero decir…es raro, generalmente env variables en mayúsculas, así que buscando algo de precisión aquí
    • docker run alpine env no da nada que se parece a esa variable
  8. 5

    Comprobar todas las soluciones anteriores en Python:

    import os
    import subprocess
    
    def in_container():
        # type: () -> bool
        """ Determines if we're running in an lxc/docker container. """
        out = subprocess.check_output('cat /proc/1/sched', shell=True)
        out = out.decode('utf-8').lower()
        checks = [
            'docker' in out,
            '/lxc/' in out,
            out.split()[0] not in ('systemd', 'init',),
            os.path.exists('/.dockerenv'),
            os.path.exists('/.dockerinit'),
            os.getenv('container', None) is not None
        ]
        return any(checks)
    • Esto no funciona para mí en Mac basado ventana acoplable contenedor. Devuelve un vacío. Ventana acoplable versión 2.1.0.1 (37199).
    • Éste lo hizo: def is_non_docker(): return os.path.exists('/proc/1/cgroup') como por la aceptó responder aquí, stackoverflow.com/questions/20010199/…
  9. 3

    Mi respuesta sólo se aplica para Node.js los procesos de pero puede ser relevante para algunos de los visitantes que tropiezan a esta pregunta buscando un Node.js respuesta específica.

    Yo tenía el mismo problema y confiar en /proc/self/cgroup he creado un mecanismo nacional de prevención paquete sólo para este propósito — para detectar si un Node.js el proceso se ejecuta dentro de una ventana acoplable contenedor o no.

    La los contenedores de mecanismo nacional de prevención módulo le ayudará a cabo en Node.js. Actualmente no es probado en Io.js pero puede trabajar allí.

    • Gracias por este módulo, que parece ser un par de abrir correcciones de pendiente – se sigue manteniendo esta?
  10. 2

    Ventana acoplable evoluciona día a día, así que no podemos decir con certeza si van a seguir .dockerenv .dockerinit en el futuro.

    En la mayoría de los sabores de Linux init es el primer proceso de inicio. Pero en el caso de los contenedores, esto no es cierto.

    #!/bin/bash
    if ps -p1|grep -q init;then  
      echo "non-docker" 
    else 
      echo "docker" 
    fi
    • LXC/ventana acoplable no tanto. Lo que es un comentario gracioso.
    • No funciona en centos 7 así. Cuando corro en mi host de la máquina dice ventana acoplable. Se parece a systemd se ejecuta como proceso de identificación 1
    • Esto se debe ejecutar en el interior del contenedor. La intención es averiguar si está dentro de un contenedor docker o no.
    • El problema es que se supone que el normal PID uno es init, lo cual no es cierto en systemd o launchd sistemas basados en…
    • launchd, advenedizo, Solaris SMF, systemd, Sys V init estilo, estilo BSD init (estos dos y algunos otros podrían llamar a su PID 1 init aunque), OpenRC, initng runit. Ver aquí. La mayoría de los modernos sistemas basados en Linux sería utilizar systemd, algunos antiguos, upstart…. Todos los modernos sistemas OS X usaría launchd
  11. 1

    Edificio sobre la aceptada respuesta que las pruebas de /proc/*/cgroup ..

    awk -F: '$3 ~ /^\/$/{c=1} END{ exit c }' /proc/self/cgroup

    Para utilizar en un script o algo así, una prueba puede ser construido de esta manera.

    is_running_in_container() {
      awk -F: '$3 ~ /^\/$/{ c=1 } END { exit c }' /proc/self/cgroup
    }
    
    if is_running_in_container; then
      echo "Aye!! I'm in a container"
    else 
      echo "Nay!! I'm not in a container"
    fi
  12. 0

    Esto PARA Q&A: «Averiguar si el sistema operativo se está ejecutando en un entorno virtual» que, aunque no es el mismo que el OP pregunta, en efecto, la respuesta común de los casos de hallazgo de que el contenedor en que te encuentras (si en absoluto).

    En particular, instalar y leer el código de este script en bash que parece que funciona bastante bien:

    virt-¿qué :

    sudo apt install virt-what
    • No funciona con virt-what la versión 1.14-1 en Ubuntu 16.04. Necesita revisión.
  13. 0

    He traducido JJC la respuesta en ruby

    def in_docker
      File.open('/proc/1/cgroup', 'rt') do |f|
        contents = f.read
        return contents =~ /docker/i || contents =~ /kubepod/i
      end
    rescue StandardError => e
      p 'Local development'
      p e
      false
    end
  14. -4

    Tal vez esto hacer el truco:

    if [ -z $(docker ps -q) ]; then
        echo "There is not process currently running"
    else
        echo "There are processes running"
    fi
    • No docker binario está disponible desde el interior del contenedor, obviamente.
    • Umm, esto fracasaría en situaciones (por ejemplo, gitlab ventana acoplable en la ventana acoplable) donde el control de contenedor ha docker y el acceso a los hosts’ ventana acoplable zócalo.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea