Cómo puedo montar un private / proc dentro de un espacio de nombres dentro de un contenedor docker?

Tengo la necesidad de crear espacios de nombres dentro de un contenedor Docker. Y como parte de esto, necesitaré montar un /proc privado para el espacio de nombres interno. Me doy cuenta de que tendré que ejecutar el contenedor con ciertos privilegios para que esto suceda, pero preferiría habilitar el conjunto más mínimo.

Esto funciona:

$ sudo docker run --privileged --security-opt=seccomp=unconfined \ -it fedora:rawhide /usr/bin/unshare -Ufmp -r \ /bin/sh -c 'mount -t proc proc /proc'

Esto no:

$ sudo docker run --cap-add=sys_admin --security-opt=seccomp=unconfined \  -it fedora:rawhide /usr/bin/unshare -Ufmp -r \   /bin/sh -c 'mount -t proc proc /proc'mount: /proc: cannot mount proc read-only.

Por lo tanto, simplemente desactive los filtros seccomp y agregue CAP_SYS_ADMIN no es suficiente. Lo ser ¿suficiente?

Actualizar: Selinux es parte del problema. Si desactiva la aplicación de Selinux globalmente, funciona. Pero, también puede desactivar la aplicación para un contenedor en particular con --security-opt label:disable y esto está documentado en el sección de configuración de seguridad del manual en línea de Docker:

sudo docker run --cap-add=sys_admin --security-opt label:disable \ -it fedora:rawhide /usr/bin/unshare -fmp /bin/sh -c \ 'mount --make-private / ; mount -t proc proc /proc'

Pero eso falla si el -U y -r las banderas se agregan de nuevo a unshare. Y, por supuesto, añadiendo --privileged el comando docker run funciona bien incluso con el -U y -r bandera.

Actualmente estoy tratando de usar las cosas de rastreo del kernel para averiguar qué, exactamente, me está dando un EPERM. Es un error inespecífico muy inútil de obtener.

Este comando funciona:

sudo docker run --cap-add=sys_admin --security-opt label:disable -it fedora:rawhide /bin/sh -c 'for dir in $(awk '"'"'/\/proc\// { print $5; }'"'"' /proc/1/mountinfo ); do umount "$dir"; done; /usr/bin/unshare -Ufmp -r /bin/sh -c '"'"'mount --make-private / ; mount -t proc proc /proc ; ls /proc'"'"

No lo dividí en varias líneas porque las citas son realmente importantes. Básicamente, desmonta un montón de cosas en /proc antes de ejecutar unshare y montar /proc en el espacio de nombres de usuario secundario.

Docker se monta sobre un montón de directorios y archivos en /proc con sus propios directorios que son directorios tmpfs vacíos y archivos nulos. Varios archivos en /proc representan valores que son aplicables a todo el sistema. En realidad, /proc/kcore le permitiría leer la memoria del kernel dentro del contenedor si fuera root, lo que, dado que mucha gente quiere creer que los contenedores son algún tipo de máquina virtual liviana o algo así, sorprendería a mucha gente.

El núcleo en (a partir de la versión 4.14 de todos modos) fs/namespace.c:mnt_already_visible comprueba si está montando un sistema de archivos ya montado, y si ese sistema de archivos tiene cosas montadas como sistemas de archivos secundarios y esos montajes tienen el indicador MNT_LOCKED, falla. El indicador MNT_LOCKED parece aplicarse (no busqué dónde está en el kernel) a todos los montajes cada vez que crea un espacio de nombres de usuario para evitar que desmonte cosas en ese espacio de nombres (porque obtiene privilegios 'dentro' del espacio de nombres de usuario) y hacer que las cosas ocultas sean visibles nuevamente.

El comando que publiqué usa un script awk en el contenido de /proc/1/mountinfo para extraer todos los subdirectorios y archivos de /proc esa ventana acoplable se ha montado y los desmonta a todos. Esto hace que el /proc el sistema de archivos se puede montar de nuevo en espacios de nombres de usuario anidados.

SamYaple en el canal # docker en Freenode ha sido bastante útil aquí, y esto puede ser un problema de cgroups. Parece que hay un cgroup de ‘dispositivos’.

Esto no te ayudará, pero TBH: Estoy* realmente * sorprendido de que esta no sea una opción estándar de montaje, ya que me parece un requisito bastante común. Lo necesito :slight_smile: … Estoy ejecutando un solo binario e incluyendo todas sus bibliotecas, por lo que no hay necesidad de una base-O/S en el contenedor, por lo que no tengo una, pero parece que quiere /proc para algunas características. Lo mismo sucedería con los binarios estáticos, como los Go, que podrían instalarse sin un sistema operativo base en un contenedor. Intenté ` - v / proc: / proc ’ y no ayuda por la razón que me das.

¿ha intentado usar -v / proc: / proc ?

@c4f4t0r-Bueno, eso no haría lo que quiero. No quiero el /proc del espacio de nombres en el que se ejecuta docker (presumiblemente el espacio de nombres de nivel raíz).

@c4f4t0r-Usando ftrace, las fuentes del kernel y un poco de pensamiento creativo, descubrí el problema. security - How do I mount a private /proc inside a namespace inside a docker container? - Server Fault