shell - script - Cómo verificar si un proceso se está ejecutando dentro de un contenedor acoplable
docker-compose exec (6)
Creé una pequeña secuencia de comandos python. Espero que alguien lo encuentre útil. :-)
#!/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)
[Actualizado1] Tengo un shell que cambiará los parámetros del kernel TCP en algunas funciones, pero ahora necesito hacer que este shell se ejecute en el contenedor Docker, es decir, el shell necesita saber que se está ejecutando dentro de un contenedor y detener la configuración del kernel.
Ahora no estoy seguro de cómo lograrlo, aquí está el contenido de /proc/self/cgroup
dentro del contenedor:
9:hugetlb:/
8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/
Cualquier indicador anterior ¿puedo usar para averiguar si este proceso se está ejecutando dentro de un contenedor?
[Actualizado2]: También he notado Determinar si un proceso se ejecuta dentro de lxc / Docker , pero parece que no funciona en este caso, el contenido en /proc/1/cgroup
de mi contenedor es:
8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/
No / lxc / containerid
Docker crea .dockerenv
y ( eliminados en v1.11 ) en la parte superior del árbol de directorios del contenedor, por lo que es posible que desee comprobar si existen. .dockerinit
Algo como esto debería funcionar.
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I''m inside matrix ;(";
else
echo "I''m living in real world!";
fi
La solución de Thomas como código:
running_in_docker() {
(awk -F/ ''$2 == "docker"'' /proc/self/cgroup | read non_empty_input)
}
Nota
La read
con una variable ficticia es una expresión simple para ¿Esto produce alguna salida? . Es un método compacto para convertir un grep
o awk
posiblemente detallado en una prueba de un patrón.
Necesitábamos excluir procesos que se ejecutan en contenedores, pero en lugar de buscar sólo docker cgroups, decidimos comparar /proc/<pid>/ns/pid
al sistema init en /proc/1/ns/pid
. Ejemplo:
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
O en nuestro caso, queríamos un trazador de líneas que genere un error si el proceso NO está en un contenedor
bash -c "test -h /proc/4129/ns/pid && test $(readlink /proc/4129/ns/pid) != $(readlink /proc/1/ns/pid)"
que podemos ejecutar desde otro proceso y si el código de salida es cero, entonces el PID especificado se ejecuta en un espacio de nombres diferente.
Para verificar dentro de un contenedor Docker si está dentro de un contenedor Docker o no se puede hacer a través de /proc/1/cgroup
. Como esta publicación sugiere que puede hacer lo siguiente:
Fuera de un contenedor de acoplador, todas las entradas en /proc/1/cgroup
finalizan en /
como puede ver aquí:
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:/
Dentro de un contenedor Docker, algunos de los grupos de control pertenecerán a Docker (o 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:/
Usamos el programa sched (/ proc / $ PID / sched) para extraer el PID del proceso. El PID del proceso dentro del contenedor diferirá, entonces es PID en el host (un sistema que no es contenedor).
Por ejemplo, la salida de / proc / 1 / sched 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 diferenciar si estás en un contenedor o no. por ejemplo, puedes hacer:
if [[ ! $(cat /proc/1/sched | head -n 1 | grep init) ]]; then {
echo in docker
} else {
echo not in docker
} fi