¿Cómo determinar si un proceso se ejecuta dentro de lxc/Docker?
Pregunta
¿Hay alguna forma de determinar si un proceso (script) se ejecuta dentro de un contenedor lxc (~ tiempo de ejecución de Docker)?Sé que algunos programas pueden detectar si se ejecutan dentro de una máquina virtual. ¿Hay algo similar disponible para lxc/docker?
Solución
La forma más confiable es comprobar /proc/1/cgroup
.Le indicará los grupos de control del proceso de inicio y cuándo está no en un contenedor, eso será /
para todas las jerarquías.Cuando estás adentro un contenedor, verá el nombre del punto de anclaje.Con los contenedores LXC/Docker, será algo así como /lxc/<containerid>
o /docker/<containerid>
respectivamente.
Otros consejos
Docker crea un archivo .dockerenv
en la raíz del árbol de directorios dentro del contenedor.
Puede ejecutar este script para verificar
#!/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 guión bash: /bin/running-in-container
y en realidad puede devolver el tipo de contenedor en el que se ha invocado. Podría ser útil.
Sin embargo, no sé sobre otras grandes distribuciones.
En un nuevo sistema Ubuntu 16.04, New SystemD & LXC 2.0
sudo grep -qa container=lxc /proc/1/environ
Una forma concisa de comprobar si hay Docker en un script de bash es:
#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
echo I'm running on docker.
fi
Función práctica de Python para verificar si se ejecuta en DUCHER:
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()
Utilizamos el PROCE PROCE (/ PID / $ PID / PID) de PROC para extraer el PID del proceso.El PID del proceso dentro del contenedor diferirá entonces, es PID en el host (un sistema no contenedor).
Por ejemplo, la salida / proc / 1 / SCRIGHT en un contenedor devolverá:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
mientras está en un host no contenedor:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
Esto ayuda a diferenciarse si está en un contenedor o no.
La forma más sencilla sería comprobar el medio ambiente.Si tienes el container=lxc
variable, estás dentro de un contenedor.
De lo contrario, si eres root, puedes intentar realizar mknod
o mount
operación, si falla, lo más probable es que se encuentre en un contenedor con capacidades descartadas.
Revisar 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)
Mi respuesta solo se aplica para node.js procesos , pero puede ser relevante para algunos visitantes que tropiezan con esta pregunta en busca de una respuesta específica de nodo.js.
Tuve el mismo problema y confiando en /proc/self/cgroup
I Creé un paquete NPM por únicamente este propósito: para detectar si un proceso de nodo.js se ejecuta dentro de un contenedor de DUCHER o NO.
The Módulo de NPM contenedorizado te ayudará en nodo.js.Actualmente no está probado en io.js, pero también puede funcionar allí también.
Docker evoluciona día a día, por lo que no podemos decir con certeza si seguirá .dockerenv .dockerinit
en el futuro.
En la mayoría de las versiones de Linux. init
es el primer proceso en comenzar.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
Building on the accepted answer that tests /proc/*/cgroup
..
awk -F: '$3 ~ /^\/$/ {c=1} END{ exit c }' /proc/self/cgroup
So for use in a script or so, a test could be constructed this way.
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
This SO Q&A: "Find out if the OS is running in a virtual environment"; though not the same as the OP's question, it does indeed answer common cases of finding which container you're in (if at all).
In particular, install and read the code of this bash script which seems to work pretty well:
virt-what :
sudo apt install virt-what
I have translated JJC's answer into 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
Maybe this do the trick:
if [ -z $(docker ps -q) ]; then
echo "There is not process currently running"
else
echo "There are processes running"
fi