Explicación detallada y caso de comando unshare

Explicación detallada del comando unshare

1. Nombre

unshare - run program with some namespaces unshared from parent(使用与父程序不共享的名称空间运行程序)

2. Resumen

unshare [options] program [arguments]

3. Descripción

Deja de compartir los espacios de nombres indicados del proceso principal y luego ejecuta el programa especificado. Los espacios de nombres que no se compartirán se indican mediante opciones. Los espacios de nombres que no se pueden compartir son (deja de compartir los espacios de nombres indicados del proceso principal y luego ejecuta el programa especificado. El espacio se indica mediante opciones. Los espacios de nombres que no se pueden compartir incluyen)

Se puede establecer un total de 6 espacios de nombres no compartidos para dejar de compartir, que son:

mount namespace

UTS namespace

IPC namespace

network namespace

pid namespace

user namespace

4. Opciones

Hay un total de las siguientes opciones:

(1)-i, --ipc

 unshare the IPC namespace.

(2)-m, --mount

 Unshare the mount namespace.

(3)-n, --net

 Unshare the network namespace.

(4) -p, --pid

Unshare the pid namespace.  See also the --fork and --mount-proc options.

(5)-u, --uts

 Unshare the UTS namespace.

(6) -U, --user

Unshare the user namespace.

(7)-f, --fork

Fork the specified program as a child process of unshare rather than running it directly.  This is useful when creating a new pid namespace.

(8)--mount-proc[=mountpoint]

Just  before running the program, mount the proc filesystem at mountpoint (default is /proc).  This is useful when creating a new pid namespace.  It also implies creating a new mount names‐pace since the /proc mount would otherwise mess up existing programs on the system.  The new proc filesystem is explicitly mounted as private (by MS_PRIVATE|MS_REC).

(9)-r, --map-root-user

