How dockerfile constitutes an image must be seen in R & D, operation and maintenance

docker command basic framework

As shown in the figure, all docker operations are basically inseparable from the image, so the image operation will be. However, how is the image formed?

The functions and uses of mirroring are as follows:

image

Docker image is the basis for creating containers. It is a read-only template that can be used to create docker containers. It is similar to snapshots of virtual machines. It can be understood as a read-only template for docker container engine. For example, an image can be a complete Centos operating system environment, called a Centos image: it can be an application with MySQL installed, called a MySQL image, etc. we can package everything we need into an image. If the packaged image can run on a machine, it can run on any machine with docker

Here are some supplements to the image

What is mirroring?

Image is a lightweight and executable independent software package, which is used to package the running environment of software and software developed based on the running environment. It contains the contents required to run a software, including code, runtime, library, environment variables and configuration files.

Federated file system (UnionFS)

Before understanding the image, first understand the federated file system. The docker image is stacked layer by layer. Each layer of image will have an id, but only the id of the last layer will be displayed in the end; Some people say this structure is like an onion, others can say it is like a flower roll, what do you think???

UnionFS (Federated file system): UnionFS file system is a layered, lightweight and high-performance file system. It supports the modification of the file system as the superposition of one submission layer at a time. UnionFS file system is the basis of Docker image. The image can be inherited through layers. Based on the basic image, various application images can be made.

docker image loading

The docker image actually consists of a layer by layer file system, which is called UnionFS

We know that docker shares the linux kernel with the host computer. In fact, the principle is as follows:

Bootfs file system will be loaded when linux starts, so the bottom layer of docker image is bootfs

When bootfs is loaded, the whole kernel will be in memory. At this time, bootfs is useless and will be unloaded by the system;

rootfs is a typical distribution of different linux systems, such as Ubuntu and centos, including / dev /proc /bin /etc /

For a docker streamlined OS, rootfs can be very small, requiring only the most basic commands, tools, and libraries. However, the underlying kernel is the same as the host, so some people also say that each docker container is a streamlined linux environment.

docker image loading process

Mirroring Tiering

When we pull an image or generate an image from a dockerfile, we do this layer by layer

So why layering?

The biggest benefit - sharing resources

That is, the docker image cache feature we want to talk about below

dockerfile build image

  • The writing format of dockerfile is dockerfile
  • FROM: there are two ways to build an image, one is scratch (build FROM zero), and the other can start building based on an image
  • The operation that the image is running (user defined)

Write a simple dockerfile

 Remember that only one directory can run by default Dockerfile,Default is 'PATH/Dockerfile',be careful Dockerfile Format, D To capitalize, can not be wrong, in addition, through-f appoint dockerfile File name for+The way of absolute path is also OK
