Creating and Building Private Libraries for Docker Mirrors

1. Creation method of Docker image
In addition to docker's core technology, docker mirroring is also a standard format for application publishing.A complete docker image can support the operation of a docker container. After entering a customized container during the entire use of the docker, it can operate in the container. The most common operation is to install application services in the container. If you want to migrate the installed services, you need to generate a new image of the environment and the services you set up.

There are three ways to create a mirror, one based on an existing image, one based on a local template, and one based on a dockerfile.

1. Create based on existing mirrors
Creating based on an existing image mainly uses the docker commit command, which essentially packages the program running in a container and the environment in which it runs to generate a new image.

Command format: docker commit [options] container ID/name repository name: [label]
Common Options
-m: Description information;
-a: Author information;
-p: stop the container running during the build process;

Start a mirror, make changes in the container, and then submit the modified container as a new image. You need to remember the ID number of the container

[root@test /]# docker ps -a                   # View Current Container
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMES
bdd5bb814008   "/ /b..."   5 seconds ago       Created                                 stupefied_ptolemy
[root@test /]# docker exec -it bdd5bb814008 /bin/bash            # Enter the container and create a test file
root@bdd5bb814008:/# ls
bin  boot  core  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@bdd5bb814008:/# touch test.txt
root@bdd5bb814008:/# exit
[root@test /]# docker commit -m "newdhcp" -a "test" bdd5bb814008 docker:mydhcp          # Create an existing container as a mirror
[root@test /]# docker images  | grep docker              # View the image you just created
docker                        mydhcp              d6197c6e3f65        24 seconds ago      125 MB   latest              6f98b6b9b486        19 months ago       125 MB
[root@test /]# docker create -it docker:mydhcp /bin/bash               # Add as Container
[root@test /]# docker ps -a
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMES
ea434b08d511        docker:mydhcp                 "/ /b..."   25 seconds ago      Created                                 compassionate_shirley
bdd5bb814008   "/ /b..."   5 minutes ago       Up 4 minutes                            stupefied_ptolemy
[root@test /]# docker start ea434b08d511                        # Start the container
[root@test /]# docker exec -it ea434b08d511 /bin/bash             # Enter the container to view the test file you just created
root@ea434b08d511:/# ls
bin  boot  core  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test.txt  tmp  usr  var

2. Create based on local templates
Mirrors can be generated by importing operating system template files, which can be downloaded from OPENVZ open source projects at:

[root@test /]# wget
# Download a mini version of the Ubuntu template
[root@test /]# cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - docker:new
# Import Template
[root@test /]# docker images |grep new              # View Imported
docker                        new                 7457fecee0fb        About a minute ago   215 MB

3. Create based on Dockerfile
A dockerfile is a file that consists of a set of instructions, each corresponding to a command in Linux, and the docker program reads the instructions in the dockerfile to generate a specified image.

The dockerfile structure is roughly divided into four parts: basic mirroring information, maintainer information, mirroring instructions, and execution instructions at container startup.Dockerfile supports one instruction per line, multiple parameters per instruction, and comments starting with the'#'number.
Description of configuration items in dockerfile:

[root@localhost ~]# docker tag docker:new centos7:system            
#Change the name and label of the centos 7 Mini image downloaded above to distinguish it
[root@localhost ~]# docker images | grep system             
#Verify that the underlying mirror is ready (that is, a centos 7 mini system is in progress)
centos7                       system              c065d5c0571d        About an hour ago   435 MB
[root@localhost ~]# vim Dockerfile   #Edit a Dockerfile, note that the best file name is a Dockerfile

FROM centos           #The first line must specify the underlying mirror on which to base (it must exist)
MAINTAINER The centos project <>    #User information to maintain the image
#Here are the instructions for mirroring
RUN yum -y update      
RUN yum -y install openssh-server
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
EXPOSE 22       #Open port 22
CMD ["/usr/sbin/sshd","-D"]     #Execute instructions when starting containers

