Doker Mirror Management Foundation

Doker Mirror Management Foundation

The concept of mirroring

Mirroring can be understood as an application container, while docker is used to load and unload containers.

The docker image contains the file system and its contents needed to start the container, so it is used to create and start the container.

The docker image uses a hierarchical construction mechanism, with bootfs at the bottom and rootfs above it

  • bootfs: A file system for system boot, including bootloader and kernel, that will be unloaded when the container is started to save memory resources
  • rootfs: on top of bootfs, as the root file system of the docker container
    • In traditional mode, when the system starts, the kernel mounts rootfs to read-only mode first, and then reloads them to read-write mode after completing the integrity self-check
    • In docker, rootfs are mounted in "read-only" mode by the kernel, then an additional "writable" layer is mounted through "joint mounting" Technology

Note: When a container is deleted, its own Writable layer is deleted together

docker mirror layer

The mirror at the bottom is called the parrent image, and the bottom is called the base image.
At the top is the Read-Write layer, and below it are the Read-Only layer.

docker storage driver

Doker provides a variety of storage drivers to store mirrors in different ways. Here are several common storage drivers:

  • AUFS
  • OverlayFS
  • Devicemapper
  • Btrfs
  • VFS

AUFS

AUFS (AnotherUnionFS) is a Union FS and is a file-level storage driver. AUFS is a layered file system that transparently covers one or more existing file systems, combining layers into a single representation of the file system. Simply put, it supports mounting different directories to a file system under the same virtual file system. This file system can overlay modified files one by one. No matter how many layers are read-only below, only the top file system is writable. When a file needs to be modified, AUFS creates a copy of the file, uses CoW to copy the file from the read-only layer to the writable layer for modification, and the results are saved in the writable layer. In Docker, the bottom read-only layer is image, and the writable layer is Container.

The AUFS filesystem is said to have 3W lines of code, whereas the ext4 filesystem only has around 4000-5000 lines of code to be integrated into the kernel. When the AUFS application was later merged into the kernel code, linuz rejected the code because it was too bloated. So AUFS is not always the file system in the linux kernel. If you want to use AUFS, you have to patch the kernel and compile and use it yourself. But the operating systems of the redhats are known for their stability and will not do this extraordinary thing, so it is impossible to use AUFS in the redhats. The docker on ubuntu uses AUFS by default.

OverlayFS

Overlay is supported after the Linux kernel 3.18 and is also a Union FS. Unlike AUFS, there are only two layers of Overlay: an upperfile system and a lower file system, representing the mirror and container layers of Docker, respectively. When a file needs to be modified, use CoW to copy the file from a read-only lower to a writable upper for modification, and the result is saved at the upper layer. In Docker, the bottom read-only layer is image, and the writable layer is Container. The latest OverlayFS is Overlay2.

AUFS and Overlay are both federated file systems, but AUFS has multiple layers, while Overlay has only two, so AUSF is slower when copying large files with lower layers when writing. And Overlay incorporates the linux kernel mainline, which AUFS does not. At present, AUFS has been basically eliminated.

DeviceMapper

Device mapper is supported after Linux kernel 2.6.9. It provides a mapping framework mechanism from logical devices to physical devices, under which users can easily formulate management strategies to implement storage resources according to their needs. AUFS and OverlayFS are file-level storage, while Device mapper is block-level storage, and all operations operate directly on blocks, not files. The Device mapper driver first creates a resource pool on the block device, then creates a basic device with a file system on the resource pool. All mirrors are snapshots of this basic device, while containers are snapshots of mirrors. So you see in the container that the file system is a snapshot of the file system of the basic device on the resource pool, and no space is allocated to the container. When a new file is to be written, a new block is allocated to it within the mirror of the container and data is written. This is called time-of-use allocation. When you want to modify an existing file, use CoW to allocate block space for the container snapshot, and copy the modified data into a new block in the container snapshot before making the modification.

