Docker entry and advanced (basic + actual combat + advanced + Compose + Swarm) ultra-detailed version

Docker entry and advanced (basic + practical + advanced)

1. Introduction to Docker

1.1 Docker overview

Docker is an open source and lightweight 应用容器引擎.

Application Scenario

  • Automated packaging and publishing of web applications.
  • Automated testing and continuous integration, release.
  • Deploy and tune database or other backend applications in a service-oriented environment.

Comparison of Docker and virtual machines

  • Traditional virtual machines virtualize hardware, run a complete operating system, and then install and run software on this system.
  • The container in Docker runs directly in the host machine. The container does not have its own kernel or virtual hardware. Each container is isolated from each other, and each container has its own file system, which does not affect each other.

Benefits of Containerization

  • Faster delivery and deployment of applications
  • Easier to upgrade and expand
  • Easier system operation and maintenance
  • more efficient resource utilization

The composition of Docker仓库、镜像和容器
insert image description here

  • mirror image

Docker images contain packaged applications and their dependent environments. Similar to the program installation package of Win.

  • mirror warehouse

The Docker image warehouse is used to store Docker images and facilitate the sharing of these images between different people and different computers. Similar to the warehouse where Win puts the installation package.

  • container

A Docker container is usually a Linux container that is created based on a Docker image. A running container is a process running on the Docker host. Similar to the program installed by Win.

1.2 Docker installation, configuration, uninstallation

Docker installation steps

0. Delete the old version to avoid installation failure

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

1. 安装docker, -y means not to ask for installation until the installation is successful

yum install -y docker-ce docker-ce-cli containerd.io

2. 启动docker, and check the version information

systemctl start docker
docker version

insert image description here

3.配置国内镜像仓库

vim /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://registry.docker-cn.com"
    ]
}

After the configuration is complete, you need to restart the docker service

systemctl restart docker  # 重启docker服务
systemctl status docker  # 确认docker服务正常运行

4. docker设置为开机启动

systemctl enable docker

5.卸载Docker

# 1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 2. 删除资源  . /var/lib/docker是docker的默认工作路径
rm -rf /var/lib/docker

1.3 Docker usage process

insert image description here

1.4 Docker access principle

Docker is a system of Client-Server structure. Docker's daemon process runs on the host and is accessed from the client through Socket! Docker Server will execute the command after receiving the command from Docker-Client!
insert image description here

1.5 Docker Common Commands

The official address of the Docker command

1.5.1 Basic commands

docker version# View the version information of docker
docker info# View the system information of docker, including the number of images and containers
docker 命令 --help# Help command (optional parameters can be viewed)

1.5.2 Mirroring commands

docker imagesView all local mirrors

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB
# 解释:
1.REPOSITORY  镜像的仓库源
2.TAG  镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小

# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id

docker searchsearch mirror

