¿Cómo puedo sustituir lsof dentro de un Docker (nativo, no basado en LXC)

16

Estoy algo desconcertado de que dentro de un contenedor Docker lsof -ino produzca ningún resultado.

Ejemplo (todos los comandos / resultados desde el interior del contenedor):

[1] root@ec016481cf5f:/# lsof -i
[1] root@ec016481cf5f:/# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -

Tenga en cuenta también cómo no se muestra ningún PID o nombre de programa netstat. fusertambién da una salida algo confusa y tampoco puede identificar los PID.

¿Alguien puede aclarar esto?

  • ¿Cómo puedo sustituir lsof -i(para ver también el nombre del proceso )
  • ¿Por qué la producción de netstatlisiado también?

NB: el contenedor se ejecuta con "ExecDriver": "native-0.1", que es la capa de ejecución propia de Docker, no LXC.


[1] root@ec016481cf5f:/# fuser -a4n tcp 22
Cannot stat file /proc/1/fd/0: Permission denied
Cannot stat file /proc/1/fd/1: Permission denied
Cannot stat file /proc/1/fd/2: Permission denied
Cannot stat file /proc/1/fd/3: Permission denied
Cannot stat file /proc/1/fd/255: Permission denied
Cannot stat file /proc/6377/fd/0: Permission denied
Cannot stat file /proc/6377/fd/1: Permission denied
Cannot stat file /proc/6377/fd/2: Permission denied
Cannot stat file /proc/6377/fd/3: Permission denied
Cannot stat file /proc/6377/fd/4: Permission denied
22/tcp:

(No estoy obsesionado con el Permission denied, porque eso representa cifras. Lo que me confunde es la lista vacía de PID después 22/tcp).


# lsof|awk '$1 ~ /^sshd/ && $3 ~ /root/ {print}'
sshd    6377      root  cwd   unknown                        /proc/6377/cwd (readlink: Permission denied)
sshd    6377      root  rtd   unknown                        /proc/6377/root (readlink: Permission denied)
sshd    6377      root  txt   unknown                        /proc/6377/exe (readlink: Permission denied)
sshd    6377      root    0   unknown                        /proc/6377/fd/0 (readlink: Permission denied)
sshd    6377      root    1   unknown                        /proc/6377/fd/1 (readlink: Permission denied)
sshd    6377      root    2   unknown                        /proc/6377/fd/2 (readlink: Permission denied)
sshd    6377      root    3   unknown                        /proc/6377/fd/3 (readlink: Permission denied)
sshd    6377      root    4   unknown                        /proc/6377/fd/4 (readlink: Permission denied)
sshd    6442      root  cwd   unknown                        /proc/6442/cwd (readlink: Permission denied)
sshd    6442      root  rtd   unknown                        /proc/6442/root (readlink: Permission denied)
sshd    6442      root  txt   unknown                        /proc/6442/exe (readlink: Permission denied)
sshd    6442      root    0   unknown                        /proc/6442/fd/0 (readlink: Permission denied)
sshd    6442      root    1   unknown                        /proc/6442/fd/1 (readlink: Permission denied)
sshd    6442      root    2   unknown                        /proc/6442/fd/2 (readlink: Permission denied)
sshd    6442      root    3   unknown                        /proc/6442/fd/3 (readlink: Permission denied)
sshd    6442      root    4   unknown                        /proc/6442/fd/4 (readlink: Permission denied)
sshd    6442      root    5   unknown                        /proc/6442/fd/5 (readlink: Permission denied)

Hay más resultados para el usuario conectado, que también se identifica correctamente, pero eso es todo. Aparentemente es imposible discernir de qué tipo ( lsof -ilímites a los enchufes de Internet) es un cierto "objeto".

0xC0000022L
fuente
¿Qué hace un lsofinforme? ¿Lo mismo?
slm
@slm: ¡brillante consulta! No lo mantiene vacío. En su lugar, muestra una gran cantidad de sshdlíneas (también relacionadas), algunas de las cuales podrían ser sockets TCP, como TYPE unknown. Peculiar. Anexando el resultado a mi pregunta.
0xC0000022L
Si lo ejecuta strace -s 2000 -o lsof.log lsof -i, es probable que le brinde información adicional sobre lo que se está bloqueando.
slm
1
@slm: buen punto. Gracias por recordarme. Aunque lo haré mañana. También es posible que straceesté limitado en el contenedor. Cosas nuevas y emocionantes para aprender. Gracias por rebotar idea. Sin embargo, debe golpear la cama.
0xC0000022L
FYI: Esto también rompe netstat -lp. Definitivamente es causada por el apparmor.
Alan Robertson