OverlayFS is file-level storage, Device mapper is block-level storage. When a file is very large and the content modified is small, Overlay copies the entire file regardless of the size of the content modified. It obviously takes more time to modify a large file than a small one. Block-level copies only the blocks that need to be modified, not the entire file. In this scenario, apparently the device mapper is faster. Because the block level has direct access to the logical disk, it is suitable for IO-intensive scenarios. Overlay is relatively better for scenarios with complex internal programs, large concurrencies, but less IO.

docker registry

When the container is started, docker daemon attempts to get the associated image locally, which is downloaded from Registry and saved locally when the local image does not exist.

Registry is used to save docker images, including the hierarchy and metadata of the images. Users can build their own Registry or use the official Docker Hub.

Classification of docker registry:

  • Sponsor Registry: Third-party Registry for use by customers and the Docker community
  • Mirror Registry: Third-party Registry, for customer use only
  • Vendor Registry: Regisry provided by vendor publishing docker image
  • Private Registry: registry provided through a private entity with a firewall and additional security layer

Composition of docker registry:

  • Repository
    • A mirror repository consisting of all iterated versions of a particular docker image
    • Multiple Repositories may exist in a Registry
      • Repository can be divided into Top Warehouse and User Warehouse
      • User repository name format is User/Repository Name
    • Each warehouse can contain multiple Tags, each with a mirror image
  • Index
    • Maintain information about user accounts, mirror checks, and public namespaces
    • Equivalent to providing Registry with a retrieval interface that performs functions such as user authentication

Mirrors in a Docker Registry are usually created by developers and then pushed to a Public or Private Registry for other people to use, such as "deploying" to a production environment.

Making docker image

In most cases, we do mirroring based on an existing basic image of someone else, which we call a base image. For example, a clean version of the minimal centos, ubuntu, or debian.

So where does this minimal centos image come from? In fact, this basic image is usually manually created by the relevant maintainers of Docker Hub, the official Docker. This basic image is easy for Docker's official professionals, but not for end users.

Docker Hub

Docker Hub is a cloud-based registration service that allows you to link to code libraries, build and test your mirrors, store manually pushed mirrors, and link to Docker Cloud so you can deploy your mirrors on your host.

It provides centralized resources for container image discovery, distribution and change management, user and team collaboration, and workflow automation throughout the development pipeline.

[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
[root@localhost ~]# docker run --name centos01 -it centos
[root@0b9a530c25c2 /]# useradd -r -M -s /sbin/nologin nginx
[root@0b9a530c25c2 /]# id nginx
uid=998(nginx) gid=996(nginx) groups=996(nginx)

[root@0b9a530c25c2 /]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make
[root@0b9a530c25c2 /]# yum -y groups mark install 'Development Tools'

[root@0b9a530c25c2 /]# mkdir -p /var/log/nginx
[root@0b9a530c25c2 /]# chown -R nginx.nginx /var/log/nginx


[root@localhost ~]# docker cp /usr/local/nginx-1.20.1.tar.gz centos01:/usr/src
[root@0b9a530c25c2 ~]# ls /usr/src/
debug  kernels  nginx-1.20.1.tar.gz

[root@0b9a530c25c2 src]# tar xf nginx-1.20.1.tar.gz 
[root@0b9a530c25c2 src]# cd nginx-1.20.1
[root@0b9a530c25c2 nginx-1.20.1]# ./configure \
>  --prefix=/usr/local/nginx \
>  --user=nginx \
>  --group=nginx \
>  --with-debug \
>  --with-http_ssl_module \
>  --with-http_realip_module \
>  --with-http_image_filter_module \
>  --with-http_gunzip_module \
>  --with-http_gzip_static_module \
>  --with-http_stub_status_module \
>  --http-log-path=/var/log/nginx/access.log \
>  --error-log-path=/var/log/nginx/error.log

[root@0b9a530c25c2 nginx-1.20.1]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install


[root@0b9a530c25c2 nginx-1.20.1]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@0b9a530c25c2 nginx-1.20.1]# source /etc/profile.d/nginx.sh
[root@0b9a530c25c2 nginx-1.20.1]# nginx
[root@0b9a530c25c2 nginx-1.20.1]# ss -anlt
State  Recv-Q Send-Q  Local Address:Port   Peer Address:Port Process                                                      
LISTEN 0      128           0.0.0.0:80          0.0.0.0:*    