[root@localhost ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   10308     [OK]
mariadb                           MariaDB is a community-developed fork of MyS…   3819      [OK]
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   754                  [OK]
percona                           Percona Server is a fork of the MySQL relati…   517       [OK]
centos/mysql-57-centos7           MySQL 5.7 SQL database server                   86
mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   79
centurylink/mysql                 Image containing mysql. Optimized to be link…   60                   [OK]

# 可选参数
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
      
      
# 搜索收藏数大于3000的镜像
[root@localhost ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10308     [OK]
mariadb   MariaDB is a community-developed fordockerk of MyS…   3819      [OK]

docker pull 镜像名[:tag]download mirror

Layered download , the core of docker image - Union File System (UnionFS)

# 如果不写tag默认就是下载最新版 latest
docker pull mysql	
# 指定版本下载
docker pull mysql:5.7

docker rmidelete mirror

# 1.删除指定的镜像id
docker rmi -f 镜像id
# 2.删除多个镜像id
docker rmi -f 镜像id 镜像id 镜像id
# 3.删除全部的镜像id
docker rmi -f $(docker images -aq)

1.5.3 Container commands

Containers are created based on Docker images.

# 先拉取一个centos镜像
docker pull centos

docker run [Options] imagerun container

docker run [Options] image

#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
	-p ip:主机端口:容器端口  配置主机端口映射到容器端口
	-p 主机端口:容器端口(常用)
	-p 容器端口
-P                     随机指定端口
-e					   环境设置
-v					   容器数据卷挂载

Run and enter the container centos

[root@localhost ~]# docker run -it centos /bin/bash
[root@ce2bbae9f151 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

exit container

exit 	# 停止容器并退出(后台方式运行则仅退出)
Ctrl+P+Q  # 不停止容器退出

docker psView running containers

# 查看当前正在运行的容器
docker ps 
     
-a   # 查看所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q   # 只显示容器的id

docker start 容器idStart the container

docker start 容器id          # 启动容器
docker restart 容器id        # 重启容器
docker stop 容器id           # 停止当前运行的容器
docker kill 容器id           # 强制停止当前容器

1.5.4 Other common commands

docker logsview log

docker logs -tf 容器id
docker logs --tail num 容器id  # num为要显示的日志条数

docker topView process information in the container

docker top 容器id

docker inspectView container metadata

docker inspect 容器id

Enter the container, because usually our containers are run in the background, sometimes we need to enter the container to modify the configuration

  • docker exec
# docker exec 进入容器后开启一个新的终端,可以在里面操作
docker exec -it 容器id /bin/bash
  • docker attach
# docker attach 进入容器正在执行的终端
docker attach 容器id

docker cpcopy operation

# 拷贝容器的文件到宿主机中
docker cp 容器id:容器内路径  宿主机路径

# 拷贝宿主机的文件到容器中
docker cp 宿主机路径 容器id:容器内路径

# 注意:源文件在哪就在哪进行复制操作
# 在主机中创建test.txt文件,并复制到centos容器的/home路径下
touch test.txt
docker cp /home/test.txt 08d1f5d4e7b1:/home/

1.5.5 Image export and import

1. Use export and import

These two commands are to export and import images through containers

docker export 容器id > xxx.tar [路径]
docker import [- 镜像名] < xxx.tar

2. Use save and load

These two commands are to export and import mirrors through mirroring

docker save 镜像id > xxx.tar [路径]
docker load < xxx.tar

1.6 Make a Docker image

The Docker image is actually composed of a layer-by-layer file system. This layer of file system is UnionFS联合文件系统。
used to 用docker image inspectview the metadata of the image.

docker image inspect nginx:latest

# 镜像的分层信息 ,层级文件可以共享
"RootFS": {
    "Type": "layers",
    "Layers": [
        "sha256:87c8a1d8f54f3aa4e05569e8919397b65056aa71cdf48b7f061432c98475eee9",
        "sha256:5c4e5adc71a82a96f02632433de31c998c5a9e2fccdcbaee780ae83158fac4fa",
        "sha256:7d2b207c26790f693ab1942bbe26af8e2b6a14248969e542416155a912fec30d",
        "sha256:2c7498eef94aef8c40d106f3e42f7da62b3eee8fd36012bf7379becc4cd639a2",
        "sha256:4eaf0ea085df254fd5d2beba4e2c11db70a620dfa411a8ad44149e26428caee4"
    ]
}

Mirror Features

  • All Docker images start from a base 镜像层. When adding or modifying content, a new image layer will be created on top of the current image layer.
  • Docker images are all read-only, and when the container starts, a new writable layer ( 容器层) is loaded on top of the image.

提交镜像 docker commit

# 使用docker commit 命令提交容器成为一个新的镜像版本
docker commit -m=“提交的描述信息”  -a="作者" 容器id 目标镜像名:[TAG] 

The webapps folder of the default Tomcat image has nothing in it, you need to copy the files from webapps.dist to the webapps folder. Next, create a mirror by yourself: copy the file from webapps.dist to the webapps folder, and submit the mirror as a new mirror. So that there are files under the default webapps folder of the image.

# 1.复制项目到webapps下
[root@localhost ~]# docker run -it tomcat /bin/bash
root@3762239532cf:/usr/local/tomcat# cd webapps
root@3762239532cf:/usr/local/tomcat/webapps# ls
root@3762239532cf:/usr/local/tomcat/webapps# cp -r ../webapps.dist/* .
root@3762239532cf:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
# 2.项目访问 http://192.168.0.105:8080/
# 3.提交容器作为一个新的镜像
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
41d0b9c0da0e   tomcat    "catalina.sh run"   4 minutes ago   Up 4 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   agitated_mccarthy
[root@localhost ~]# docker commit -m="add webapps" -a="buckletime" 41d0b9c0da0e mytomcat:1.0
sha256:6bbddb87eb6f909f77c6f851b25edd5a02ad9632f397b68f65f4169b9874f02a
# 4.查看镜像列表
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
mytomcat     1.0       6bbddb87eb6f   31 seconds ago   684MB
tomcat       latest    fb5657adc892   3 months ago     680MB
centos       latest    5d0da3dc9764   6 months ago     231MB
# 5.运行新的容器并查看文件
[root@localhost ~]# docker run -it mytomcat:1.0 /bin/bash
root@5c04b86e6369:/usr/local/tomcat# ls webapps
ROOT  docs  examples  host-manager  manager

2. Container data volume

2.1 Data Volume Introduction

Docker packages the application and running environment to form a container to run. If the data generated by the Docker container does not generate a new image through docker commit, so that the data is saved as part of the image, then when the container is deleted, the data will naturally disappear. . To save data in Docker we use volumes. |

A volume is a directory or a file that exists in one or more containers and is mounted to the container by Docker, but the volume does not belong to the Union File System, so it can bypass the Union File System to provide some persistent storage or shared data Features: .

Volumes are designed to be 数据的持久化和同步,容器间可以数据共享.

Features of data volumes:

  • Data volumes can share or reuse data between containers
  • Changes in the volume can take effect directly
  • Changes in the data volume will not be included in the update of the mirror

2.2 Data Volume Usage

Run the container and specify the command to mount the data volume:

docker run -it -v 主机目录:容器目录

# 1.运行centos容器,并指定挂载数据卷
[root@localhost ~]# docker run -it -v /home/main_data/:/home/docker_data centos /bin/bash
# 2.使用docker inspect查看容器的元数据,查看是否挂载成功
[root@localhost ~]# docker inspect 9f80a90b6c54
"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/main_data",
                "Destination": "/home/docker_data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]
# 3.在主机中创建文件
[root@localhost main_data]# touch main.txt
[root@localhost main_data]# ls
main.txt
# 4.查看容器中的文件
[root@9f80a90b6c54 /]# ls /home/docker_data/
main.txt

Example: MySQL container creates a data volume to synchronize data

The default data file storage directory of MySQL under Linux is /var/lib/mysql, and the default configuration file is set to /etc/mysql/conf.d. In order to avoid data loss after the MySQL image or container is deleted, the following is established Data volumes store MySQL data and files.

# 1.启动mysql  挂载数据卷
docker run -d -p 3306:3306 \
		   -v /home/mysql/conf:/etc/mysql/conf.d \
		   -v /home/mysql/data:/var/lib/mysql \
		   -e MYSQL_ROOT_PASSWORD=123456 mysql 
# 2.远程连接mysql服务,若无权限,进入mysql容器中修改远程连接权限
docker exec -ti 36d4806c765a /bin/bash
# 登录mysql
mysql -u root -p
# 修改root 可以通过任何客户端连接
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 3.使用客户端创建mytest数据库并查看主机中同步的数据,数据同步成功
[root@localhost data]# ls /home/mysql/data

2.3 docker volume command

[root@localhost data]# docker volume --help

Commands:
  create      # 创建数据卷
  inspect     # 查看数据卷详情
  ls          # 查看所有数据卷列表
  prune       # 删除所有未使用的卷
  rm          # 删除数据卷

docker volume createCreate data volume

[root@localhost data]# docker volume create my-vol

docker volume lsView a list of all data volumes

[root@localhost data]# docker volume ls

docker volume inspectView data volume details

[root@localhost data]# docker volume inspect my-vol 
[
    {
        "CreatedAt": "2022-04-07T12:52:42+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

docker volume rmDelete data volume

[root@localhost data]# docker volume rm my-vol

docker volume pruneremove all unused volumes

[root@localhost data]# docker volume prune

docker rm -vWhen deleting a container also deletes the associated volume

2.4 Named Mount and Anonymous Mount

mount anonymously

Anonymous mounting means that when specifying a data volume, only the container path is specified, and the corresponding host path is not specified, so that the corresponding mapped host path is /var/lib/docker/volumes/an automatically generated 随机命名folder in the default path .

# 运行并匿名挂载Nginx容器
[root@localhost data]# docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看卷列表
[root@localhost data]# docker volume ls
DRIVER    VOLUME NAME
local     0e102dae2f6731494400f7c98c11c835293c030b736588d80d4296b96f10c71d
local     my-vol

named mount

Named mount refers to the specified folder name , which is different from the specified path mount. The specified folder name here is specified by Docker and is also under the default data volume path . Use the docker volume ls command to check the directory status of the current data volume.

# 运行并具名挂载Nginx容器
[root@localhost data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 查看卷列表
[root@localhost data]# docker volume ls
DRIVER    VOLUME NAME
local     0e102dae2f6731494400f7c98c11c835293c030b736588d80d4296b96f10c71d
local     juming-nginx
local     my-vol
# 查看数据卷详情,注意主机路径也是默认数据卷路径下
[root@localhost data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-04-07T13:10:39+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

The commands for anonymous mount, named mount, and specified path mount are as follows:

  • Anonymous mount -v 容器内路径, not recommended
  • named mount-v 卷名:容器内路径
  • Specify the path to mount-v 宿主机路径:容器内路径

Extension: Specify related parameters for data volume mapping: ro/rw

  • ro - readonly read only. If read-only is set, it means that this path can only be operated by the host machine, not by the container .
  • rw ----- readwrite can read and write
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

2.5 Dockerfile for data volume

DockerfileIt is a build file for building a docker image and a command script file. Mirroring can be generated through this script.

Directives can be used in the Dockerfile VOLUMEto add one or more data volumes to the image.

dockerfile script

# 脚本中指令(大写)
# 基础镜像
FROM centos
# 匿名挂载
VOLUME ["volume01","volume02"]
CMD echo "----end----"
# 命令行环境
CMD /bin/bash

Execute the script to build the imagedocker build

[root@localhost docker_test_volume]# docker build -f dockerfile1 -t buckletime-centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 0af875dd3c35
Removing intermediate container 0af875dd3c35
 ---> 3876cf15e836
Step 3/4 : CMD echo "----end----"
 ---> Running in 73344c7d325a
Removing intermediate container 73344c7d325a
 ---> ce432169d4d9
Step 4/4 : CMD /bin/bash
 ---> Running in 8e12aeb63375
Removing intermediate container 8e12aeb63375
 ---> b74eed3e6de1
Successfully built b74eed3e6de1
Successfully tagged buckletime-centos:1.0
# 查看镜像
[root@localhost docker_test_volume]# docker images
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
buckletime-centos   1.0       b74eed3e6de1   15 seconds ago   231MB
mytomcat            1.0       6bbddb87eb6f   3 hours ago      684MB
nginx               latest    12766a6745ee   8 days ago       142MB
tomcat              latest    fb5657adc892   3 months ago     680MB
mysql               latest    3218b38490ce   3 months ago     516MB
centos              latest    5d0da3dc9764   6 months ago     231MB

View data volume

# 启动自己构建的镜像并进入容器
[root@localhost docker_test_volume]# docker run -it b74eed3e6de1 /bin/bash
# 查看目录
[root@20978f76e318 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02
# 查看数据卷挂载信息
[root@localhost docker_test_volume]# docker inspect 20978f76e318
"Mounts": [
    {
        "Type": "volume",
        "Name": "9bdb13dbdd9a543a00b01e6a84475c6877547a5b722617d1f2afa0546f5cbb47",
        "Source": "/var/lib/docker/volumes/9bdb13dbdd9a543a00b01e6a84475c6877547a5b722617d1f2afa0546f5cbb47/_data",
        "Destination": "volume01",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    },
    {
        "Type": "volume",
        "Name": "2edc8939b90a1a6f3b684a279819b7f0f20fd89f9eebc9a78a4318fb77cf22ba",
        "Source": "/var/lib/docker/volumes/2edc8939b90a1a6f3b684a279819b7f0f20fd89f9eebc9a78a4318fb77cf22ba/_data",
        "Destination": "volume02",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
]

You can see the mount directory of the host under Mounts. Because the host directory is not specified in the dockerfile, it is an anonymous mount, and a randomly named path is generated in the /var/lib/docker/volumes/ directory.

2.6 Data volume container

Container data volumes refer to the establishment of data volumes to synchronize data between multiple containers to achieve data synchronization between containers.

insert image description here
First start container 1, volume01 and volume02 are the mount directories

docker run -it --name cnetos01 buckletime-centos:1.0

--volumes-fromThen start container 2, and set container 2 and container 1 to establish a data volume mount relationship through parameters

docker run -it --name centos02 --volumes-from cnetos01 buckletime-centos:1.0

Data volume container summary:

  • Synchronization of configuration files and data between containers, the life cycle of the data volume container continues until no container is used
  • If you use -v to persist to the host, the data in the host will not be deleted and will be permanently valid.

3. Dockerfile

3.1 Introduction to Dockerfile

Dockerfileis a build file that builds a docker image, and is a 命令脚本文件. Mirroring can be generated through this script.

build steps

  1. 编写dockerfile文件
  2. docker build 构建镜像
  3. docker run 运行镜像
  4. docker push 发布镜像

Dockerfile basics

  • Commands must be uppercase
  • Instructions are executed sequentially from top to bottom
  • # means comment
  • Each command creates and commits a new image layer
    insert image description here

3.2 Dockerfile instructions

FROMBasic image, everything is built from here
MAINTAINER. Image maintainer description, name + email.
RUNCommands that need to be run when the image is built.
COPYCopy files to the target image.
ADDAdd files to the target image. Tar files and URL paths are supported.
WORKDIRSpecify the working directory of the image
VOLUMEto hang The directory to be loaded can only specify the path in the container. The path of the host is the default mount directory.
EXPOSESpecify the port exposed by the container.
CMDSpecify the command to be run when starting the container. Only the last command will take effect and can be replaced.
ENTRYPOINTSimilar to CMD, you can Add commands
ENVto set environment variables when building

3.3 Dockerfile in action

Combat 1: Build a customized centos based on the official centos image

The official centos image is the minimum version, and many commands are missing. We can customize a contos based on the official centos image

1. Write the dockerfile file dockerfile-mycentos

FROM centos:7
MAINTAINER buckletime<[email protected]>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum install -y vim
RUN yum install -y net-tools

EXPOSE 80

CMD echo "-----end------"
CMD /bin/bash

2. Build the image through the dockerfile

docker build -f Dockfile文件 -t 目标镜像:[tag] 目标位置

[root@localhost dockerfile]# docker build -f dockerfile-mycentos -t mycentos:0.1 .
...
Step 9/9 : CMD /bin/bash
 ---> Running in d5083707b308
Removing intermediate container d5083707b308
 ---> b6a1205a01ec
Successfully built b6a1205a01ec
Successfully tagged mycentos:0.1
# 查看镜像
[root@localhost dockerfile]# docker images
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
mycentos            0.1       b6a1205a01ec   3 minutes ago    580MB
centos              7         eeb6ee3f44bd   6 months ago     204MB

3. Run the test
insert image description here

4. You can use docker historycommands to analyze the build process of a mirror image

# 通过 docker history 命令来分析刚刚构建的镜像过程
[root@localhost dockerfile]# docker history b6a1205a01ec
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
b6a1205a01ec   23 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
8c604ec85c0d   23 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
ad5af97ad072   23 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
3cdf414340ac   23 minutes ago   /bin/sh -c yum -y install vim                   216MB     
cdc69b9b3a21   24 minutes ago   /bin/sh -c yum -y install net-tools             161MB     
ff54b51b10da   24 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B        
d62c8129ba70   24 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B        
5bc36fed9ecf   24 minutes ago   /bin/sh -c #(nop)  MAINTAINER buckletime<187…   0B        
eeb6ee3f44bd   6 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      6 months ago     /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      6 months ago     /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

Combat 2: The difference between the CMD instruction and the ENTRYPOINT instruction

CMDSpecify the command to run when starting the container. Only the last command will take effect and can be replaced.
ENTRYPOINTSimilar to CMD, commands can be added

CMD command test

1.vim dockerfile-cmd

FROM centos:7
CMD ["pwd"]
CMD ["ls","-a"]

2. Build a mirror image

[root@localhost dockerfile]# docker build -f dockerfile-cmd -t cmd-test:1.0 .

3. Run the test

[root@localhost dockerfile]# docker run -it cbe86f605790
.   .dockerenv	       bin  etc   lib	 media	opt   root  sbin  sys  usr
..  anaconda-post.log  dev  home  lib64  mnt	proc  run   srv   tmp  var
# 要想追加命令 -l ,CMD指令会报错,只能使用全部命令去替换 ls -al
[root@localhost dockerfile]# docker run -it cbe86f605790 -l
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
[root@localhost dockerfile]# docker run -it cbe86f605790 ls -al
total 12
drwxr-xr-x.   1 root root     6 Apr  7 09:02 .
drwxr-xr-x.   1 root root     6 Apr  7 09:02 ..
-rwxr-xr-x.   1 root root     0 Apr  7 09:02 .dockerenv
-rw-r--r--.   1 root root 12114 Nov 13  2020 anaconda-post.log
lrwxrwxrwx.   1 root root     7 Nov 13  2020 bin -> usr/bin
drwxr-xr-x.   5 root root   360 Apr  7 09:02 dev
drwxr-xr-x.   1 root root    66 Apr  7 09:02 etc
drwxr-xr-x.   2 root root     6 Apr 11  2018 home
lrwxrwxrwx.   1 root root     7 Nov 13  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root     9 Nov 13  2020 lib64 -> usr/lib64
drwxr-xr-x.   2 root root     6 Apr 11  2018 media
drwxr-xr-x.   2 root root     6 Apr 11  2018 mnt
drwxr-xr-x.   2 root root     6 Apr 11  2018 opt
dr-xr-xr-x. 241 root root     0 Apr  7 09:02 proc
dr-xr-x---.   2 root root   114 Nov 13  2020 root
drwxr-xr-x.  11 root root   148 Nov 13  2020 run
lrwxrwxrwx.   1 root root     8 Nov 13  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root     6 Apr 11  2018 srv
dr-xr-xr-x.  13 root root     0 Apr  7 01:43 sys
drwxrwxrwt.   7 root root   132 Nov 13  2020 tmp
drwxr-xr-x.  13 root root   155 Nov 13  2020 usr
drwxr-xr-x.  18 root root   238 Nov 13  2020 var

ENTRYPOINT command test

1.vim dockerfile-entrypoint

FROM centos:7
ENTRYPOINT ["pwd"]
ENTRYPOINT ["ls","-a"]

2. Build a mirror image

[root@localhost dockerfile]# docker build -f dockerfile-entrypoint -t entrypoint-test:1.0 .

3. Run the test

[root@localhost dockerfile]# docker run -it 1ff2ec561a44
.   .dockerenv	       bin  etc   lib	 media	opt   root  sbin  sys  usr
..  anaconda-post.log  dev  home  lib64  mnt	proc  run   srv   tmp  var
# 追加命令 -l
[root@localhost dockerfile]# docker run -it 1ff2ec561a44 -l
total 12
drwxr-xr-x.   1 root root     6 Apr  7 09:06 .
drwxr-xr-x.   1 root root     6 Apr  7 09:06 ..
-rwxr-xr-x.   1 root root     0 Apr  7 09:06 .dockerenv
-rw-r--r--.   1 root root 12114 Nov 13  2020 anaconda-post.log
lrwxrwxrwx.   1 root root     7 Nov 13  2020 bin -> usr/bin
drwxr-xr-x.   5 root root   360 Apr  7 09:06 dev
drwxr-xr-x.   1 root root    66 Apr  7 09:06 etc
drwxr-xr-x.   2 root root     6 Apr 11  2018 home
lrwxrwxrwx.   1 root root     7 Nov 13  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root     9 Nov 13  2020 lib64 -> usr/lib64
drwxr-xr-x.   2 root root     6 Apr 11  2018 media
drwxr-xr-x.   2 root root     6 Apr 11  2018 mnt
drwxr-xr-x.   2 root root     6 Apr 11  2018 opt
dr-xr-xr-x. 242 root root     0 Apr  7 09:06 proc
dr-xr-x---.   2 root root   114 Nov 13  2020 root
drwxr-xr-x.  11 root root   148 Nov 13  2020 run
lrwxrwxrwx.   1 root root     8 Nov 13  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root     6 Apr 11  2018 srv
dr-xr-xr-x.  13 root root     0 Apr  7 01:43 sys
drwxrwxrwt.   7 root root   132 Nov 13  2020 tmp
drwxr-xr-x.  13 root root   155 Nov 13  2020 usr
drwxr-xr-x.  18 root root   238 Nov 13  2020 var

Combat 3: Dockerfile to create a Tomcat image

1. Prepare the environment

Prepare the compressed packages of Tomcat and jdk

[root@localhost dockerfile]# ll
总用量 188324
-rwxr-xr-x. 1 root root  11560971 4月   7 17:26 apache-tomcat-9.0.62.tar.gz
-rwxr-xr-x. 1 root root 181260798 4月   7 17:26 jdk-8u65-linux-x64.tar.gz
-rw-r--r--. 1 root root         0 4月   7 18:39 readme.txt

2. Write Dockerfile

The official name is Dockerfile, use this name directly, you don’t need to specify -f when building

FROM centos:7
MAINTAINER buckletime<[email protected]>

ENV MYPATH /usr/local
WORKDIR $MYPATH

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u65-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.62.tar.gz /usr/local/

RUN yum -y install vim

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

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/logs/catalina.out

3. Build the image

[root@localhost dockerfile]# docker build -t mytomcat:2.0 .
Successfully built 874b2eaffc8f
Successfully tagged mytomcat:2.0

4. Start the image

[root@localhost dockerfile]# docker run -d -p 9090:8080 --name mytomcat \
-v /home/buckletime/dockerbuild/tomcat/project:/usr/local/apache-tomcat-9.0.62/webapps/project \
-v /home/buckletime/dockerbuild/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.62/logs mytomcat:2.0

Access test: http://192.168.0.105:9090 successfully entered the Tomcat home page

5. Publish the project

Since the volume is mounted, the project can be published directly by placing the project locally

Actual Combat 4: SpringBoot project is packaged into a Docker image

  1. Springboot project packaging, here is the jar package as an example

  2. Upload to Linux and write Dockerfile

    [root@localhost idea]# ls
    demo-0.0.1-SNAPSHOT.jar  Dockerfile
    
    FROM java:8
    
    # 将demo-0.0.1-SNAPSHOT.jar 复制 到容器中并重命名为 app.jar
    COPY demo-0.0.1-SNAPSHOT.jar app.jar
    
    CMD ["--server.port=8080"]
    
    EXPOSE 8080
    
    ENTRYPOINT ["java","-jar","app.jar"]
    
  3. build image

    [root@localhost idea]# docker build -t springbootdemo:1.0 .
    [root@localhost idea]# docker images
    REPOSITORY       TAG                IMAGE ID       CREATED          SIZE
    springbootdemo   1.0                d9648a49a226   50 seconds ago   661MB	
    
  4. run, test

    [root@localhost idea]# docker run -d -p:8888:8080 --name mydemo springbootdemo:1.0
    [root@localhost idea]# curl localhost:8888/hello
    hello buckletime![root@localhost idea]# 
    

Actual Combat 5: Publishing Mirror Images

Publish the image to Docker Hub

  1. Docker Hub official website , register an account

  2. docker loginLogin account with

    [root@localhost ~]# docker login --help
    
    Usage:  docker login [OPTIONS] [SERVER]
    
    Log in to a Docker registry.
    If no server is specified, the default is defined by the daemon.
    
    Options:
      -p, --password string   Password
          --password-stdin    Take the password from stdin
      -u, --username string   Username
    
  3. docker pushSubmit a mirror using

    # 发布镜像最好带上版本号,可以使用docker tag 命令修改镜像名称和版本号
    docker tag 6d27817ecb31 buckletime/mycentos:2.0
    # docker push 发布镜像
    docker push buckletime/mycentos:2.0
    

Publish the image to Alibaba Cloud Container Service

  1. Log in to Alibaba Cloud and find the container image service
  2. create namespace
  3. Create a container image
  4. Publish the image according to the description in the container image

Fourth, Docker summary

insert image description here

5. Docker network

First empty all containers and images for easy learning

# 清空所有容器
docker rm $(docker ps -aq)
# 清空所有镜像
docker rmi $(docker images -aq)

5.1 Understanding Docker networking

insert image description here
1. Run a Tomcat container, tomcat01, and view the address of the container

[root@localhost ~]# docker run -d -P --name tomcat01 tomcat
[root@localhost ~]# docker exec -it tomcat01 ip addr

insert image description here

When running, use ip addrthe direct view of the container address. There may be an error report and the ip command cannot be found. You need to install iproute2 in the container.
There is no yum command in the official Tomcat. Use apt-getthe command to install iproute2 and ping command

[root@localhost ~]# docker exec -it tomcat01 /bin/bash
root@8e57c8b48890:/usr/local/tomcat# apt-get update
root@8e57c8b48890:/usr/local/tomcat# apt-get -y install iproute2 iproute2-doc
root@8e57c8b48890:/usr/local/tomcat# apt-get -y install inetutils-ping

Since the ip of the container is allocated by docker, the container and the host are in the same network segment.Linux主机与容器之间能 ping 通

[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.046 ms

2. Run another Tomcat container, tomcat02, and view the address of the container

[root@localhost ~]# docker run -d -P --name tomcat02 tomcat
[root@localhost ~]# docker exec -it tomcat02 ip addr
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
70: eth0@if71: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

It can be found:

  • We found that this container brings network cards, all in pairs
  • evth-pairIt is a pair of virtual device interfaces, they all appear in pairs, one is connected to the protocol, and the other is connected to each other. Because of this feature, evth-pair acts as a bridge to connect various virtual network devices
  • OpenStac, the connection between Docker containers, and the connection between OVS all use evth-pair technology

3. Can the two tomcat01 and tomcat02 be pinged? Can ping the same, also in the same network segment

[root@localhost ~]# docker exec -it tomcat02 ping 127.17.0.2
PING 127.17.0.2 (127.17.0.2): 56 data bytes
64 bytes from 127.17.0.2: icmp_seq=0 ttl=64 time=0.099 ms
64 bytes from 127.17.0.2: icmp_seq=1 ttl=64 time=0.051 ms

insert image description here
in conclusion

  • When all containers do not specify a network, they are routed by docker0 , and docker will assign an available IP to the container
  • Docker is using the Linux bridge
  • All network interfaces in Docker are virtual , with high forwarding efficiency

insert image description here

5.2 Container interconnection --link

--linkThe command can connect the container, so that the container can be used容器名访问

[root@localhost ~]# docker exec -it tomcat02 ping tomcat01
ping: unknown host
# --link命令 连接容器 tomcat03 连接 tomcat02 
[root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
# tomcat03 能通过容器名访问 tomcat02
[root@localhost ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.137 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.061 ms
# 但是tomcat02 不能通过容器名访问 tomcat03
[root@localhost ~]# docker exec -it tomcat02 ping tomcat03
ping: unknown host

Essential principle: --link is to add a mapping relationship of container name in hosts, which is a one-way connection

[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	tomcat02 03da12909222
172.17.0.4	8e77f2a544a5

In real development, it is not recommended to use --link, the configuration is to modify the hosts file, and it is a one-way configuration

5.3 Container interconnection custom network

Do not use docker0, because docker0 does not support connection access using container names. Use a custom network.

docker networkOrder

[root@localhost ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9eeca5a5158c   bridge    bridge    local
c60f472b3848   host      host      local
a959f5564b21   none      null      local

network mode

  • bridge: bridge (docker default, custom network also uses bridge mode)
  • host: share the network with the host
  • none: do not set the network
  • container: container network connection (limited, rarely used)

create network

docker network createcreate network

  • --driver 模式(default bridge)
  • --subnet 子网
  • --gateway 网关
# docker network create 创建网络
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
2b9f9c88b69fbb9917c550d0b8017471e246aeb2c8b17c1667ece8a19b086bca
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9eeca5a5158c   bridge    bridge    local
c60f472b3848   host      host      local
2b9f9c88b69f   mynet     bridge    local
a959f5564b21   none      null      local

Our own network is created:

docker network inspect mynetView network details

insert image description here
Start the container to specify the network--net

[root@localhost ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat
972542a6d6516b6d03d81493d03c1f60cecb5160e4ecdad44fb4d18e4430b03f
[root@localhost ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat
f4fd35dcefcd8059af0b0a0c607b137b9c8d4c9d6ba0ae2cf6be23d8a3498992
# 这样两个容器可以直接使用容器名互相连接访问
[root@localhost ~]# docker exec -it tomcat-net01 ping tomcat-net02
PING tomcat-net02 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.137 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.061 ms

Custom Network Benefits

  • Different clusters use different networks to ensure that the clusters are safe and healthy

5.4 Network connectivity

docker network connect 网络 容器Connect the container to the network

[root@localhost ~]# docker network connect --help

Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container

test

# 使用docker0启动两个tomcat
[root@localhost ~]# docker run -d -P --name tomcat04 tomcat
[root@localhost ~]# docker run -d -P --name tomcat05 tomcat
# tomcat04和 自定义网络mynet下的tomcat-net01连接,此时肯定是不通的
[root@localhost ~]# docker exec -it tomcat04 ping tomcat-net01
ping: unknown host
# docker network connect 将容器tomcat04连接到mynet网络中
docker network connect mynet tomcat04
# 再次连接,可以连通
[root@localhost ~]# docker exec -it tomcat04 ping tomcat-net01
PING tomcat-net01 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.137 ms
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.061 ms

docker network inspect mynet Check the network details and find that the container tomcat04 has been added to the mynet network, that is: a container with two ip addresses

insert image description here

5.5 Docker network combat

Combat 1: Redis cluster deployment

insert image description here

# 1.创建redis网络
[root@localhost ~]# docker network create redis_net --subnet 172.38.0.0/16 --gateway 172.38.0.1
# 2.通过shell脚本创建6个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
# 3.通过shell脚本启动6个redis容器
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
# 4.配置集群。进入一个redis容器中,注意,redis没有/bin/bash 命令,使用/bin/sh 
[root@localhost ~]# docker exec -it redis-1 /bin/sh
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

After the configuration cluster command is executed, the following information appears, indicating that the cluster configuration is successful

insert image description here
5. Redis cluster test

redis-cli -cIt is to enter the redis cluster, redis-cliand it is to enter the stand-alone version of redis

  • cluster info: View cluster information
  • cluster nodes: View cluster node information
/data # redis-cli -c
127.0.0.1:6379> cluster nodes
8dea9b0ac434985556f08543f663a1d149772b75 172.38.0.11:6379@16379 myself,master - 0 1649398430000 1 connected 0-5460
29c361a494c043eb2597a3702537bf9553b89c95 172.38.0.16:6379@16379 slave c356c34a7fe0bf89b0abdcf538a910c1444da20e 0 1649398429000 6 connected
187da435dedcc35a48d0236bb8cbb2a2410d354e 172.38.0.15:6379@16379 slave 8dea9b0ac434985556f08543f663a1d149772b75 0 1649398430636 5 connected
17c460274af7f601846685dd91a39cc244823e17 172.38.0.14:6379@16379 slave 554f73de745a0dbdbe8bb8d805b93c622cb98a73 0 1649398429530 4 connected
554f73de745a0dbdbe8bb8d805b93c622cb98a73 172.38.0.13:6379@16379 master - 0 1649398429127 3 connected 10923-16383
c356c34a7fe0bf89b0abdcf538a910c1444da20e 172.38.0.12:6379@16379 master - 0 1649398430133 2 connected 5461-10922
127.0.0.1:6379> set name buckletime
-> Redirected to slot [5798] located at 172.38.0.12:6379
OK

The set value in the cluster is randomly processed (172.38.0.12). At this time, stop the redis-2 container on 172.38.0.12, simulate the downtime of the redis service, and check whether the data is still there and whether the value just now can be obtained.

[root@localhost ~]# docker stop redis-2
redis-2
127.0.0.1:6379> get name
-> Redirected to slot [5798] located at 172.38.0.16:6379
"buckletime"

Enter the cluster again and find that the value just now can be obtained, indicating that the data is not affected and is highly available.
Check the cluster node information again, as shown in the figure below: the redis-2 node status is fail, and the cluster automatically elects another master
insert image description here

6. Docker Compose stand-alone deployment

6.1 Introduction and installation of Docker Compose

Compose is used for 定义和运行多容器 Docker 应用程序的工具. With Compose, you can 使用 YML 文件来配置应用程序需要的所有服务. Then, with a single command, all services can be created and started from the YML file configuration.

For a detailed introduction, please refer to the official website of Docker Compose . The tutorial on the official website is very detailed, so you can read more on the official website.

The three steps used by Compose:

  • Use Dockerfileto define the application's environment.
  • Use to docker-compose.ymldefine the services that make up your application so they can run together in an isolated environment.
  • Finally, execute docker-compose upthe command to get the entire application up and running.

The configuration example of docker-compose.yml is as follows:

version: '3'
services:
  web:
    build: .
    ports:
   - "5000:5000"
    volumes:
   - .:/code
    - logvolume01:/var/log
    links:
   - redis
  redis:
    image: redis
volumes:
  logvolume01: {
    
    }

understand two concepts

  • Service service, a single service module used in the project, such as web, redis, mysql...
  • A project project, a group of related services that make up a project, such as a blog...

Docker Compose installation

Install Docker Compose in Linux:1.下载 2.授权

# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 授权
sudo chmod +x /usr/local/bin/docker-compose

6.2 Docker Compose quick experience

1.创建一个应用. A counter implemented by python + flask + redis.

vim app.py, write application code

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

vim requirements.txt, required dependencies

flask
redis

2.创建Dockerfile

vim Dockerfile, build Docker image

# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

3.定义docker-compose.yml

vim docker-compose.yml, define service information in the configuration file

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

4.用Compose构建和运行应用程序

docker-compose up -dThe parameter indicates the background start

[root@localhost demo_compose]# docker-compose up
Creating network "demo_compose_default" with the default driver
Building web
Sending build context to Docker daemon  4.608kB
Step 1/10 : FROM python:3.7-alpine
...
Creating demo_compose_web_1   ... done
Creating demo_compose_redis_1 ... done
...
web_1    |  * Running on http://127.0.0.1:5000
web_1    |  * Running on http://172.18.0.2:5000 (Press CTRL+C to quit)

The workflow of Compose can be seen from the construction process :

  • Create a network with the name "folder name_default"
  • Read the docker-compose.yml configuration file
  • Build and start the service according to the service definition in the configuration file

Run the resulting test:

[root@localhost idea]# curl 172.18.0.2:5000
Hello World! I have been seen 1 times.
[root@localhost idea]# curl 172.18.0.2:5000
Hello World! I have been seen 2 times.
[root@localhost idea]# curl 172.18.0.2:5000
Hello World! I have been seen 3 times.
[root@localhost idea]# curl 172.18.0.2:5000
Hello World! I have been seen 4 times.

5.停止程序

  • Ctrl + CNon-background startup, you can use this command
  • docker-compose stop-d Background startup can use this command
  • docker-compose down [--volumes]

The difference between stop and down is that 使用down会完全删除容器. 使用stop是停止一次The parameter --volumes means to delete the data volume used by the container

6.3 Docker Compose default naming rules

1.compose service name naming rules

Use docker psView Running Services to find out that the naming rules for service names are文件夹名_服务名_num

[root@localhost idea]# docker ps
CONTAINER ID   IMAGE              NAMES					COMMAND                  CREATED          STATUS          PORTS                                       
f8d252c277d0   redis:alpine       demo_compose_redis_1  "docker-entrypoint.s…"	 18 minutes ago   Up 18 minutes   6379/tcp                                    
e29dfaeda7c5   demo_compose_web   demo_compose_web_1	"flask run"              18 minutes ago   Up 18 minutes   0.0.0.0:8000->5000/tcp, :::8000->5000/tcp

The compose startup service is started as a cluster, and num represents the number of copies

2. Network name naming rules

Use to docker network lsview the network list, the naming rule of the network name is文件夹名_default

[root@localhost idea]# docker network ls
NETWORK ID     NAME                   DRIVER    SCOPE
9eeca5a5158c   bridge                 bridge    local
5fcff058a02c   demo_compose_default   bridge    local
c60f472b3848   host                   host      local

In this way, under the same project folder, all services can be accessed through the domain name

6.4 docker-compose.yml configuration rules

Official website docker-compose.yml configuration details

version: "3.9"	# 1.版本
services:		# 2.服务
  web:	# 服务名
  	# 服务配置
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"
# 3.其他配置 网络/卷/全局规则等
volumes:
network:
config:

The best way to learn docker-compose.yml configuration rules is to write more and read more!

6.5 Combat: Writing springboot projects to build and run through Compose

1. Write a microservice project and implement a counter (redis) by yourself

Introduce redis dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Write controller code

@RestController
public class CounterController {
    
    

    @Autowired
    StringRedisTemplate redisTemplate;

    @RequestMapping("counter")
    public String counter(){
    
    
        Long views = redisTemplate.opsForValue().increment("views");
        return "hello, buckletime, views " + views + " times";
    }
}

application.properties configuration file

server.port=8080
# 配置redis 注意,不要写ip,直接写服务名再通过Compose构建服务
spring.redis.host=redis

Finally, package the project into a jar package

2.Dockerfile build image

FROM java:8

COPY *.jar app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","app.jar"]

3. Write docker-compose.yml configuration

version: "3.8"
services:
  mycounter:  # 服务名
    build: .  # . 表示使用当前目录下的 Dockerfile文件构建镜像
    image: mycounter  # 镜像
    depends_on:
      - redis   # depends_on 依赖 表示需要依赖redis服务
    ports:
      - "8080:8080"   # 端口映射
  redis:
    image: "redis:alpine"

4. Build and run through Compose

[root@localhost mycounter]# ll
总用量 26884
-rwxr-xr-x. 1 root root 27520888 48 19:50 demo-0.0.1-SNAPSHOT.jar
-rwxr-xr-x. 1 root root      336 48 19:50 docker-compose.yml
-rwxr-xr-x. 1 root root      120 48 19:50 Dockerfile
[root@localhost mycounter]# docker-compose up -d

5. Access test, run successfully

[root@localhost mycounter]# curl localhost:8080/counter
hello, buckletime, views 1 times[root@localhost mycounter]# curl localhost:8080/counter
hello, buckletime, views 2 times[root@localhost mycounter]# curl localhost:8080/counter
hello, buckletime, views 3 times[root@localhost mycounter]# curl localhost:8080/counter
hello, buckletime, views 4 times[root@localhost mycounter]# curl localhost:8080/counter
hello, buckletime, views 5 times[root@localhost mycounter]# 

7. Docker Swarm cluster deployment

7.1 Swarm-related concepts

swarm

Cluster management and orchestration. Docker can initialize a swarm cluster, and other nodes can join.

Node

It is a docker node. Multiple nodes form a network cluster. (management, worker)

Service

The service can run on the management node or the worker node, the core! User access!

Task

Commands in the container, detailed tasks

The principle of swarm and k8s is the same

  • Command -> manager node -> api -> scheduling -> worker node (create maintenance task)

7.2 Swarm working mode

Docker Swarm working mode official document

1. Node working mode
insert image description here
3. Service, Task, Container

When you deploy your service to a swarm, the swarm manager accepts your service definition as the service's desired state. It then schedules the service on the nodes in the swarm as one or more replica tasks. These tasks run independently of each other on the nodes in the swarm.

For example, suppose you want to load balance among three instances of an HTTP listener. The following figure shows an HTTP listener service with three replicas. Each of the three instances of the listener is a task in the swarm.
insert image description here
3. Task、Scheduling

The diagram below shows how swarm mode accepts service creation requests and schedules tasks to worker nodes.
insert image description here

7.3 Swarm cluster construction

[root@localhost ~]# docker swarm --help

Commands:
  ca          Display and rotate the root CA
  init        Initialize a swarm
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

docker swarm init --advertise-addr 172.24.82.149initialize a node

insert image description here

docker swarm joinjoin a node

  • docker swarm join-token managerGet manager token
  • docker swarm join-token workerGet worker token

insert image description here

Add nodes on the other two machines, one manager and one worker. Get a 4-node swarm cluster

insert image description here
Cluster Construction Summary

  • docker swarm initInitialize the master node
  • docker swarm joinJoin nodes (manager, worker)

7.4 Understand the Raft consensus protocol

7.2 In the example, the cluster has two masters and two slaves. When the leader node goes down, the other manager node cannot work. Only one master node survives and cannot re-elect a new leader. After changing one of the worker nodes to the manager node, the When the cluster has three masters and one slave, when the Leader node is down, the other two manager nodes can work normally, because a new Leader can be elected at this time.

Leader election : When the current leader fails, a new leader must be elected.

Therefore, to ensure the high availability of the cluster

  • The number of master nodes must be >=3
  • The number of surviving master nodes must be >=2

Simply put, the Raft protocol: it can only be used when most nodes are alive

7.5 Swarm cluster dynamic expansion and contraction service

[root@localhost ~]# docker service --help

Commands:
  create      Create a new service
  inspect     Display detailed information on one or more services
  logs        Fetch the logs of a service or task
  ls          List services
  ps          List the tasks of one or more services
  rm          Remove one or more services
  rollback    Revert changes to a service's configuration
  scale       Scale one or multiple replicated services
  update      Update a service

docker service createCreate and run a service

[root@localhost ~]# docker service create -p 8888:80 --name myngnix ngnix
  • docker run container, no expansion and contraction
  • docker service service, with expansion and contraction, rolling update function

docker service lsview service list

[root@localhost ~]# docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
blkxxbxk897b   myngnix   replicated   1/1        ngnix:latest   *:8888->80/tcp

Dynamic expansion and contraction

  • docker service scale 服务名=numnum indicates the number of services to be scaled
  • docker service update --replicas num 服务名num indicates the number of services to be scaled
[root@localhost ~]# docker service scale myngnix=5
[root@localhost ~]# docker service update --replicas 3 myngnix

The two dynamic scaling commands are equivalent. scale is more convenient

Eight, Docker other commands (understand)

8.1 Docker Stack

docker stack is similar to docker compose

  • docker compose stand-alone container arrangement
  • docker stack cluster container arrangement
[root@localhost ~]# docker stack --help

Usage:  docker stack [OPTIONS] COMMAND

Manage Docker stacks

Options:
      --orchestrator string   Orchestrator to use (swarm|kubernetes|all)

Commands:
  deploy      Deploy a new stack or update an existing stack
  ls          List stacks
  ps          List the tasks in the stack
  rm          Remove one or more stacks
  services    List the services in the stack

8.2 Docker Secret

Security, password configuration, certificates, etc.

[root@localhost ~]# docker secret --help

Usage:  docker secret COMMAND

Manage Docker secrets

Commands:
  create      Create a secret from a file or STDIN as content
  inspect     Display detailed information on one or more secrets
  ls          List secrets
  rm          Remove one or more secrets

8.3 Docker Config

Unified configuration

[root@localhost ~]# docker config --help

Usage:  docker config COMMAND

Manage Docker configs

Commands:
  create      Create a config from a file or STDIN
  inspect     Display detailed information on one or more configs
  ls          List configs
  rm          Remove one or more configs

Guess you like

Origin blog.csdn.net/weixin_45698637/article/details/123999825