Seven days, write a docker with go (the fourth day)

Time:2022-1-2

Project source code:Click to view the project source code

image

We used it in frontnamespaceandcgroupA simple container is built, but we can find that the directory in the container is still the directory of the currently running program. Here, an important feature such as image is missing. Here, we first use docker to pull the most compact imagebusybox, it is a box of many UNIX tools, providing a very complete and compact system.

#Pull busybox
docker pull busybox
#Run
docker run -d busybox top -b

#View container ID
docker ps

#Export container
docker export -o busybox.tar

Seven days, write a docker with go (the fourth day)
Seven days, write a docker with go (the fourth day)

You can see that we have successfully exported the contents of the container. Let me unzip it, and then use this folder as the read-only layer of the container.

mkdir busybox && tar -xvf busybox.tar -C busybox/

be careful:Later, for convenience, we put busybox Put tar under the / root path

When docker starts the container, it will create two new layers, write layer and container layer. Write layer is the only read-write layer of the container, and container layer is the new read-only layer for the container. Here, we take busybox as this layer, the read-write layer, and we create onewriteLayerFolder as this layer, then mount the two folders under the same folder, and then take this folder as the startup directory of the container. This folder is namedmnt

Linux mount folder

Here we have three folders,mnt writeLayer busybox, we willwriteLayer busyboxThese two folders are mounted tomntUnder the folder, you can seemntandwriteLayerAll folders are empty, onlybusyboxThere’s something under the folder. Let’s have a look after we mount it

Seven days, write a docker with go (the fourth day)

#Mount
 mount -t aufs -o dirs=/root/writeLayer:/root/busybox none /root/mnt

Seven days, write a docker with go (the fourth day)

As you can see,mntAlready appearedbusyboxWhat’s in the folder, and we’re herewriteLayerCreate a new folder under the folder and see what happens

Seven days, write a docker with go (the fourth day)

It can be clearly seen that we are rightwriteLayerWhat you do is mapped tomntUnder the folder, docker is also implemented in this way. Every time you modify something in the container, it will not affect the image, because all the operations you do arewriteLayerLayer, and the mirror is inbusybox, that iscontainer-initLayer.

Go implementation mount

func NewWorkSpace(rootPath string, mntPath string, volume string) error {
    // 1.  Create read-only layer
    err := createReadOnlyLayer(rootPath)
    if err != nil {
        logrus.Errorf("create read only layer, err: %v", err)
        return err
    }
    // 2.  Create a read-write layer
    err = createWriteLayer(rootPath)
    if err != nil {
        logrus.Errorf("create write layer, err: %v", err)
        return err
    }
    // 3.  Create a mount point to mount the read-only layer and read-write layer to the specified location
    err = CreateMountPoint(rootPath, mntPath)
    if err != nil {
        logrus.Errorf("create mount point, err: %v", err)
        return err
    }
    return nil
}

In short, there are three steps. The first step is to create a read-only layer, the second step is to create a read-write layer, and the third step is to mount them in the same folder. The specific implementation is also relatively simple, that is, to create a folder. Here’s how to mount them

func CreateMountPoint(rootPath string, mntPath string) error {
    _, err := os.Stat(mntPath)
    if err != nil && os.IsNotExist(err) {
        err := os.MkdirAll(mntPath, os.ModePerm)
        if err != nil {
            logrus.Errorf("mkdir mnt path, err: %v", err)
            return err
        }
    }

    dirs := fmt.Sprintf("dirs=%s%s:%s%s", rootPath, common.WriteLayer, rootPath, common.BusyBox)
    cmd := exec.Command("mount", "-t", "aufs", "-o", dirs, "none", mntPath)
    if err := cmd.Run(); err != nil {
        logrus.Errorf("mnt cmd run, err: %v", err)
        return err
    }
    return nil
}

The article will start on my WeChat official account, scan code attention, and get the latest content in time.

Seven days, write a docker with go (the fourth day)

This work adoptsCC agreement, reprint must indicate the author and the link to this article

Recommended Today

Explanation of websocket heartbeat reconnection

Recently, websocket has been used in the development of applet. The applet provides corresponding native API, which is different from H5 API. Therefore, some mature class libraries of popular H5 are difficult to use, and the native API has some defects, so it implements a set of heartbeat reconnection mechanism by itself. First, let’s briefly […]