Docker Hub offers the following main features:

  • Mirror warehouse
    • Find and extract mirrors from community and official repositories, and manage, push, and extract mirrors from private repositories that you can access.
  • Automation Construction
    • Automatically create a new image when you change the source code repository.
  • Webhooks
    • A webhook is a feature of automated build that allows you to trigger actions when successfully pushed to a mirror repository.
  • organization
    • Create a workgroup to manage access to the mirror warehouse.
  • GitHub and Bitbucket Integration
    • Add hub and Docker images to the current workflow.

Obtaining docker image

To get a Docker image from a remote registry, such as your own Docker registry, and add it to your local system, use the Docker pull command

docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>

Host providing docker distribution service over TCP (default 5000).

Identify specific images controlled by the registry

  • The registry also supports raw; Raw is optional for these registries
  • When included, the additional hierarchy provided is useful for distinguishing mirrors with the same functionality

Additional Hierarchy Levels

NamespaceExamples(/)
organizationredhat/kubernetes, google/kubernetes
login(username)Alice/application, bob/application
roledevel/database, test/database, prod/database

Mirror Generation

The generation of mirrors:

  • Dockerfile
  • Container-based manufacturing
  • Docker Hub automated builds

Container-based mirroring

Create a new image based on container changes

Usage:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OptionsDefaultDescription
—author, -aAuthor (e.g., "John Hannibal Smith hannibal@a-team.com")
-c, --change listApply Dockerfile instruction to the created image
-m, --message stringCommit message
-p, --pausetruePause container during commit

Pull the official image of centos

