一、docker是什么
Docker 是一个基于GO语言开发的开源应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
--- 摘自百度词条
二、历史
2010年,成立dotCloud,并将公司的容器化技术命名为Docker,Docker刚刚诞生时,没有引起太多人的注意,直到开源(2013)之后,才火爆。
三、解决的问题
解决的问题:
- 不同平台导致的问题不能复现:比如代码放在别人的电脑上运行出现的问题,在自己电脑上没有复现。
- 环境配置麻烦:项目比较复杂,每一人都要在自己的电脑上部署相关环境,太费事了。
- 应用隔离。
所以docker就能解决这些问题,在项目的Dockerfile或者docker-compose.yuml中配置好相关内容,发给别人,别人直接安装docker,起镜像就可以,不会有环境的差异。
容器化技术 VS 虚拟机
虚拟机:
缺点:
- 资源占用十分多
- 冗余步骤多
- 启动很慢
容器化技术:
并不是一个完整的操作系统,是一个删减版的。
$emsp; 对比:
- 传统虚拟机,直接虚拟一套硬件环境,运行一个完整的操作系统,然后在这个操作系统上安装和运行应用。
- 容器内的应用是直接运行在宿主机上,使用宿主机的内核,容器是没有自己的内核的,也没有硬件,所以比较轻巧。
- 容器之间是隔离的,每一个容器都有自己的文件系统。
四、名词概念
- 镜像(image):相当于一个模版。
- 容器(container):一个镜像可以启动成多个容器,相当于复制吧。
- 仓库(repository):存放镜像的地方。分为公有仓库和私有仓库。
五、基本组成

六、启动流程(run)和原理
1、启动流程
2、原理
Docker是一个C/S结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。DockerServer接收到DockerClient指令之后开始执行。
3、docker为什么比VM快?
- docker有着比虚拟机更少的抽象层。
- docker是直接运行在宿主机上的,而VM需要重新加载一次操作系统内核。虚拟机加载Guest OS,分钟级别的,而docker是利用的宿主机的操作系统,秒级。
七、 nginx容器端口暴漏

八、 Docker镜像加载原理
联合文件系统
UnionFS(联合文件系统):是一种分层、轻量级且高性能的文件系统。它支持对文件系统的修改作为一次提交来一层层叠加,同时将不同目录挂载到同一个虚拟文件系统下。Docker镜像就是基于这种技术实现的,镜像可以分层来进行继承,基于基础镜像,我们可以制作各种镜像。
特性:一次同时加载多个文件系统,从外面看是一个文件系统,联合加载会将这些文件系统进行叠加。
镜像加载原理
docker镜像实际上就是一层层的文件系统组成的。
- bootfs:主要包含bootloader和kernel。bootloader的作用是引导加载kernel,在boot加载完成之后,将内存的操作权交给kernel之后,就会卸载。(各容器共用一个,这个的加载是比较耗时的)
- rootfs:操作系统的发行版,比如吧centos。

镜像分层
UnionFs压缩之后:
层相同时,直接复用。
我们下载下来的镜像是不可更改的,我们容器的变动都是在下载下来的镜像之上操作的。

九、容器卷
为什么要使用容器卷?因为docker容器中的数据是保存在容器内部的,一旦删除容器,数据就会丢失,所以需要将容器内的数据保存在本地服务器上一份,即数据共享。 容器间数据也是可以共享的。 服务器和容器数据挂载使用-v,容器之间的挂载使用的是--volumes-from。 这里的数据共享实际上是数据的同步拷贝。
十、具名挂载、匿名挂载、指定路径挂载

这里第一个就是匿名挂载,启动方法如:
docker run -dit -p 80801:80 --name nginx1 -v /etc/nginx nginx /bin/sh
第二个是具名挂载,启动方法如:
docker run -dit -p 80802:80 --name nginx2 -v juming:/etc/nginx nginx /bin/sh

除此之外还有一种指定路径挂载,启动方法如:
docker run -dit -p 8083:80 --name nginx3 -v /data/nginx:/etc/nginx nginx /bin/sh
拓展: 有些时候会这样写:
-v /data/nginx:/etc/nginx:ro
ro代表挂载文件只读(read-only) rw代表挂载文件可读可写(read-write)
CMD和ENTRYPOINT的区别
CMD指定容器启动时,要运行的命令,只有最后一个才会生效,可替换。 ENTRYPOINT指定容器启动时,要运行的命令,可追加。
十一、网络
我们每启动一个docker容器,docker就会给容器分配一个ip。只要我们安装了docker,就会有一个网卡docker0。 容器与容器通信使用的是桥接模式,使用的技术是evth-pair技术。 $emsp; 每启动一个容器,都会生成一对evth-pair网卡。evth-pair是一对虚拟接口,都是成对成对出现的。
1、docker0转发
容器通信:

其中红色部分就是evth-pair的网卡。docker0充当路由器的作用,要么广播,要么在路由表里面找进行路由。 在不指定网络的情况下,都是docker0进行路由的。 docker中的网络接口都是虚拟的,因为转发效率高。 该技术不支持容器名连接访问。
2、--link
一个比较老的技术。已经不建议使用了。
在启动容器时,使用--link,来绑定要连通的容器,会在该容器的hosts里面加上启动容器的ip和id映射,但是是单向的,要双向通信,要两个容器都--link。使用该技术,不支持容器名连接访问。
3、网络模式
网络模式有:
- bridge:桥接模式。默认的,自己创建的网络也是使用的桥接模式。
- none:不配置网络。
- host:和宿主机共享网络。
- container:容器网络连通。(很少用。局限性大)
创建好自己网络之后,同一网络中的容器能够使用容器名ping通。
4、网络连通
不同网段的容器和网络进行连接,使用例如:
docker network connect myNetwork nginx3 只有nginx就有两个网络,每个网络中都有一个属于自己的ip地址。
注意: 有些镜像启动容器时,使用-d之后,docker ps发现没有启动容器,因为后台运行时,必须要有一个前台进程,如果没有,容器就会自杀。