Run the program only after the current effective user and group IDs have been mapped to the superuser UID and GID in the newly created user namespace.  This  makes  it  possible  to  conve‐niently  gain  capabilities  needed  to  manage various aspects of the newly created namespaces (such as configuring interfaces in the network namespace or mounting filesystems in the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support more sophisticated use cases, such as mapping multiple ranges  of  UIDs  and  GIDs.  This  option  implies --setgroups=deny.

(10) --propagation private|shared|slave|unchanged

Recursively  sets mount propagation flag in the new mount namespace. The default is to set the propagation to private, this feature is possible to disable by unchanged argument. The options        is silently ignored when mount namespace (--mount) is not requested.

(11)--setgroups allow|deny

Allow or deny setgroups(2) syscall in user namespaces.

setgroups(2) is only callable with CAP_SETGID and CAP_SETGID in a user namespace (since Linux 3.19) does not give you permission to call setgroups(2) until after GID map has been  set.  The GID map is writable by root when setgroups(2) is enabled and GID map becomes writable by unprivileged processes when setgroups(2) is permanently disabled.

(12) -V, --version

Display version information and exit.

(13)-h, --help

Display help text and exit.

5. Ejemplos

# unshare --fork --pid --mount-proc readlink /proc/self

1

Establish a PID namespace, ensure we're PID 1 in it against newly mounted procfs instance.

(建立一个PID命名空间,确保我们在新安装的procfs实例中是PID 1。)

 

$ unshare --map-root-user --user sh -c whoami

root

Establish a user namespace as an unprivileged user with a root user within it.

(将用户命名空间建立为非特权用户,其中包含根用户。)

6. ¿Cuáles son las funciones de varios espacios de nombres?

(1) Espacio de nombres de montaje

Mount Namespace es el primer espacio de nombres implementado por el kernel de Linux, que se ha agregado desde la versión 2.4.19 del kernel. Se puede utilizar para aislar puntos de montaje vistos por diferentes procesos o grupos de procesos. En términos sencillos, es posible ver diferentes directorios de montaje en diferentes procesos. El uso de Mount Namespace puede darse cuenta de que solo se puede ver su propia información de montaje en el contenedor, y la operación de montaje en el contenedor no afectará el directorio de montaje del host.

Usemos un ejemplo para demostrar Mount Namespace. Usamos una herramienta de línea de comando unshare. unshare es una herramienta en el kit de herramientas util-linux. CentOS 7 ha integrado esta herramienta de forma predeterminada. Puede usar el comando unshare para crear y acceder a diferentes tipos de espacios de nombres.

Primero, usamos los siguientes comandos para crear un proceso bash y crear un nuevo espacio de nombres de montaje:

unshare --mount --fork /bin/bash

Después de ejecutar el comando anterior, hemos creado un nuevo espacio de nombres de montaje en el host, y el espacio de nombres de montaje recién creado se ha agregado a la ventana de línea de comandos actual. Permítanme usar un ejemplo para verificar que la creación de un directorio de montaje en un espacio de nombres de montaje independiente no afecta el directorio de montaje del host.

Después de ejecutar el comando anterior, hemos creado un nuevo espacio de nombres de montaje en el host, y el espacio de nombres de montaje recién creado se ha agregado a la ventana de línea de comandos actual. Permítanme usar un ejemplo para verificar que la creación de un directorio de montaje en un espacio de nombres de montaje independiente no afecta el directorio de montaje del host.

Primero cree un directorio en el directorio / tmp.

[root@centos7 centos]# mkdir /tmp/tmpfs

Después de crear el directorio, use el comando mount para montar un directorio de tipo tmpfs. El comando es el siguiente:

[root@centos7 centos]# mount -t tmpfs -o size=20m tmpfs /tmp/tmpfs

Luego use el comando df para ver la información del directorio montado:

[root@centos7 centos]# df -h

Filesystem   Size Used Avail Use% Mounted on

/dev/vda1    500G 1.4G 499G  1% /

devtmpfs     16G   0  16G  0% /dev

tmpfs      16G   0  16G  0% /dev/shm

tmpfs      16G   0  16G  0% /sys/fs/cgroup

tmpfs      16G  57M  16G  1% /run

tmpfs      3.2G   0 3.2G  0% /run/user/1000

tmpfs      20M   0  20M  0% /tmp/tmpfs

Puede ver que el directorio / tmp / tmpfs se ha montado correctamente. Para verificar que este directorio no está montado en el host, abrimos una nueva ventana de línea de comando y ejecutamos el comando df para ver la información de montaje del host:

[centos@centos7 ~]$ df -h

Filesystem   Size Used Avail Use% Mounted on

devtmpfs     16G   0  16G  0% /dev

tmpfs      16G   0  16G  0% /dev/shm

tmpfs      16G  57M  16G  1% /run

tmpfs      16G   0  16G  0% /sys/fs/cgroup

/dev/vda1    500G 1.4G 499G  1% /

tmpfs      3.2G   0 3.2G  0% /run/user/1000

De la salida anterior, podemos ver que / tmp / tmpfs no está montado en el host. Se puede ver que la operación de montaje en nuestro Mount Namespace independiente no afectará al host.

Para verificar aún más nuestras ideas, continuamos verificando la información del espacio de nombres del proceso actual en la ventana de la línea de comandos actual, el comando es el siguiente:

[root@centos7 centos]# ls -l /proc/self/ns/

total 0

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 ipc -> ipc:[4026531839]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 mnt -> mnt:[4026532239]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 net -> net:[4026531956]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 pid -> pid:[4026531836]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 user -> user:[4026531837]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 uts -> uts:[4026531838]

Luego abra una nueva ventana de línea de comando y use el mismo comando para verificar la información del espacio de nombres en el host:

[centos@centos7 ~]$ ls -l /proc/self/ns/

total 0

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 ipc -> ipc:[4026531839]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 mnt -> mnt:[4026531840]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 net -> net:[4026531956]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 pid -> pid:[4026531836]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 user -> user:[4026531837]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 uts -> uts:[4026531838]

Al comparar los resultados de salida de los dos comandos, podemos ver que, a excepción de los valores de ID de Mount Namespace, los valores de ID de otros espacios de nombres son los mismos.

A partir de los resultados anteriores, podemos concluir que el uso del comando unshare puede crear un nuevo espacio de nombres de montaje, y el montaje en el espacio de nombres de montaje recién creado está completamente aislado del exterior.

(2) Espacio de nombres PID

La función del espacio de nombres PID es aislar el proceso. En diferentes espacios de nombres PID, los procesos pueden tener el mismo número PID. El uso del espacio de nombres PID puede darse cuenta de que el proceso principal de cada contenedor es el proceso n. ° 1, mientras que los procesos en el contenedor tienen diferentes PID en el host. Por ejemplo, el PID de un proceso en el host es 122 y el espacio de nombres PID se puede utilizar para darse cuenta de que el proceso ve el PID de 1 en el contenedor.

A continuación, usamos un ejemplo para demostrar la función del espacio de nombres PID. Primero, usamos el siguiente comando para crear un proceso bash y crear un nuevo espacio de nombres PID:

unshare --fork --pid --mount-proc /bin/bash

Después de ejecutar el comando anterior, creamos un nuevo espacio de nombres PID en el host y agregamos el espacio de nombres PID recién creado a la ventana de la línea de comandos actual. Utilice el comando ps aux en la ventana de la línea de comandos actual para ver la información del proceso:

[root@centos7 centos]# ps aux

USER    PID %CPU %MEM  VSZ  RSS TTY   STAT START  TIME COMMAND

root     1 0.0 0.0 115544 2004 pts/0  S  10:57  0:00 bash

root    10 0.0 0.0 155444 1764 pts/0  R+  10:59  0:00 ps aux

A través de la salida del comando anterior, puede ver que bash es el proceso número uno en el espacio de nombres actual, y no podemos ver otra información de proceso en el host.

(3) Espacio de nombres UTS

El espacio de nombres UTS se utiliza principalmente para aislar nombres de host y permite que cada espacio de nombres UTS tenga un nombre de host independiente. Por ejemplo, nuestro nombre de host es Docker, el uso de UTS Namespace puede realizar el nombre de host en el contenedor como ladoudocker o cualquier otro nombre de host personalizado.

De manera similar, usamos un ejemplo para verificar la función del espacio de nombres UTS. Primero, usamos el comando unshare para crear un espacio de nombres UTS:

unshare --fork --uts /bin/bash

Después de que se crea el espacio de nombres UTS, la ventana de la línea de comandos actual ya está en un espacio de nombres UTS independiente. A continuación, usamos el comando hostname (el nombre de host se puede usar para ver el nombre de host) para establecer el nombre de host:

 hostname -b lagoudocker

Luego verifique el nombre de host nuevamente:

[root@centos7 centos]# hostname

lagoudocker

A través de la salida del comando anterior, podemos ver que el nombre de host en el espacio de nombres UTS actual se ha modificado a lagudocker. Luego abrimos una nueva ventana de línea de comando y usamos el mismo comando para verificar el nombre de host del host:

[centos@centos7 ~]$ hostname

centos7

Puede ver que el nombre del host sigue siendo centos7 y no se ha modificado. A partir de esto, se puede verificar que el espacio de nombres UTS se puede usar para aislar nombres de host.

(4) Espacio de nombres de IPC

El espacio de nombres de IPC se utiliza principalmente para aislar la comunicación entre procesos. Por ejemplo, el espacio de nombres PID y el espacio de nombres IPC se pueden usar juntos para darse cuenta de que los procesos dentro del mismo espacio de nombres IPC pueden comunicarse entre sí, pero los procesos con diferentes espacios de nombres IPC no pueden comunicarse.

De manera similar, usamos un ejemplo para verificar la función del espacio de nombres de IPC. Primero, usamos el comando unshare para crear un espacio de nombres de IPC:

unshare --fork --ipc /bin/bash

A continuación, necesitamos usar dos comandos para verificar el espacio de nombres de IPC.

Comando ipcs -q: se utiliza para ver la lista de colas de comunicación entre sistemas.

Comando ipcmk -Q: se utiliza para crear una cola de comunicación entre sistemas.

Primero usamos el comando ipcs -q para ver la lista de colas de comunicación del sistema bajo el espacio de nombres IPC actual:

[centos@centos7 ~]$ ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

De lo anterior, podemos ver que actualmente no hay una cola de comunicación del sistema, y ​​luego usamos el comando ipcmk -Q para crear una cola de comunicación del sistema:

[root@centos7 centos]# ipcmk -Q

Message queue id: 0

Use el comando ipcs -q nuevamente para ver la lista de colas de comunicación del sistema en el espacio de nombres IPC actual

[root@centos7 centos]# ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

0x73682a32 0     root    644    0      0

Puede ver que hemos creado con éxito una cola de comunicación del sistema. Luego abrimos una nueva ventana de línea de comando y usamos el comando ipcs -q para verificar la cola de comunicación del sistema del host:

[centos@centos7 ~]$ ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

A través del experimento anterior, se puede encontrar que la cola de comunicación del sistema creada en un espacio de nombres IPC separado no se puede ver en el host. Es decir, IPC Namespace se da cuenta del aislamiento de las colas de comunicación del sistema.

(5) Espacio de nombre de usuario

El espacio de nombres de usuario se utiliza principalmente para aislar usuarios y grupos de usuarios. Un escenario de aplicación típico es que un proceso que se ejecuta como un usuario no root en el host se puede asignar a un usuario root en un espacio de nombres de usuario separado. El uso del espacio de nombres de usuario puede darse cuenta de que el proceso tiene privilegios de root en el contenedor, pero es solo un usuario normal en el host.

User Namesapce se puede crear sin autorización de root. A continuación, creamos un espacio de nombres de usuario como un usuario normal, el comando es el siguiente:

[centos@centos7 ~]$ unshare --user -r /bin/bash

[root@centos7 ~]#

CentOS7 está predeterminado para permitir la creación del espacio de nombres de usuario en 0. Si la ejecución del comando anterior falla (el error devuelto por el comando unshare es unshare: unshare fallido: argumento no válido), debe utilizar el siguiente comando para modificar el número de El sistema permite crear espacios de nombres de usuario El comando es: echo 65535> / proc / sys / user / max_user_namespaces, y luego intente crear nuevamente el espacio de nombres de usuario.

Luego ejecute el comando id para verificar la información del usuario actual:

[root@centos7 ~]# id

uid=0(root) gid=0(root) groups=0(root),65534(nfsnobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

De la salida anterior, podemos ver que ya somos el usuario root en el nuevo espacio de nombres de usuario. A continuación, usamos el comando de reinicio que solo puede ejecutar el usuario root del host para verificarlo, y ejecutamos el comando de reinicio en la ventana de línea de comandos actual:

[root@centos7 ~]# reboot

Failed to open /dev/initctl: Permission denied

Failed to talk to init daemon.

Como puede ver, aunque somos el usuario root en el espacio de nombres de usuario recién creado, no tenemos la autoridad para ejecutar el comando de reinicio. Esto muestra que en el espacio de nombre de usuario aislado, no se puede obtener la autoridad raíz del host, lo que significa que el espacio de nombre de usuario se da cuenta del aislamiento de usuarios y grupos de usuarios.

(6) Espacio de nombres de red

El espacio de nombres de red se utiliza para aislar información como dispositivos de red, direcciones IP y puertos. Net Namespace permite que cada proceso tenga su propia dirección IP, puerto e información de tarjeta de red independientes. Por ejemplo, la dirección IP del host es 172.16.4.1 y se puede establecer una dirección IP independiente en 192.168.1.1 en el contenedor.

También use la verificación de ejemplo, primero usamos el comando ip a para verificar la información de red en el host:

$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

  inet 127.0.0.1/8 scope host lo

​    valid_lft forever preferred_lft forever

  inet6 ::1/128 scope host

​    valid_lft forever preferred_lft forever

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

  link/ether 02:11:b0:14:01:0c brd ff:ff:ff:ff:ff:ff

  inet 172.20.1.11/24 brd 172.20.1.255 scope global dynamic eth0

​    valid_lft 86063337sec preferred_lft 86063337sec

  inet6 fe80::11:b0ff:fe14:10c/64 scope link

​    valid_lft forever preferred_lft forever

3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default

  link/ether 02:42:82:8d:a0:df brd ff:ff:ff:ff:ff:ff

  inet 172.17.0.1/16 scope global docker0

​    valid_lft forever preferred_lft forever

  inet6 fe80::42:82ff:fe8d:a0df/64 scope link

​    valid_lft forever preferred_lft forever

Luego usamos el siguiente comando para crear un espacio de nombres de red:

 unshare --net --fork /bin/bash

De manera similar, usamos el comando ip a para verificar la información de la red:

[root@centos7 centos]# ip a

1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Como puede ver, hay dispositivos de red como lo, eth0 y docker0 en el host, y los dispositivos de red en nuestro espacio de nombres de red recién creado son diferentes de los del host.

Supongo que te gusta

Origin blog.csdn.net/qq_34939308/article/details/114115443
Recomendado
Clasificación