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 🐷
instructions | effect |
---|---|
FROM | Which image is used to build the image |
MAINTAINER | Name or email address of image maintainer |
RUN | shell command to run when building the image |
CMD | shell commands executed when the container is run |
EXPOSE | Declare the service port of the container after running the container |
ENV | Setting container environment variables |
ADD | Copying files or directories to the image will automatically download or decompress them |
COPY | Copy file or directory to image |
VOLUME | Specify to run the container mount point to the directory automatically generated by the host (default / var/lib/docker/volumes), similar to manager volume mount |
USER | Specify the running user for the RUN, CMD, and ENTRYPOINT execution commands |
WORKDIR | Similar to linux cd, the directory where the container runs |
HEALTHCHECK | health examination |
ENTRYPOINT | shell 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! 🐒