In the following routine, we have enabled mount namespace and re-mounted the/proc file system in the sub-process.
We can see that there are only two processes, and the pid = 1 process is our/bin/bash. We can also see that the/proc directory is much cleaner:
We can also see that the top command in the sub-process only shows two processes.
Here, let's talk about it. After creating a mount namespace using CLONE_NEWNS, the parent process copies its own file structure to the child process. All the mount operations in the new namespace in the sub-process only affect the file system, without any external impact. In this way, strict isolation can be achieved.
You may ask, do we still need to mount some other file systems like this? Yes.
Docker's Mount NamespaceNext I will show you a "shanzhai image" that imitates the Mount Namespace of Docker.
First, we need a rootfs, that is, we need to copy the commands in the image we want to do to the directory of A rootfs. We build the following directory by imitating Linux:
hchen@ubuntu:~/rootfs$ lsbin dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var
Then, we need to copy some of the commands We Need To The rootfs/bin directory (the sh command must be copied in, otherwise we cannot chroot)
hchen@ubuntu:~/rootfs$ ls ./bin ./usr/bin./bin:bash chown gzip less mount netstat rm tabs tee top ttycat cp hostname ln mountpoint ping sed tac test touch umountchgrp echo ip ls mv ps sh tail timeout tr unamechmod grep kill more nc pwd sleep tar toe truncate which./usr/bin:awk env groups head id mesg sort strace tail top uniq vi wc xargs
Note: You can use the ldd command to copy the so files related to these commands to the corresponding directory:
hchen@ubuntu:~/rootfs/bin$ ldd bash linux-vdso.so.1 => (0x00007fffd33fc000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f4bd42c2000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4bd40be000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4bd3cf8000) /lib64/ld-linux-x86-64.so.2 (0x00007f4bd4504000)
Below are some so files in my rootfs:
hchen@ubuntu:~/rootfs$ ls ./lib64 ./lib/x86_64-linux-gnu/./lib64:ld-linux-x86-64.so.2./lib/x86_64-linux-gnu/:libacl.so.1 libmemusage.so libnss_files-2.19.so libpython3.4m.so.1libacl.so.1.1.0 libmount.so.1 libnss_files.so.2 libpython3.4m.so.1.0libattr.so.1 libmount.so.1.1.0 libnss_hesiod-2.19.so libresolv-2.19.solibblkid.so.1 libm.so.6 libnss_hesiod.so.2 libresolv.so.2libc-2.19.so libncurses.so.5 libnss_nis-2.19.so libselinux.so.1libcap.a libncurses.so.5.9 libnss_nisplus-2.19.so libtinfo.so.5libcap.so libncursesw.so.5 libnss_nisplus.so.2 libtinfo.so.5.9libcap.so.2 libncursesw.so.5.9 libnss_nis.so.2 libutil-2.19.solibcap.so.2.24 libnsl-2.19.so libpcre.so.3 libutil.so.1libc.so.6 libnsl.so.1 libprocps.so.3 libuuid.so.1libdl-2.19.so libnss_compat-2.19.so libpthread-2.19.so libz.so.1libdl.so.2 libnss_compat.so.2 libpthread.so.0libgpm.so.2 libnss_dns-2.19.so libpython2.7.so.1libm-2.19.so libnss_dns.so.2 libpython2.7.so.1.0
Configuration files that these commands depend on:
hchen@ubuntu:~/rootfs$ ls ./etcbash.bashrc group hostname hosts ld.so.cache nsswitch.conf passwd profileresolv.conf shadow
You will now say, I rely on, some configurations I want to set for the container when it starts, rather than hard code in the image. For example,/etc/hosts,/etc/hostname, And the/etc/resolv. conf file of DNS. Okay. Then, outside rootfs, we create another conf directory and put these files in this directory.
hchen@ubuntu:~$ ls ./confhostname hosts resolv.conf
In this way, our parent process can dynamically set the configurations of these files required by the container, and then mount them into the container. In this way, the configurations in the container image are more flexible.
Well, we finally got to our program.
# Define _ GNU_SOURCE # include # define STACK_SIZE (1024*1024) static char container_stack [STACK_SIZE]; char * const container_args [] = {"/bin/bash", "-l", NULL}; int container_main (void * arg) {printf ("Container [% 5d]-inside the container! /N ", getpid (); // set hostname sethostname (" container ", 10 ); // remount "/proc" to make sure the "top" and "ps" show container's information if (mount ("proc", "rootfs/proc ", "proc", 0, NULL )! = 0) {perror ("proc");} if (mount ("sysfs", "rootfs/sys", "sysfs", 0, NULL )! = 0) {perror ("sys");} if (mount ("none", "rootfs/tmp", "tmpfs", 0, NULL )! = 0) {perror ("tmp");} if (mount ("udev", "rootfs/dev", "devtmpfs", 0, NULL )! = 0) {perror ("dev");} if (mount ("devpts", "rootfs/dev/pts", "devpts", 0, NULL )! = 0) {perror ("dev/pts");} if (mount ("shm", "rootfs/dev/shm", "tmpfs", 0, NULL )! = 0) {perror ("dev/shm");} if (mount ("tmpfs", "rootfs/run", "tmpfs", 0, NULL )! = 0) {perror ("run");}/** copy the Docker configuration file from the external container * You can view: /var/lib/docker/containers // directory, * You will see the files of docker. */If (mount ("conf/hosts", "rootfs/etc/hosts", "none", MS_BIND, NULL )! = 0 | mount ("conf/hostname", "rootfs/etc/hostname", "none", MS_BIND, NULL )! = 0 | mount ("conf/resolv. conf", "rootfs/etc/resolv. conf", "none", MS_BIND, NULL )! = 0) {perror ("conf");}/* imitates-v in the docker run Command, -- volume = [] What the parameter does */if (mount ("/tmp/t1", "rootfs/mnt", "none", MS_BIND, NULL )! = 0) {perror ("mnt");}/* chroot isolation directory */if (chdir ("./rootfs ")! = 0 | chroot ("./")! = 0) {perror ("chdir/chroot");} execv (container_args [0], container_args); perror ("exec"); printf ("Something's wrong! /N "); return 1;} int main () {printf (" Parent [% 5d]-start a container! /N ", getpid (); int container_pid = clone (container_main, container_stack + STACK_SIZE, CLONE_NEWUTS | counter | CLONE_NEWPID | counter | SIGCHLD, NULL); waitpid (container_pid, NULL, 0); printf ("Parent-container stopped! /N "); return 0 ;}
When sudo runs the above program, you will see the following mount information and a so-called "image ":
hchen@ubuntu:~$ sudo ./mountParent [ 4517] - start a container!Container [ 1] - inside the container!root@container:/# mountproc on /proc type proc (rw,relatime)sysfs on /sys type sysfs (rw,relatime)none on /tmp type tmpfs (rw,relatime)udev on /dev type devtmpfs (rw,relatime,size=493976k,nr_inodes=123494,mode=755)devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)tmpfs on /run type tmpfs (rw,relatime)/dev/disk/by-uuid/18086e3b-d805-4515-9e91-7efb2fe5c0e2 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)/dev/disk/by-uuid/18086e3b-d805-4515-9e91-7efb2fe5c0e2 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)/dev/disk/by-uuid/18086e3b-d805-4515-9e91-7efb2fe5c0e2 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)root@container:/# ls /bin /usr/bin/bin:bash chmod echo hostname less more mv ping rm sleep tail test top truncate unamecat chown grep ip ln mount nc ps sed tabs tar timeout touch tty whichchgrp cp gzip kill ls mountpoint netstat pwd sh tac tee toe tr umount/usr/bin:awk env groups head id mesg sort strace tail top uniq vi wc xargs
For how to create a chroot directory, here is a tool called DebootstrapChroot. You can follow the link to see it (in English)
You can play the next thing on your own. I believe in your imagination. :)
Today's content will be introduced here. In the basic Docker technology: Linux Namespace (next), I will introduce you to User Namespace, Network Namespace, and other aspects of Namespace.
From: http:// OS .51cto.com/art/201609/517640.htm
Address: http://www.linuxprobe.com/docker-linux-namespace-1.html