Linux rootfs

foreword

Through " initrd&init process ", we know that rootfs is the root directory of the file system, which contains all the files and directories required by the operating system, including programs, library files, configuration files, device files, etc., which are files that must be loaded when the system starts one of the systems. When the system starts, the kernel will first mount the rootfs to the / directory, and then start running the init process to perform various initialization tasks.

make rootfs

  1. Download busybox source code
git clone git://git.busybox.net/busybox
  1. compile busybox
## 使用默认配置
make defconfig

## 或者自定义配置
make menuconfig

make install 
  1. cross compile
## 去下载交叉编译环境
wget https://releases.linaro.org/components/toolchain/binaries/6.4-2018.05/arm-linux-gnueabi/gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabi.tar.xz

## 解压
tar xvf gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabi.tar.xz -C  /opt/

## 配置动态编译
make menuconfig

Settings  --->
	--- Build Options
	(arm-linux-gnueabi-) Cross compiler prefix 

## 编译
exports ARCH=arm
exports CROSS_COMPILE=arm-linux-gnueabi-	
make
make install	
  1. Configure the busybox startup environment
    insert image description here
## 复制busybox编译好的进 rootfs文件
cp _install/* ../rootfs/

## 查看你新环境命令要支持的库
ldd bin/sh
	linux-vdso.so.1 (0x00007ffd8c19f000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f714889a000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f7148680000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f714828f000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f7148f3f000)

## 创建文件,并把库同路径移过来
mkdir lib lib64
cp /lib/x86_64-linux-gnu/*.so.*   lib/x86_64-linux-gnu/
cp /lib64/*.so.*  lib64/

## 如果是交叉编译的话移的是交叉环境里的库
cp /opt/gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/lib ../rootfs  -rap

## 初始化配置
mkdir etc
cp ./examples/bootfloppy/etc/*  etc
mkdir dev  proc sys tmp var
## 修改/etc/init.d/rcS
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH

mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts

echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

## 修改/etc/fstab 主要是配置一些基本的文件系统挂载信息
proc            /proc           proc    defaults        0       0
tmpfs           /tmp            tmpfs   defaults        0       0
sysfs           /sys            sysfs   defaults        0       0

Use of rootfs

There are two main ways to use rootfs, chroot and pivot_root

chroot

chroot is to change the root directory of a process so that the process cannot access other directories outside the directory.

sudo chroot .
pivot_root isolation

pivot_root puts the root file system of the current process in the put_old directory, and makes new_root a new root file system
to change the working directory of all processes or threads in the current working directory. This is very different from chroot, which only changes The root directory of a process to be run. pviot_root is mainly to switch the entire system to a new root directory, and then remove the dependence on the previous rootfs, so that the file system before umount can be used (pivot_root requires root permissions)

unshare --mount --fork /bin/bash #需要有独立的命名空间
mkdir /new-root
mount -t tmpfs mytmpfs  /new-root #new-root是一个独立的挂载点
cd /new-root
mkdir old-root  #注意可以不创建old-root文件夹直接使用tmp文件夹
cp -r /ushare/busybox/* /new-root/ #new_root文件夹里面有完整rootfs的各种文件
cd ..
pivot_root /new-root/ /new-root/old-root
cd /
  1. Must be used with namespace
  2. With pivot_root, each manufacturer can create its own rootfs (that is, mirror) and provide it to container manufacturers before docker

Custom images in containers

The premise of building a mirror is that it must rely on the base mirror (provided by major manufacturers), there are two main ways in docker

  1. Use the docker commit command to build an image based on an existing container.
  2. Write a Dockerfile and use the docker build command to build the image.

The first method is equivalent to installing a plug-in based on the base image, and then packaging a mirror image.
The second method is to write a configuration file and parse the content of the file at runtime to build it.

Docker image construction method usage scenarios and selection

The docker commit image construction method is usually used in the following two scenarios:

  • Build a temporary test image;
  • After the container is compromised, use docker commit to build an image based on the compromised container, so as to keep the site and facilitate future traceability.

Except for these two scenarios, I do not recommend that you use docker commit to build a mirror image of the production live network environment. The reasons are as follows:

  1. The image built using docker commit contains a large number of useless files generated by compiling and building, installing software, and running the program, which will cause the image to be very large and bloated.
  2. The image built using docker commit will lose all the operation history of the image, and the image construction process cannot be restored, which is not conducive to the maintenance of the image.
  3. The operation process of Dockerfile can be queried through docker image history [image name], which is convenient for developers to view change records.

Assuming that the size of an image file is 500MB, if you start 100 containers, you need to download a file of 500MB*100= 50GB and occupy 50GB of disk space

Union File System UnionFS

To solve this problem, use UnionFS - Union File System. In fact, you can understand its essence by using the following picture:
insert image description here
the above picture is the way we said that 50GB is required to start 100 containers, and the following is the use of the joint file system-that is, file sharing!

It can be seen from the figure that all APPs share the "ubuntu:18.04" distribution file system, so if the size of an image file is 500MB, the operating system is 400M, and the APP is 100M, 100 containers only need 400MB + 100MB * 100 = about 1G400M, which is far less than 50GB.

There are many types of UnionFS, and the union file systems currently supported by Docker include OverlayFS, AUFS, Btrfs, VFS, ZFS and Device Mapper

> docker history golang:1.19.3-alpine
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
c50491847fcb   6 months ago   /bin/sh -c #(nop) WORKDIR /go                   0B        
<missing>      6 months ago   /bin/sh -c mkdir -p "$GOPATH/src" "$GOPATH/b…   0B        
<missing>      6 months ago   /bin/sh -c #(nop)  ENV PATH=/go/bin:/usr/loc…   0B        
<missing>      6 months ago   /bin/sh -c #(nop)  ENV GOPATH=/go               0B        
<missing>      6 months ago   /bin/sh -c set -eux;  apk add --no-cache --v…   343MB     
<missing>      6 months ago   /bin/sh -c #(nop)  ENV GOLANG_VERSION=1.19.3    0B        
<missing>      6 months ago   /bin/sh -c #(nop)  ENV PATH=/usr/local/go/bi…   0B        
<missing>      6 months ago   /bin/sh -c set -eux;  if [ -e /etc/nsswitch.…   0B        
<missing>      6 months ago   /bin/sh -c apk add --no-cache ca-certificates   515kB     
<missing>      6 months ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      6 months ago   /bin/sh -c #(nop) ADD file:57d621536158358b1…   5.29MB   

The docker history is that the order of operations is viewed from bottom to top, such as the last one

<missing>      6 months ago   /bin/sh -c #(nop) ADD file:57d621536158358b1…   5.29MB  

That is to say, the first from alpine of dockerFile

file:57d621536158358b1… 

The file ID of the corresponding UnionFS

main reference

" <linux> busybox making rootfs "
" Busybox making basic rootfs "
" chroot and pivot_root summary of complete chroot and pivot_root usage examples "
" About making Docker images?" | Dockerfile Quick Start "
" Deep Learning Docker - OverlayFS Joint File System "

Guess you like

Origin blog.csdn.net/y3over/article/details/130626506