[root@localhost ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest

[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    5d0da3dc9764   2 months ago   231MB

Run container using centos image

[root@localhost ~]# docker run -d --name centos01 -it centos /bin/bash
e7e164c48aaad085e7cd9e1dee327c0ac322cb62bd8ed847d0e35436165b6d6e
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
e7e164c48aaa   centos    "/bin/bash"   6 seconds ago   Up 5 seconds             centos01

Use the docker exec command to enter the centos2 container

[root@localhost ~]# docker run -d --name centos01 -it centos /bin/bash
e7e164c48aaad085e7cd9e1dee327c0ac322cb62bd8ed847d0e35436165b6d6e
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
e7e164c48aaa   centos    "/bin/bash"   6 seconds ago   Up 5 seconds             centos01
[root@localhost ~]# docker exec -it e7e164c48aaa /bin/bash
[root@e7e164c48aaa /]# ls 
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@e7e164c48aaa /]# 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
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

After the container is working properly, upload the nginx source package from the local machine to the directory specified by the container

[root@localhost ~]# docker cp /usr/src/nginx-1.20.1.tar.gz e7e164c48aaa:/usr/src

Use the docker exec command to enter the container and compile nginx

Download compilation tools
[root@e7e164c48aaa ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make

Establish nginx user
[root@e7e164c48aaa ~]# useradd -r -M -s /sbin/nologin nginx
[root@e7e164c48aaa ~]# id nginx
uid=998(nginx) gid=996(nginx) groups=996(nginx)

Establish nginx Log Directory
[root@e7e164c48aaa ~]# mkdir -p /var/log/nginx
[root@e7e164c48aaa ~]# chown -R nginx.nginx /var/log/nginx/

Compile Installation nginx
[root@e7e164c48aaa ~]# cd /usr/src/
[root@e7e164c48aaa src]# ls
debug  kernels  nginx-1.20.1.tar.gz
[root@e7e164c48aaa src]# tar xf nginx-1.20.1.tar.gz 
[root@e7e164c48aaa src]# cd nginx-1.20.1
[root@b19e7e164c48aaa nginx-1.20.1]# ./configure \
>  --prefix=/usr/local/nginx \
>  --user=nginx \
>  --group=nginx \
>  --with-debug \
>  --with-http_ssl_module \
>  --with-http_realip_module \
>  --with-http_image_filter_module \
>  --with-http_gunzip_module \
>  --with-http_gzip_static_module \
>  --with-http_stub_status_module \
>  --http-log-path=/var/log/nginx/access.log \
>  --error-log-path=/var/log/nginx/error.log

[root@e7e164c48aaa nginx-1.20.1]# make && make install

Configuring environment variables
[root@e7e164c48aaa ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@e7e164c48aaa ~]# source /etc/profile.d/nginx.sh
[root@e7e164c48aaa ~]# nginx
[root@e7e164c48aaa ~]# ss -anlt
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:80         0.0.0.0:*           

Local access

[root@localhost ~]# curl 172.17.0.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Edit a self-start script

[root@e7e164c48aaa ~]# cd /
[root@e7e164c48aaa /]# vi start.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
/bin/bash
[root@e7e164c48aaa /]# chmod +x start.sh 
[root@e7e164c48aaa /]# exit

Once set up, make a mirror of this container

[root@localhost ~]# docker commit -p e7e164c48aaa
sha256:f4fe4bec94e8feb6c589f2b47ca3d95672bf0f4d5aeede8ea17793ed251ac027
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
<none>       <none>    f4fe4bec94e8   8 seconds ago   549MB
centos       latest    5d0da3dc9764   2 months ago    231MB
[root@localhost ~]# docker tag f4fe4bec94e8 syb1978974056:v0.2
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
syb1978974056   v0.2      f4fe4bec94e8   42 seconds ago   549MB
centos          latest    5d0da3dc9764   2 months ago     231MB

Run a container with the newly generated image

[root@localhost ~]# docker run -itd --name centos02 -p 8080:80 f4fe4bec94e8 /start.sh
ce2c73d304c7de2ef6974475260608147e1f0a0870f4f9b7cba904a9faae68b0
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS                                   NAMES
ce2c73d304c7   f4fe4bec94e8   "/start.sh"   46 seconds ago   Up 44 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   centos02
e7e164c48aaa   centos         "/bin/bash"   15 minutes ago   Up 15 minutes                                           centos01

Enter Container to View

[root@localhost ~]# docker exec -it e7e164c48aaa /bin/bash
[root@e7e164c48aaa /]# ss -anlt
State  Recv-Q Send-Q  Local Address:Port   Peer Address:Port Process                                                      
LISTEN 0      128           0.0.0.0:80          0.0.0.0:*    

Browser Test

Upload mirror to docker hub repository

Access and login docker hub Official
Create warehouse

The warehouse name here corresponds to the mirror name one-to-one

After the warehouse is created, log in to docker hub locally and push to mirror it in the docker hub warehouse

[root@localhost ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: syblyw0806
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
[root@localhost ~]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
syblyw0806/test   v0.3      f4fe4bec94e8   39 minutes ago   549MB
centos            latest    5d0da3dc9764   2 months ago     231MB

[root@localhost ~]# docker push syblyw0806/test:v0.3
The push refers to repository [docker.io/syblyw0806/test]
eb596e259ddf: Pushed 
74ddd0ec08fa: Mounted from library/centos 
v0.3: digest: sha256:b9c4bbc468350c60ccabb654e16e7ae664acb88fc72ead41356b1ef63c8f4a46 size: 742

Import and Export of Mirrors

If there are 2 hosts, we have made a mirror on host 1. What do host 2 want to do with this mirror?

We can push the image into the mirror warehouse on Host 1, then pull the image down on Host 2, which is a bit of a hassle. If I'm just testing it, I can run on another host after I've finished mirroring on one host. There's no need to push it onto the warehouse and pull it back locally.

At this point, we can package the image into a compressed file based on the existing image and copy it to another host to import it. This is the import and export function of the image.

In docker we use docker save for export and docker load for import.

Execute docker save export mirror on the host where the mirror has been generated

docker save -o myimages.gz syblyw0806/test

Perform docker load import mirroring on another host that is not mirrored

docker load -i myimages.gz

Keywords: Operation & Maintenance Docker Container

Added by Disgrntld on Thu, 02 Dec 2021 19:28:36 +0200