When writing a dockerfile, there is a strict format to follow: the first line must use the FROM directive to specify the name of the image on which it is based; the next line must use the MAINTAINER directive to specify the user information to maintain the image; the next is the directive related to the mirroring operation, such as the RUN directive, which adds a new layer to the underlying image for each run; and the last line must use the CMD directive to specify the boot containerThe command action to run when.

There are more than a dozen commands for dockerfile to build a mirror, and the common ones are as follows:

Example: Create an apache image using dockerfile and run it in a container

[root@test /]# mkdir apache                        # Create working directory
[root@test /]# cd /apache/
[root@test apache]# vim Dockerfile                # Create and write Dockerfile files
FROM    centos                               # The base mirror centos based on
MAINTAINER      the centos            # User information to maintain the image
RUN     yum -y update                     # Mirror Operations Instructions Install Apache Package
RUN     yum -y install httpd 
EXPOSE  80                                    # Open port 80
ADD     index.html /var/www/html/index.html               # Copy the first page file of the site
ADD /                     # Copy execution script to mirror
RUN     chmod 775 /             
RUN     systemctl disable httpd           # Set Apache service not to start by itself
CMD     ["/"]                     # Execute script when starting container

[root@test apache]# vim                     # Write execution scripts
rm -rf /run/httpd/*                           # Clean up httpd cache
exec /usr/sbin/apachectl -D FOREGROUND                # Start Apache Service
[root@test apache]# echo "" > index.html                 # Create Test Page
[root@test apache]# ls
Dockerfile  index.html
[root@test apache]# docker build -t httpd:centos .               
............................               // Omit some content
# Note: This command is followed by a "." representing the current path, otherwise an error will be made, remember that don't forget
[root@test apache]# docker run -d -p 12345:80 httpd:centos               # Using the new mirror to run the container, -p option implements port mapping from local port 12345 to container port 80
[root@test apache]# docker ps -a             # View Containers
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                   NAMES
0721b1641ce0        httpd:centos                  "/"                6 seconds ago       Up 6 seconds>80/tcp   sad_mcclintock

Accessing apache services in containers

2. Build private libraries and how to use them
As the number of mirrors created increases, there needs to be a place to store the image, which is the warehouse. There are two kinds of warehouses: public warehouse and private warehouse. Most of the company's production environment is saved to private warehouse. The easiest way is to download the image in public warehouse. If you upload the image to public warehouse, you also need to register and log on. About public warehouse uploadPass, refer to
How do I build a private warehouse?You can use registry to build a local private warehouse

[root@test ~]# docker search registry               #Query keyword "registry"
INDEX       NAME                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED                            The Docker Registry 2.0 implementation for...   2679      [OK]       
                 ..................#Omit some content
[root@localhost ~]# docker pull     #Download Top Mirrors
                 ..................#Omit some content
Status: Downloaded newer image for    #Download Successful
[root@localhost ~]# vim /etc/sysconfig/docker           
#Modify docker configuration file to specify private repository URL, otherwise error will occur when uploading mirror in custom private repository

# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --insecure-registry='
#Change the line above where the IP address is the IP address of the private warehouse server, and here is the local IP address.
                           ..................#Omit Part
#Save Exit After Modification
[root@test ~]# systemctl restart docker      #Restart docker

Start a container with the downloaded registry image. By default, the warehouse is stored in the container's / tmp/registry directory. Use the -v option to mount the local directory into the container's / tmp/registry directory for use, so that the image will be lost when the container is deleted.Start a private warehouse service locally with a listening port number of 5000.

Note: I have a / data/registry directory locally (mounting a highly available GFS file system or using NFS is optional, but it is recommended that for important data storage directories, dynamic capacity expansion and data loss due to disk corruption) be mounted in the / tmp/registry directory in a private warehouse container for storageMirror file uploaded to private repository.

[root@test ~]# df -hT /data/registry/             #View the file system used by my directory
//File System Type Capacity Used Available%Mountpoint
node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry
[root@test ~]# docker run -d -p 5000:5000 -v /data/registry/:/tmp/registry
#Start the private repository and map the port to the host's 5000 port, mount the local / data/registry directory to the container's / tmp/registry directory is the private repository image you just downloaded.
[root@test ~]# docker tag     
#Use the docker tag command to change the tag of the mirror to be uploaded, where the IP and port are fixed, otherwise you cannot connect to the private repository
#Because a port mapping was done while running the container above, the port number of the private repository was mapped to the 5000 end of the host machine
#So direct access to the host's port 5000 is equivalent to access to a private repository.
[root@test ~]# docker images | grep 5000            #Find mirror to upload     latest              f32a97de94e1        6 months ago        25.8 MB
[root@test ~]# docker push            #Upload to just running private repository
The push refers to a repository []
73d61bf022fd: Pushed 
5bbc5831d696: Pushed 
d5974ddb5a45: Pushed 
f641ef7a37ad: Pushed 
d9ff549177a9: Pushed 
latest: digest: sha256:b1165286043f2745f45ea637873d61939bff6d9a59f76539d6228abf79f87774 size: 1363
#Next, upload another mirror to test.
[root@test ~]# docker images | grep mynamed            #Upload it
docker                        mynamed             e178f320e482        4 hours ago         323 MB
[root@test ~]# docker tag docker:mynamed    
#As a rule, you must change the name of the warehouse. Note: If the label is not the default latest, you also need to add the label name after the warehouse name
[root@test ~]# docker images | grep     #Determine that the change was successful        test                e178f320e482        4 hours ago         323 MB
[root@test ~]# docker push       #Upload to Private Warehouse
The push refers to a repository []
c756b9ec7fb0: Pushed 
7d8d01394159: Pushed 
72b7cd87d69b: Pushed 
3be48ef75683: Pushed 
9b28c58ad64b: Pushed 
75e70aa52609: Pushed 
dda151859818: Pushed 
fbd2732ad777: Pushed 
ba9de9d8475e: Pushed 
test: digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f size: 2403

At this point, the testing is complete, but how can I prove that the private repository uses the local/data/registry directory?And how do I view the uploaded image?(Mirrors uploaded to a private repository cannot be viewed using the normal ls command).

[root@test ~]# df -hT /data/registry/           #View the local/data/registry/mounted file system first
//File System Type Capacity Used Available%Mountpoint
node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry
[root@test ~]# docker exec -it a6bf726c612b /bin/sh 
#Containers that enter a private warehouse do not have/bin/bash, so/bin/sh is used.
/ # df -hT /tmp/registry/   #Looking at it, we found that the file system mounted by this directory is the same as that mounted by the host machine, indicating that it is OK.
Filesystem           Type            Size      Used Available Use% Mounted on
node4:dis-stripe     fuse.glusterfs
                                    80.0G    129.4M     79.8G   0% /tmp/registry
#So how do you view the image uploaded to the private repository?Look at the following:
[root@test ~]# curl -XGET   
#Look at the uploaded images and you can see the two images you just uploaded
#Knowing only the name of a mirror is not enough. To download, you also need the corresponding label of the mirror. How do you view the label of a mirror?
[root@test ~]# curl -XGET
#Look at it like this. The name in the URL path above is the mirror name. Look at the label corresponding to the mirror name
[root@test ~]# docker pull      #Download mirrors from private repositories
#You must specify the access address of the private repository, that is, what is the name of the upload and what is the download, even if there is no IP address in the mirror name of the query.
Trying to pull repository ... 
sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f: Pulling from
Digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f
Status: Downloaded newer image for

If you need to download a mirror of a private warehouse on another server, you need to execute the following command on that other server to specify the private warehouse server address:

[root@node1 ~]# echo '{ "insecure-registries":[""] }' > /etc/docker/daemon.json
#Where represents the IP address and port to access the private warehouse, depending on your server situation
[root@node1 ~]#systemctl restart docker          #Restart docker service

Tags: Docker Apache CentOS ssh

Posted on Thu, 28 Nov 2019 10:05:17 -0800 by tinyang