[root@docker01 ~]# mkdir dockerfile && cd dockerfile
[root@docker01 dockerfile]# ls
Dockerfile
[root@docker01 dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
RUN yum -y install net-tools
CMD ["/bin/bash"]

Create image based on dockerfile

[root@docker01 ~]# docker build -t new02:centos /root/dockerfile

This occurs because built has previously used a secondary mirror image

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/4 : RUN yum -y install vim
 ---> Using cache
 ---> 7f5cb26c1891
Step 3/4 : RUN yum -y install net-tools
 ---> Using cache
 ---> 79d2860a90c1
Step 4/4 : CMD ["/bin/bash"]
 ---> Using cache
 ---> 7ffcfd3ab131
Successfully built 7ffcfd3ab131
Successfully tagged new02:centos

It also confirms the benefits of docker layering mentioned above

docker image cache feature

Requirements for cache availability:

  • If you use the same image on the same layer, you can use the cache directly without downloading it
  • Must be the same layer, the same mirror
  • If the previous layer changes, the cache feature cannot be used even if the subsequent layer operates in the same order
[root@docker01 ~]# docker build -t new02:centos /root/dockerfile --no-cache 

Common instructions for dockerfile 🐷

instructionseffect
FROMWhich image is used to build the image
MAINTAINERName or email address of image maintainer
RUNshell command to run when building the image
CMDshell commands executed when the container is run
EXPOSEDeclare the service port of the container after running the container
ENVSetting container environment variables
ADDCopying files or directories to the image will automatically download or decompress them
COPYCopy file or directory to image
VOLUMESpecify to run the container mount point to the directory automatically generated by the host (default / var/lib/docker/volumes), similar to manager volume mount
USERSpecify the running user for the RUN, CMD, and ENTRYPOINT execution commands
WORKDIRSimilar to linux cd, the directory where the container runs
HEALTHCHECKhealth examination
ENTRYPOINTshell commands executed when the container is run
PS matters needing attention:
1. RUN stay building When running, you can write multiple entries. actually RUN There are conditions
2. CMD and ENTRYPOINT Running container When running, you can only write one. If you write more than one
 Article, the last article takes effect
 difference:
CMD "ls","a" During construction, additional content cannot be displayed on the command line
ENTRYPORT "ls","a" During construction, additional contents can be displayed on the command line, such as: docker run -it id -l
3. If in Dockerfile If you need to import a file into the image, the file must be
dockerfile Under the directory or subdirectory
4. There can only be one directory Dockerfile File, and the case of the name is strictly in accordance with
 requirement: Dockerfile.

Example: Dockerfile builds nginx

Building nginx environment based on CentOS 7

FROM centos:7
RUN yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
COPY nginx-1.17.5.tar.gz /usr/local

WORKDIR /usr/local/
RUN tar -zxf /usr/local/nginx-1.17.5.tar.gz
RUN useradd -M -s /sbin/nologin nginx

WORKDIR /usr/local/nginx-1.17.5/
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make install

WORKDIR /root
RUN ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
RUN nginx -t
RUN nginx

EXPOSE 80
COPY index.html /usr/local/nginx/html/
#CMD [ "nginx" "-g" "daemon off" ]

By default, nginx will not be opened when entering the container. nginx -g "daemon off" needs to be added

[root@docker01 t5]# docker built -t dc05:nginx .
[root@docker01 t5]# docker run -itd --name dc10 dc05:nginx nginx -g "daemon off;"
2b691183e572300b01dc565860ea97eaa28574a8b2f651f4010ea094d81b7e41
[root@docker01 t5]# docker exec -it dc10 /bin/bash
[root@2b691183e572 ~]# 
[root@2b691183e572 ~]# curl 127.0.0.1
123.com

Building httpd from dockerfile

Based on centos:7 🦌

FROM centos:7
RUN yum -y install httpd
ENV dir=/var/www/html/index.html
COPY index.html $dir
ADD run.sh /root/run.sh
RUN chmod 755 /root/run.sh
EXPOSE 80
CMD ["/root/run.sh"]

Start httpd when opening the container, VIM run sh

#!/bin/bash
exec /usr/sbin/httpd -D FOREGROUND #Open httpd in the foreground

Image construction based on httpd

FROM httpd:latest
ENV dir=/usr/local/apache2/htdocs/index.html
COPY index.html $dir
EXPOSE 80

Building tomcat from dockerfile

FROM centos:7

ADD apache-tomcat-8.5.55.tar.gz /usr/local/
ADD jdk-8u261-linux-x64.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH


ENV JAVA_HOME /usr/local/jdk1.8.0_261
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD ["/usr/local/apache-tomcat-8.5.55/bin/catalina.sh","run"]

Build mirror

[root@docker01 ~]# docker build -t mytomcat /tomcat/

Start a container based on this image

[root@docker01 ~]# docker run -itd --name dc02 -P -v /root/tomcat/test:/usr/local/apache-tomcat-8.5.55/webapps/test -v /var/log/tomcat:/usr/local/apache-tomcat-8.5.55/logs mytomcat

Simulate deployment of a project release

The directory is mounted, so the project can be deployed on the host computer

You need to add WEB-INF and web. Inf to the host xml

[root@docker01 test]# mkdir WEB-INF
[root@docker01 test]# ls
WEB-INF 
[root@docker01 test]# cd WEB-INF/
[root@docker01 WEB-INF]# vim web.xml
[root@docker01 WEB-INF]# cd ..
[root@docker01 test]# vim index.jsp

Pick any web xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description> Test App</description>
</web-app>

Write a jsp test page

print time <%=new java.util.Date()%>

Using docker to build redis high availability cluster

Pull the official image of redis

docker pull redis

Create redis data files and configuration files on the host;

#!/bin/bash
for port in $(seq 1 6)
do
mkdir -p /opt/redis_cluster/redis_node${port}_6379/conf
mkdir -p /data/redis_cluster/redis_node${port}_6379
cat > /opt/redis_cluster/redis_node${port}_6379/conf/redis_node${port}_6379.conf << EOF
bind 0.0.0.0
port 6379
cluster-enabled yes                  
cluster-config-file clusters_6379.conf   
cluster-node-timeout 15000
cluster-announce-ip 172.16.0.1$port
cluster-announce-port 6379
cluster-announce-bus-port 16379		
appendonly yes
appendfilename "redis_node${port}_6379.aof"
appendfsync everysec
EOF
done

Start redis container

docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /opt/redis_cluster/redis_node1_6379/conf/redis_node1_6379.conf:/etc/redis/redis.conf -v /data/redis_cluster/redis_node1_6379:/data -d --net redis --ip 172.16.0.11 redis:latest redis-server /etc/redis/redis.conf

Script to create redis container

for port in $(seq 1 6)
do
docker run -itd -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} -v /opt/redis_cluster/redis_node${port}_6379/conf/redis_node${port}_6379.conf:/etc/redis/redis.conf -v /data/redis_cluster/redis_node${port}_6379:/data -d --net redis --ip 172.16.0.1${port} redis:latest redis-server /etc/redis/redis.conf
done

