Construcción de contenedores a mano: el espacio de nombres PID

Continuando con la serie de espacios de nombres, este artículo cubre los PID espacio de nombres Si desea obtener una descripción general de todos los espacios de nombres, consulte el primer artículo. Previamente creaste un nuevo mnt espacio de nombres Curiosamente, como descubrió, incluso después de crear una nueva mnt espacio de nombres, aún tenía acceso a los ID de proceso (PID) del host original. Cuando ha tratado de escalar el / proceso espacio de nombres, recibió el error bastante confuso, como se ve a continuación:

[email protected]$ mount -t proc proc /proc
mount: permission denied (are you root?)

[email protected]$ whoami
root

Si bien podía crear todo tipo de montajes en el nuevo espacio de nombres de montaje, no podía interactuar ni editar / proceso. En este artículo, reviso la PID espacio de nombres y mostrar cómo se puede utilizar, así como el mnt espacio de nombres, para asegurar aún más su nuevo contenedor.

Índice

    ¿Qué son los identificadores de proceso?

    Antes de saltar directamente a la PID espacio de nombres, creo que es una buena idea proporcionar un poco de contexto sobre por qué este espacio de nombres es importante.

    Cuando se crea un proceso en la mayoría de los sistemas operativos similares a Unix, se le asigna un identificador numérico específico llamado (PID). Este PID se utiliza para identificar de forma única un proceso, incluso si hay dos procesos que comparten el mismo nombre legible por humanos. Por ejemplo, si hay varias sesiones ssh activas en un sistema y necesita cerrar una conexión específica, el PID ayuda al administrador a garantizar que se cierre la sesión correcta.

    Todos estos procesos se rastrean en un sistema de archivos especial llamado procfs. Si bien este sistema de archivos puede montarse técnicamente en cualquier lugar, la mayoría de las herramientas (y convenciones) esperan que procfs escalar debajo /proc. Si haces una lista de /proc, verá una carpeta para cada proceso que se ejecuta en su sistema. Dentro de esta carpeta hay todo tipo de archivos especiales que se utilizan para rastrear varios aspectos del proceso. A los efectos de este artículo, estos archivos no son importantes. Solo sé que /proc es donde la mayoría de los sistemas similares a Unix almacenan información sobre los procesos en un sistema en ejecución.

    El espacio de nombres PID

    Una de las principales razones de la PID El espacio de nombres es para permitir el aislamiento del proceso. Específicamente, como dice la página man:

    Los espacios de nombres PID aíslan el espacio de números de ID del proceso, lo que significa que los procesos en diferentes espacios de nombres PID pueden tener el mismo PID.

    Esto es importante porque significa que los procesos pueden estar seguros de que no tienen un PID en conflicto con otro proceso. Al examinar un solo sistema, por supuesto, no hay riesgo de un conflicto de PID ya que el sistema incrementa continuamente el número de identificación del proceso y nunca asigna el mismo número dos veces. Cuando se trata de contenedores en múltiples máquinas, este problema se vuelve más prominente. Como se describe en la página man:

    Los espacios de nombres PID permiten que los contenedores brinden funcionalidades como suspender/reanudar el conjunto de procesos en el contenedor y migrar el contenedor a un nuevo host mientras los procesos dentro del contenedor mantienen los mismos PID. .

    Aparte del aislamiento, el sistema PID funciona de manera idéntica al que está fuera del espacio de nombres. Los ID de proceso dentro del nuevo espacio de nombres comienzan en 1, siendo considerado el primer proceso como el en eso para tratar. el en eso El proceso se maneja de manera muy diferente a todos los demás PID en un host. Esto tiene implicaciones particulares para el sistema en ejecución que están más allá del alcance de esta serie. Si está interesado en obtener más información, consulte la sección "Señales y proceso de inicialización" de la Artículo LWN Espacios de nombres.

    Lo que debe tenerse en cuenta, sin embargo, es que cualquier proceso tiene el PID 1 es vital para la longevidad de los espacios de nombres. Si PID 1 se detiene por cualquier motivo, el núcleo enviará un SIGKILL a todos los procesos restantes en el espacio de nombres, cerrando efectivamente ese espacio de nombres.

    Explorar espacios de nombres PID

    Si te preguntas, como yo, si puedes anidar PID espacios de nombres, la respuesta es sí. De hecho, el núcleo deja espacio para hasta 32 anidados PID espacios de nombres Esto se considera una relación unidireccional. Esto significa que el padre puede ver los PID de hijos, nietos, etc. Sin embargo, no puede ver ninguno de los PID de su antepasado. Considera lo siguiente:

    [[email protected] ~] sudo unshare -fp /bin/bash
    [[email protected] ~] sleep 90000 &
    
    [[email protected] ~] ps -ef
    UID          PID    PPID  C STIME TTY          TIME CMD
    [truncated ]
    .....
    root       11627   11620  0 09:16 pts/0    00:00:00 sudo unshare -fp /bin/bash
    root       11633   11627  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
    root       11634   11633  0 09:17 pts/0    00:00:00 /bin/bash
    root       11639   11634  0 09:17 pts/0    00:00:00 sleep 90000
    root       11641   11634  0 09:17 pts/0    00:00:00 ps -ef
    
    [[email protected] ~] sudo unshare -fp /bin/bash
    [[email protected] ~] sleep 8000 &
    
    [[email protected] ~] ps -ef
    [truncated ]
    .....
    
    UID          PID    PPID  C STIME TTY          TIME CMD
    root       11650   11634  0 09:17 pts/0    00:00:00 sudo unshare -fp /bin/bash
    root       11654   11650  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
    root       11655   11654  0 09:17 pts/0    00:00:00 /bin/bash
    root       11661   11655  0 09:17 pts/0    00:00:00 sleep 8000
    root       11671   11655  0 09:17 pts/0    00:00:00 ps -ef

    Notará que he truncado la salida porque el PID espacio de nombres para tener acceso completo a todos los PID en /proc. Vea lo que sucede si intenta detener un proceso que está en un ancestro:

    [[email protected] ~] kill -9 11361
    bash: kill: (11361) - No such process

    ¿Por qué? En pocas palabras, las herramientas tradicionales como ps desconocen el espacio de nombres y, de hecho, están leyendo del /proc directorio telefónico. si hiciste un ls /proc, todavía vería todas las carpetas y archivos de antes porque, como se indicó en el último artículo, el PID espacio de nombres todo mnt el espacio de nombres sube. Abordaré esta situación más adelante. Por ahora, volvamos al ejemplo en cuestión.

    En otro caparazón, identifique los procesos de sueño:

    [[email protected] ~] ps -ef |grep sleep
    root       11639   11634  0 09:17 pts/0    00:00:00 sleep 90000
    root       11661   11655  0 09:17 pts/0    00:00:00 sleep 8000

    Si desea verificar que estos procesos están en diferentes espacios de nombres, deberá encontrar el bash proceso PID. Recuerda, desde que corriste sudo unshare -fp /bin/bash, el bash el proceso es el en eso proceso en el nuevo espacio de nombres. Por lo tanto, es el PID el que se vinculará al ID del espacio de nombres. Tome los PID:

    [[email protected] ~] ps -ef |grep bash
    root       11627   11620  0 09:16 pts/0    00:00:00 sudo unshare -fp /bin/bash
    root       11633   11627  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
    root       11634   11633  0 09:17 pts/0    00:00:00 /bin/bash
    root       11650   11634  0 09:17 pts/0    00:00:00 sudo unshare -fp /bin/bash
    root       11654   11650  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
    root       11655   11654  0 09:17 pts/0    00:00:00 /bin/bash

    Puedes ver los PID 11634 y 11655 en la salida. Si compara eso con la salida de lsns (enumerar espacios de nombres), verá lo siguiente:

    [[email protected] ~] lsns |grep bash
            NS TYPE   NPROCS    PID USER             COMMAND
    4026532952 pid         4 11634 root             /bin/bash
    4026532954 pid         4 11655 root             /bin/bash

    Como puede ver, los ID de espacio de nombres son diferentes y, por lo tanto, los procesos se encuentran en espacios de nombres diferentes.

    Ahora que ha establecido que los espacios de nombres son realmente diferentes, echemos un vistazo a la ascendencia PID mencionada anteriormente. Puede hacerlo identificando el NSpid atributo de un PID dado en el /proc directorio, como se ve a continuación:

    sudo cat /proc/11655/status |grep NSpid
    NSpid:    11655    6    1

    Las columnas se leen de izquierda a derecha e indican el PID en sus respectivos espacios de nombres. El PID más a la izquierda es el espacio de nombres principal o raíz. En este caso, tiene un PID de 11655, un PID secundario de 6, y un PID terciario de 1. Dado que los espacios de nombres tienen todos los descendientes PID espacio de nombres, se puede ver así:

    • En el anfitrión, el bash proceso en ejecución sleep 8000 el control tiene un PID de 11655.
    • Dentro del primer "contenedor", el bash proceso en ejecución sleep 8000 el control tiene un PID de 6.
    • Dentro del segundo "contenedor" anidado, el PID es 1. Fue el contenedor lo que realmente inició el proceso.

    Cada uno de estos bash commands se creó en su propio espacio de nombres, pero es visible para el padre (en este caso, el raíz espacio de nombres).

    /proc, PID y usuarios sin privilegios

    El lector astuto se habrá dado cuenta de que en los dos últimos artículos un usuario normal podía crear tanto usuario y mnt espacios de nombres En este artículo he utilizado el sudo pedido. Esto se debe a que no puede crear un PID espacio de nombres solo con un usuario sin privilegios. La respuesta a esto es combinar múltiples creaciones de espacios de nombres en un solo evento. Hay diferentes soluciones de montaje. /proc como usuario sin privilegios.

    Si solo está tratando de crear un nuevo usuario espacio de nombres, obtendrá un resultado extraño:

    [ [email protected] ~] unshare -Urp
    -bash: fork: Cannot allocate memory
    -bash-5.1# ps -ef
    -bash: fork: Cannot allocate memory
    -bash-5.1# ls
    -bash: fork: Cannot allocate memory

    ¿Que está sucediendo aquí? Recuerda cómo el primer proceso dentro de un nuevo PID el espacio de nombres se convierte en el en eso ¿para tratar? En este caso, el shell actual no puede mover los espacios de nombres. existe en el raíz espacio de nombres, y cuando haya creado un nuevo PID espacio de nombres, el sistema no sabía cómo manejarlo. La solución a esto es tener el propio proceso de bifurcación. Esto permite que el shell actual se convierta en un proceso hijo del unshare pedido. Utilizando el -f flag hace que se cree el espacio de nombres:

    [ [email protected] ~] unshare -Urfp
    [ [email protected] ~]

    Sin embargo, todavía se ve la contaminación de la /proc punto de montaje. Hay dos soluciones para esto. En primer lugar, puede crear un nuevo mnt espacio de nombres, luego haga una copia de seguridad /proc tu mismo:

    [ [email protected]  ~]$ unshare -Urpmf
    [ [email protected] ~]# mount -t proc proc /proc
    [ [email protected] ~]# ps -ef
    UID          PID    PPID  C STIME TTY          TIME CMD
    root           1       0  0 09:31 pts/0    00:00:00 -bash
    root          10       1  0 09:31 pts/0    00:00:00 ps -ef

    De hecho, durante muchos años esta fue la única opción pero, una bandera --mount-proc fue creado hace algún tiempo para hacerlo en un solo paso. La página del manual dice:

    Justo antes de ejecutar el programa, monte el sistema de archivos proc en el punto de montaje (el valor predeterminado es /proc). Esto es útil al crear un nuevo espacio de nombres PID. También implica la creación de un nuevo espacio de nombres de montaje, ya que el montaje /proc interrumpiría los programas existentes en el sistema. El nuevo sistema de archivos proc se monta explícitamente como privado (con MS_PRIVATE | MS_REC).

    Por lo tanto, puede ver referencias al siguiente comando:

    unshare -Urpf --mount-proc

    Esto crea un nuevo mnt espacio de nombres al montar /proc para usted.

    Introducción de un espacio de nombres

    Para reducir la complejidad, dejé los espacios de nombres creados anteriormente. Creé un nuevo espacio de nombres con el siguiente comando:

    unshare -Urfp --mount-proc

    También creé un sleep proceso solo para ayudar a identificar el espacio de nombres. Como solo tengo un nuevo espacio de nombres, puedo usar el lsns Comando para determinar el PID correcto:

    [ [email protected]  ~]$ lsns |grep bash
    4026532965 pid         2 13142 user -bash

    Luego ejecuta el nsenter pedido:

    sudo nsenter -t 13142 -a

    el -a la bandera indica al nsenter para ingresar todos los espacios de nombres para este PID. sudo se requiere con el -a marca, de lo contrario no podrá modificar todos los espacios de nombres apropiados. Ahora debería poder enumerar todos los PIDS en este NS:

    [ [email protected]  ~]$ ps -ef
    
    UID          PID    PPID  C STIME TTY          TIME CMD
    root           1       0  0 09:54 pts/0    00:00:00 -bash
    root           8       1  0 09:54 pts/0    00:00:00 sleep 99999
    root          25       0  0 10:15 pts/1    00:00:00 -bash
    root          31      25  0 10:15 pts/1    00:00:00 ps -ef

    Envoltura

    el PID El espacio de nombres es importante cuando se trata de crear entornos aislados. Permite que los procesos tengan sus propios PID independientemente del sistema host. En un mundo donde varios hosts pueden estar involucrados en la orquestación de entornos aislados (contenedores), se vuelve crucial contar con una instalación que garantice PID únicos durante la congelación y migración de procesos. Además, por motivos de seguridad, si está ejecutando espacios de nombres para el aislamiento de aplicaciones, el PID El espacio de nombres es vital para evitar la fuga de información a través de los procesos que puede estar ejecutando un host.

    Cuando se combina con el usuario y mnt espacios de nombres, el PID El espacio de nombres ofrece una gran protección sin necesidad de privilegios de root. Los navegadores modernos, como Firefox y Vivaldi, usan espacios de nombres para proporcionar espacio aislado del navegador. En el siguiente artículo, demostraré la reporte espacio de nombres y vea cómo puede continuar construyendo su contenedor a mano agregando componentes de red discretos.

    Artículos de interés

    Subir