Respuestas:

7

(NOTA: no está claro en la pregunta de cómo el autor de la pregunta está entrando en el contenedor ventana acoplable que estoy. Asumiendo que docker exec -it CONTAINER bash se utilizó.)

Tuve este problema al usar una imagen de docker basada en la centos:7versión de docker 1.9.0y para superar esto, simplemente ejecuté:

docker exec --privileged -it CONTAINER bash

Tenga en cuenta la inclusión de --privileged.

Mi comprensión ingenua de la razón por la que esto es necesario: parece que Docker hace un esfuerzo para que el contenedor sea más "seguro", como se documenta aquí .

erik.weathers
fuente
4

Ja, la trama se complica. Si alguien tiene una mejor respuesta, escríbala y la aceptaré, si es aceptable. Pero aquí la razón aparente. Qué negligente de mi parte ignorar los archivos de registro en el host :

Jun 12 01:29:46 hostmachine kernel: [140235.718807] audit_printk_skb: 183 callbacks suppressed
Jun 12 01:29:46 hostmachine kernel: [140235.718810] type=1400 audit(1402536586.521:477): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="trace" denied_mask="trace" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718860] type=1400 audit(1402536586.521:478): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718886] type=1400 audit(1402536586.521:479): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718899] type=1400 audit(1402536586.521:480): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718921] type=1400 audit(1402536586.521:481): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718954] type=1400 audit(1402536586.521:482): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719001] type=1400 audit(1402536586.521:483): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719043] type=1400 audit(1402536586.521:484): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719086] type=1400 audit(1402536586.521:485): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719126] type=1400 audit(1402536586.521:486): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"

Por lo tanto, apaparmor parece ser el culpable, aunque tendré que descubrir cómo convencerlo para que permita esto sin comprometer la seguridad del host / contenedor o para ver si es posible sin comprometer la seguridad.

0xC0000022L
fuente
2
Descrito en el número de Docker # 7276
Anthony O.
3

Otra posibilidad, esta vez con una configuración de seguridad más precisa: otorgue el privilegio SYS_PTRACE al contenedor acoplable:

docker run --cap-add=SYS_PTRACE ...
peterh - Restablece a Monica
fuente
1
En caso de que alguien se pregunte por qué lsofnecesita CAP_SYS_PTRACE: es necesario leer /proc/*/stat. See ptrace (2)
David Röthlisberger
2

También he encontrado este problema. El problema se fue después de que deshabilité apparmoren docker:

$ sudo aa-complain <docker apparmor profile name, "docker-default" on ubuntu>

URL de referencia: https://help.ubuntu.com/community/AppArmor

menghan
fuente
3
Es posible que desee considerar agregar más explicaciones a esta respuesta (por ejemplo, qué aa-complainhace o alguna documentación que respalde esta solución).
HalosGhost
@HalosGhost Lo siento, no estoy muy familiarizado apparmor, simplemente busqué en Google y encontré la manera de desactivarlo. En otras palabras, no sé por qué funciona o por qué no funcionó. Mi sistema operativo host es Ubuntu 14.04, así que busqué "ubuntu apparmor" y encontré help.ubuntu.com/community/AppArmor . Espero que esto sea útil para ti.
menghan
2
No tengo este problema; Mi preocupación era la calidad de su respuesta y lo útil (e informativo) que sería para el OP.
HalosGhost
@HalosGhost Gracias por su ayuda, reedito mi respuesta.
menghan
En ubuntu 14.04 el comando era sudo aa-complain /etc/apparmor.d/docker. Básicamente, desactiva la armadura de la aplicación para el proceso de Docker, lo que significa que Docker puede leer cualquier archivo en el sistema. Anteriormente, solo podía funcionar con archivos permitidos en el perfil. Una mejor solución podría ser cambiar las reglas de armadura de la aplicación que permitirían el acceso a los archivos / proc / pid / fd.
Martins Balodis