Enter redis and create a redis high availability cluster

[root@docker01 ~]# docker exec -it redis-1 /bin/bash
root@d2dcc044beac:/data# redis-cli --cluster create 172.16.0.11:6379 172.16.0.12:6379 172.16.0.13:6379 172.16.0.14:6379 172.16.0.15:6379 172.16.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.0.15:6379 to 172.16.0.11:6379
Adding replica 172.16.0.16:6379 to 172.16.0.12:6379
Adding replica 172.16.0.14:6379 to 172.16.0.13:6379
M: 19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379
   slots:[0-5460] (5461 slots) master
M: cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379
   replicates 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792
S: 7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379
   replicates 19c9265cf4becb247852ac0a14a005f253db107d
S: c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379
   replicates cf3cecfe839469f5b67524ffa01a81e808ce73de
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.16.0.11:6379)
M: 19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379
   slots: (0 slots) slave
   replicates 19c9265cf4becb247852ac0a14a005f253db107d
M: cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379
   slots: (0 slots) slave
   replicates 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792
M: 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379
   slots: (0 slots) slave
   replicates cf3cecfe839469f5b67524ffa01a81e808ce73de
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Validation cluster

root@d2dcc044beac:/data# redis-cli -c -h 172.16.0.16 -p 6379
172.16.0.16:6379> set k1 v1
-> Redirected to slot [12706] located at 172.16.0.13:6379
OK
172.16.0.13:6379> set k2 v2
-> Redirected to slot [449] located at 172.16.0.11:6379
OK
172.16.0.11:6379> get k1
-> Redirected to slot [12706] located at 172.16.0.13:6379
"v1"
172.16.0.13:6379> get k2
-> Redirected to slot [449] located at 172.16.0.11:6379
"v2"
172.16.0.11:6379> 

Verify high availability

# Verify high availability and stop the redis-3 master
[root@docker01 ~]# docker stop redis-3
redis-3
172.16.0.16:6379> CLUSTER NODES
7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379@16379 slave 19c9265cf4becb247852ac0a14a005f253db
19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379@16379 master - 0 1596082825000 1 connected 0-546
cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379@16379 master - 0 1596082824000 2 connected 5461-
9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379@16379 master - 0 1596082821731 7 connected 10923
9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379@16379 master,fail - 1596082761527 1596082758000 
c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379@16379 myself,slave cf3cecfe839469f5b67524ffa01a8
172.16.0.16:6379> 
#Get the data again. k1 originally put in redis-3 has been put on redis-4
root@d2dcc044beac:/data# redis-cli -c -h 172.16.0.14 -p 6379
172.16.0.14:6379> get k1
"v1"

oK, done! 🐒

Tags: Linux Docker CentOS Container dockerfile

Posted by rndilger on Sun, 02 Jan 2022 21:47:52 +1030