正文
学习都是通过先了解概念,然后串联概念形成知识体系。所以我们先来学习几个概念吧。
Docker只是做了资源的隔离,无法做到不同操作系统的移植。
它更像一个大文件夹,里面有项目运行时所需的所有资源。比如以往的项目中多个微服务依赖相同的环境但是版本不同,这会很混乱。但是通过容器,自己的东西全部放在自己的容器中,所以也有定义说容器具有操作系统的全部文件和目录,但是不包括内核,所以很好理解每个容器中都有自己的目录结构。
概念
镜像(Image)
镜像可以把它理解成一个文件夹,提供项目运行时所需的程序、库、资源、配置等文件,另外还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
当我们移植项目时指的就是移植镜像。镜像和后面的容器(Container)和仓库(Repository)概念息息相关
容器(Container)
这是Docker最重要的概念,项目运行就是运行在一个容器中,镜像与容器的关系,就是面向对象编程中类与对象的关系,我们定好每一个类,然后使用类创建对象,对应到Docker的使用上,则是构建好每一个镜像,然后使用镜像创建我们需要的容器。
这里有一个关键的点,容器其实只是运行中的一个进程,所以可以这么比喻:镜像有实体,就是我们的文件代码;但是容器没有,它只是一个进程存在在内存中。能更好的帮助理解:移植是移动镜像,容器可以有多个等意思。
Dockerfile
上面的比喻有个不恰当的地方就是,镜像确确的来说也不是文件代码,对文件代码进行一系列命令运行之后才是镜像,这一系列的代码就是写在Dockerfile中。
所以启动一个容器的步骤是:编辑Dockerfile文件;执行build命令,这个命令会去执行Dockerfile文件,生成镜像;然后执行run命令生成容器并启动。
仓库(Repository)
存放镜像的地方就叫仓库,类似github,全世界的仓库是https://hub.docker.com。可以拉取和上传。
数据卷
当我们需要在宿主机上操作容器内的文件,这就需要数据卷了,它可以建立双方文件夹的映射。
Container networking(容器网络)
一个完整的项目可能存在很多容器,比如node,mysql,redis,webapp等,它们彼此之间可能存在通信问题,比如node容器如何连接mysql的服务等。 为此,docker提供了网络通信。
docker-compose
一个完整的项目可能通过很多容器组成,启动容器、挂载网络,指定数据卷会变非常的麻烦,docker-compose为我们解决了这个问题。
写时复制机制
写时复制 ( Copy on Write ) 这个词对于开发者来说应该并不陌生,在很多编程语言里,都隐藏了写时复制的实现。在编程里,写时复制常常用于对象或数组的拷贝中,当我们拷贝对象或数组时,复制的过程并不是马上发生在内存中,而只是先让两个变量同时指向同一个内存空间,并进行一些标记,当我们要对对象或数组进行修改时,才真正进行内存的拷贝。
Docker 的写时复制与编程中的相类似,也就是在通过镜像运行容器时,并不是马上就把镜像里的所有内容拷贝到容器所运行的沙盒文件系统中,而是利用 UnionFS 将镜像以只读的方式挂载到沙盒文件系统中。只有在容器中发生对文件的修改时,修改才会体现到沙盒环境上。
也就是说,容器在创建和启动的过程中,不需要进行任何的文件系统复制操作,也不需要为容器单独开辟大量的硬盘空间,与其他虚拟化方式对这个过程的操作进行对比,Docker 启动的速度可见一斑。
采用写时复制机制来设计的 Docker,既保证了镜像在生成为容器时,以及容器在运行过程中,不会对自身造成修改。又借助剔除常见虚拟化在初始化时需要从镜像中拷贝整个文件系统的过程,大幅提高了容器的创建和启动速度。可以说,Docker 容器能够实现秒级启动速度,写时复制机制在其中发挥了举足轻重的作用。
Docker的组成与架构
Docker跟大部分服务端软件一样(如MySQL),都是使用C/S的架构模型,也就是通过客户端调用服务器,只是我们现在刚好服务端和客户端都在同一台机器上而已。
- Client端 主要是我们使用命令的地方。
- Server端(也叫守卫进程) 为客户端提供了处理命令、容器、镜像、数据卷、网络管理等功能。
概念有机结合
我们拉取镜像,然后根据镜像创建并运行容器,在客户端输入各种命令时,如创建镜像、创建运行容器、挂载数据卷、开辟网络等,这些命令都是了在client端输入,传给Server端,由它来做处理。
命令
镜像相关
#根据Dockerfile构建镜像
docker build -t 镜像名字 .(执行的Dockerfile的路径,'.'表示当前路径)
#根据容器创建镜像
docker commit -a 作者 -m 描述的信息 容器id 镜像的名字:镜像的tag
#列出所有镜像
docker image ls
#从仓库拉取镜像
docker pull 镜像名字
#删除镜像
dockere rmi 镜像名字/镜像id
容器相关
#查看容器
docker ps(查看运行中的容器) -a(查看所有容器)
#启动/停止/重启容器
docker start stop reset /容器id
#创建并启动容器
docker run
-d(后台运行容器,并返回容器ID) /
-i(以交互模式运行容器,通常与 -t 同时使用) /
-t(为容器重新分配一个伪输入终端,通常与 -i 同时使用) /
-p(端口映射,格式为:主机(宿主)端口:容器端口) /
-v(绑定数据卷) /
--name(为容器指定一个名称) /
--net(指定容器的网络连接类型)
/bin/bash(表示启动容器后执行的第一个命令,这里表示启动Bash,保证用户可以使用 Shell)
#进入容器
docker exec -it 容器id
#查看容器的输出
docker container logs 容器id -f(实时监控) --tail(获得最后行数的信息) 行数 -t(加上时间戳)