本文大量参考b站kuangshen的Docker视频
Docker的常用命令
帮助命令
1 | docker version # 显示docker的版本信息 |
帮助文档的地址:https://docs.docker.com/engine/reference/commandline/build/
镜像命令
docker images
1 | [root@localhost /]# docker images |
docker search 搜索镜像
1 | [root@localhost /]# docker search mysql |
docker pull 下载镜像
1 | 下载镜像 docker pull 镜像名[:tag] |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5oXLHZ6-1607516885224)(Docker%E6%A6%82%E8%BF%B0(1)].assets%5Cimage-20200610165130055.png)
docker rmi 删除镜像
rm——remove i——images
1 | [root@localhost /]# docker rmi -f 镜像id #删除指定镜像 |
容器命令
说明:有了镜像才可以创建容器,linux,下载一个centos镜像来学习
1 | docker pull centos |
新建容器并启动
1 | docker run [可选参数] image |
列出所有运行的容器
1 | docker ps 命令 |
退出容器
1 | exit # 直接退出容器 |
删除容器
1 | docker rm 容器id # 删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -f |
启动和停止容器的操作
1 | docker start 容器id # 启动容器 |
常用其他命令
后台启动容器
1 | 命令 docker run -d 镜像名 |
查看日志
1 | docker logs -f -t --tail 数字 容器id |
查看容器中进程信息
1 | 命令 docker top 容器id |
查看镜像的元数据
1 | 命令 |
进入当前正在运行的容器
1 | 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置 |
从容器内拷贝文件到主机上
1 | docker cp 容器id:容器内目标文件路径 目的主机路径 |
小结

1 | attach Attach to a running container # 当前shell下attach连接指定运行的镜像 |
Docker镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
所有应用,直接打包docker镜像,就可以直接跑起来!
如何得到镜像
- 从远程仓库下载
- 别人拷贝给你
- 自己制作一个镜像 DockerFile
Docker镜像加载原理
UnionFs (联合文件系统)
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加载 kernel, Linux刚启动时会加载bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包括bootloader和 Kernel。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于个精简的OS, rootfs可以很小,只需要包合最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
分层理解
分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载!
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令
1 | ➜ / docker image inspect redis |
理解:
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而整体的大镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的文件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
如何提交一个自己的镜像?
commit镜像
1 | docker commit 提交容器成为一个新的副本 |
实战测试
1 | 1、启动一个默认的tomcat |

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚拟机的快照。
到了这里就算是入门Docker了!
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!==需求:数据可以持久化==
MySQL,容器删除了,删库跑路!==需求:MySQL数据可以存储在本地!==
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载
1 | docker run -it -v 主机目录:容器目录 |

在容器内指定目录下添加或修改一个文件,会同步到主机指定目录下!反之,在主机目录下做相关操作,也会同步到容器对应的目录下!
再来测试!
1、停止容器
2、宿主机修改文件
3、启动容器
4、容器内的数据依旧是同步的!
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
两个路径保持完全的同步!!!双向绑定,一边发生变化,另一边也会随之变化!
具名和匿名挂载
1 | 匿名挂载 |

所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data下!
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用 具名挂载
1 | 如何确定是具名挂载还是匿名挂载,还是指定路径挂载! |
拓展:
1 | 通过 -v 容器内路径:ro 或 rw 改变读写权限 |
初始Dockerfile
Dockerfile 就是用来构建 docker镜像的构建文件!命令脚本! 先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是最终镜像的一层!
1 | 创建一个dockerfile文件,名字可以随机,建议 dockerfile |

注意:我们这里的 dockerfile 是我们编写的文件名哦!
这两个卷和外部一定有两个同步的目录!
查看一下卷挂载在主机上的路径
docker inspect 容器id
测试一下刚才的文件是否同步出去了!
这种方式我们未来使用十分的多,因为我们通常会构建自己的镜像!
假设构建镜像的时候没有挂在卷,要手动镜像挂载即可: (参考上文==具名和匿名挂载==)
1 | -v 卷名:容器内路径 |
数据卷容器(多个容器之间同步数据 )
多个mysql同步数据!



在docker03下创建docker03文件后,进入docker01发现也依旧会同步过来:
1 | # 测试1:删除docker01后,docker02和docker03是否还可以访问原来docker01下创建的的文件? |


多个mysql实现数据共享
1 | ➜ ~ 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 --name mysql01 mysql:5.7 |
结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、 编写一个dockerfile文件
2、 docker build 构建称为一个镜像
3、 docker run运行镜像
4、 docker push发布镜像(DockerHub 、阿里云仓库)
查看官方是怎么做的!
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序
3、# 表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
DockerFile的指令
1 | FROM # 基础镜像,一切从这里开始构建 centos |

实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的( FROM scratch ),然后配置需要的软件和配置来构建。
创建一个自己的 centos
1 | 1、编写DockerFile文件,内容如下: |
生成命令:
1 | docker build -f mydockerfile-centos -t mycentos:0.1 . |
==通过build命令,用写好的mydockerfile-centos文件来构建target(-t 目标)名为mycentos:0.1 .的镜像 [tag]为版本号==
其中from的centos是本地从hub上pull过的镜像(docker images),如果没有 则会自动去pull下载
测试运行:
运行的时候带上版本号 否则获取最新版本
对比:
之前的原生的centos
我们增加之后的镜像

注:net-tools 包含一系列程序,构成了 Linux 网络的基础。
我们可以列出本地镜像的变更历史:
我们平时拿到一个镜像,可以研究一下它是怎么做的!
CMD 和 ENTRYPOINT 的区别
测试CMD
1 | 编写dockerfile文件 |
测试ENTRYPOINT
1 | 编写dockerfile文件 |
Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果!
实战:Tomcat镜像
1、准备镜像文件tomcat压缩包,jdk压缩包!
2、编写Dockerfile文件,官方命名: Dockerfile ,build会自动寻找这个文件,就不要 -f 指定了!
1 | FROM centos |
ADD命令会自动解压压缩包
3、构建镜像
1 | docker build -t diytomcat . diytomcat是定义的镜像名 |
4、启动镜像,创建容器
1 | docker run -d -p 9090:8080 --name kuangshentomcat02 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-8.0.53/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-8.0.53/logs diytomcat |
5、访问测试
6、发布项目(由于做了卷挂载,我们就可以直接在本地发布项目了)
在/home/kuangshen/build/tomcat/test目录下创建WEB-INF目录,在里面创建web.xml文件:
1 |
|
在回到test目录,添加一个index.jsp页面:
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
发现:test项目部署成功,可以直接访问!
1 | [root@localhost tomcatlogs]# cat catalina.out |

之前一直访问失败是web.xml配置有问题,最后也是查看该日志提示,才得以解决!!!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
发布自己的镜像
Docker Hub
2、确定这个账号可以登录
3、在我们服务器上提交自己的镜像
1 | [root@localhost tomcat]# docker login --help |
4、登录完毕后就可以提交镜像了,就是一步 docker push
1 | push自己的镜像到服务器上! |

注意:镜像的重命名前一定要加当前的dockerhub的用户名,否则将会push失败!!!!(如:把ztx115改成ztx, push一定失败!)
1 | docekr push上去即可! 自己平时发布的镜像尽量带上版本号 |

发现,提交时也是按照镜像的层级来进行提交的!
发布到阿里云镜像服务上(狂神视频截图)
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建容器镜像仓库


5、浏览阿里云
使用阿里云容器镜像的参考官方指南即可!!!(即上图)
小结




