Description of the unshare command

1. The name

Unshare-run program with some namespaces unshared from parentCopy the code

2. In this paper,

unshare [options] program [arguments]
Copy the code

3. Describe

Unshares the indicated namespaces from the parent process and then executes the specified program. The namespaces to be Unshared are indicated via options. Unshareable namespaces are(unshare the specified namespace in the parent process and then execute the specified program. The namespace to unshare is indicated by the option. Non-shareable namespaces include

A total of six unshared namespaces can be set by unshare. They are:

mount namespace

UTS namespace

IPC namespace

network namespace

pid namespace

user namespace
Copy the code

4. The options

The options are as follows:

(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.Copy the code

Example 5.

# 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. Ensure we're PID 1 in it against newly mounted Procfs instance. $ unshare --map-root-user --user sh -c whoami root Establish a user namespace as an unprivileged user with a root user Create the user namespace as an unprivileged user, including the root user.Copy the code

6. What are the roles of namespaces?

(1)Mount Namespace

The Mount Namespace is the first Namespace implemented by the Linux kernel. It was added in version 2.4.19 of the kernel. It can be used to isolate the mount points seen by different processes or process groups. In layman’s terms, it is possible to see different mount directories in different processes. By mounting a Namespace, you can view only its own Mount information in a container. The mounting operations in a container do not affect the Mount directories on the host.

Let’s use an example to demonstrate how to Mount a Namespace. We use a command line tool called Unshare. Unshare is a tool in the Util-Linux toolkit that is integrated with CentOS 7 by default. You can use the unshare command to create and access different types of namespaces.

First we create a bash process and create a Mount Namespace using the following command:

unshare --mount --fork /bin/bash
Copy the code

After the preceding commands are executed, a new Mount Namespace has been created on the host and added to the current command line window. The following example shows that creating a Mount directory in a separate Mount Namespace does not affect the Mount directory on the host.

After the preceding commands are executed, a new Mount Namespace has been created on the host and added to the current command line window. The following example shows that creating a Mount directory in a separate Mount Namespace does not affect the Mount directory on the host.

Start by creating a directory under/TMP.

[root@centos7 centos]# mkdir /tmp/tmpfs
Copy the code

After the directory is created, run the mount command to mount a TMPFS directory. The command is as follows:

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

Then run the df command to check the mounted directories:

[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/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/tmpfsCopy the code

You can see that the/TMP/TMPFS directory has been mounted correctly. To verify that the directory is not mounted on the host, open a new command-line window and run the df command again to check the mount information of the 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
Copy the code

From the output above, you can see that the/TMP/TMPFS is not mounted on the host. Therefore, we can see that the Mount operation in our separate Mount Namespace does not affect the host.

To further verify our idea, let’s go ahead and check the Namespace information of the current process in the current command line window.

[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]
Copy the code

Then open a new command line window and run the same command to view the Namespace information on the 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]
Copy the code

By comparing the output of the two commands, you can see that the IDS of all namespaces are the same except the IDS of the Mount Namespace.

According to the above results, you can use the unshare command to create a Mount Namespace, and the Mount is completely isolated from the outside of the Namespace.

(2)PID Namespace

PID The Namespace is used to isolate processes. In different PID namespaces, processes can have the same PID number. Using PID Namespace, the main process of each container can be process 1, while the processes in the container have different PID on the host. For example, if the PID of a process is 122 on the host, you can use the PID Namespace to set the PID of the process to 1 in the container.

Let’s use an example to demonstrate the function of PID Namespace. Let’s create a bash process and create a new PID Namespace using the following command:

unshare --fork --pid --mount-proc /bin/bash
Copy the code

After the above commands are executed, a new PID Namespace is created on the host and the current command line window is added to the newly created PID Namespace. Run the ps aux command in the current command line window to check the process information:

[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 auxCopy the code

The preceding command output shows that bash is process 1 in the Namespace, and we do not see other process information on the host.

(3)UTS Namespace

The UTS Namespace is primarily used to isolate host names, allowing each UTS Namespace to have a separate host name. For example, our host name is Docker, and UTS Namespace can be used to implement lagoudocker or any other customized host name in the container.

We also use an example to verify the effect of UTS Namespace. First, we use the unshare command to create a UTS Namespace:

unshare --fork --uts /bin/bash
Copy the code

Hostname = hostname = hostname = hostname = hostname = hostname = hostname = hostname = hostname = hostname = hostname = hostname

 hostname -b lagoudocker
Copy the code

Then look at the host name:

[root@centos7 centos]# hostname

lagoudocker
Copy the code

From the output of the above command, we can see that the current hostname in UTS Namespace has been changed to Lagoudocker. Then we open a new command line window and use the same command to check the hostname of the host:

[centos@centos7 ~]$ hostname

centos7
Copy the code

You can see that the name of the host is still Centos7 and has not been changed. From this, you can verify that UTS Namespace can be used to isolate host names.

(4)IPC Namespace

The IPC Namespace is used to isolate inter-process communication. For example, if the PID Namespace and IPC Namespace are used together, processes in the same IPC Namespace can communicate with each other, but processes in different IPC namespaces cannot communicate with each other.

Use the unshare command to create an IPC Namespace:

unshare --fork --ipc /bin/bash
Copy the code

In the following, we need to use two commands to verify the IPC Namespace.

The ipcs -q command displays the list of intersystem communication queues.

The ipcmk -q command is used to create a communication queue between systems.

We first use the ipcs -q command to check the list of system communication queues under the current IPC Namespace:

[centos@centos7 ~]$ ipcs -q

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

key    msqid   owner   perms   used-bytes  messages
Copy the code

We can see that there is no system communication queue, then we use ipcmk -q command to create a system communication queue:

[root@centos7 centos]# ipcmk -Q

Message queue id: 0
Copy the code

Run the ipcs -q command again to view the list of system communication queues under the current IPC Namespace

[root@centos7 centos]# ipcs -q

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

key    msqid   owner   perms   used-bytes  messages

0x73682a32 0     root    644    0      0
Copy the code

You can see that we have successfully created a system communication queue. Then we open a new command line window and use the ipcs -q command to check the system communication queue of the host:

[centos@centos7 ~]$ ipcs -q

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

key    msqid   owner   perms   used-bytes  messages
Copy the code

Through the above experiment, it can be found that the system communication queues created in a separate IPC Namespace are not visible on the host. That is, THE IPC Namespace isolates the communication queues in the system.

(5)User Namespace

User Namespace Is used to isolate users and User groups. A typical application scenario is that a process running on a host as a non-root User can be mapped to User root in a separate User Namespace. Using the User Namespace allows a process to have the root permission in the container, while being a common User on the host.

User Namesapce can be created without root permission. To create a Namespace, run the following command:

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

[root@centos7 ~]#
Copy the code

By default, CentOS7 allows User Namespace 0 to be created. If the preceding command fails to be executed (unshare: unshare failed: Invalid argument), run the following command to change the number of User namespaces that the system allows to be created: Echo 65535 > /proc/sys/user/max_user_namespaces, and then try again to create a user Namespace.

Then run the id command to view the current user information:

[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
Copy the code

You can see from the output above that we are already root in the new User Namespace. To verify this, run the reboot command on the current command-line interface (CLI) :

[root@centos7 ~]# reboot

Failed to open /dev/initctl: Permission denied

Failed to talk to init daemon.
Copy the code

You can see that you are the root User in the newly created User Namespace, but you do not have the permission to reboot. This indicates that in the isolated User Namespace, the root permission of the host cannot be obtained. In other words, the User Namespace isolates users from User groups.

(6)Net Namespace

Net Namespace is used to isolate information such as network devices, IP addresses, and ports. Net Namespace allows each process to have its own IP address, port, and network adapter information. For example, if the host IP address is 172.16.4.1, you can set an independent IP address in the container to 192.168.1.1.

As an example, we first use the IP a command to check the network information on the 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 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 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 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 foreverCopy the code

Then we create a Net Namespace using the following command:

 unshare --net --fork /bin/bash
Copy the code

Similarly we use the IP a command to check the network information:

[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
Copy the code

As you can see, the host has lo, eth0, docker0 and other network devices, and our new Net Namespace is different from the network devices on the host.