Hello Docker!妈妈不会担心你Docker入不了门?

2019-08-0510:34:36WEB前端开发Comments2,585 views字数 9321阅读模式

Docker 是什么呢?百度百科是这样跟我说的:
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
这段话已经很概括的描述了 Docker 是什么,Docker 能干嘛,Docker 的基本特性!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

相信刚开始接触 Docker 的你跟我也一样,看了几遍都很懵逼!没关系,看完全文再回头看这段话,或许就有不一样的体会了!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们先看看 Docker 官方给出的“定妆照”:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

如果非要我用一句话描述这张图片,还在上幼儿园的我会说:“一条可爱的鲸鱼背着多个集装箱,畅游在大海里 ”!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

而现在我会说:“Docker 是一个运行在操作系统上的软件,这个软件上面可以运行多个相互隔离的容器”!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

不同的表述,同一个意思!这条可爱的鲸鱼就是咱们的 Docker,而大海就是我们的操作系统,多个集装箱就是在 Docker 上运行的容器!什么是容器咱们后面会说~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

假如你想漂洋过海来看我,你可以选择自己造一条船,这样你就得自己备足很多干粮,还得准备很多其他的必需品才能出发!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

但是现在有一条鲸鱼游过来对你说,我这里有很多集装箱,里面有你所需要的一切,你选一个适合你的进来就可以了,我会带你乘风破浪的!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

看到这里,你是否对 Docker 有个初步的印象了呢?至少知道了:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

  • Docker 是什么?
  • 为什么需要 Docker?

与传统虚拟机对比
前面我们说过 Docker 可以实现虚拟化,那 Docker 与我们平时用的虚拟机有什么区别和联系呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

在那些年我们还买不起云服务器的时候,如果我们想学 Linux 那就得先安装一个创建虚拟机的软件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

然后在软件上面创建虚拟机,再分配内存、分配磁盘、安装 Linux 操作系统等等一系列的操作,最后等个分把钟让虚拟机运行起来~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

为什么传统虚拟机启动会那么慢呢?因为传统虚拟机技术是虚拟出一套硬件后,在其上面运行一个完整的操作系统,然后在该系统上面再运行所需要的应用程序,并且虚拟机的资源需要提前分配,一旦分配这些资源将全部被占用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

但是 Docker 容器内的应用程序是直接运行于宿主的内核,容器没有自己的内核,更加不会对硬件进行虚拟。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

因此 Docker 容器比传统的虚拟机更为轻便!但是 Docker 容器技术也是参考虚拟机一步一步的迭代优化过来的!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们来看看官方给出的 Docker 容器和传统虚拟机的对比图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

图中也能看出来,Docker 就是一个运行在操作系统上的软件!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

以后如果想在 Windows 上面学习 Linux,只需要在本地安装一个 Windows 版本的 Docker,然后看完本文的剩下的部分,就能轻轻松松的玩转 Linux 啦!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

不过在 Windows 上安装 Docker 也需要先安装一个虚拟机~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

基本组成要素
前面对 Docker 的基本概念有了个大致印象,但是到目前为止,可能你对 Docker 的认识还比较空泛,那下面部分我们就从 Docker 的基本组成要素来更深入的走进 Docker!Docker 是一个 Client-Server 的结构!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

先看看官网给出的架构图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

这张图里面概括了 Docker 的所有的元素!我们就逐一分析 Docker 客户端、Docker 服务、仓库、镜像、容器等概念!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker 客户端
最左边是 Docker 的客户端,类似我们操作 MySQL 的工具 Navcat,只不过我们这里的是没有图形化界面的命令终端。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker 客户端是用户与 Docker 服务交互的窗口!我们能看到图中就是各种操作的命令!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker 服务
中间的是 Docker 后台运行的服务,一个称为 Docker Daemon 的守护进程。可以理解为我们 MySQL 的服务,我们的操作命令都是在这部分进行处理!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker Deamon 监听着客户端的请求,并且管理着 Docker 的镜像、容器、网络、磁盘(图中只列出了镜像与容器)等对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

同样,Docker 的客户端与服务可以运行在同一机器上,也可以用某台机器上的客户端远程连接另一台机器上的 Docker 服务,这跟我们的 MySQL 一样的呢。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

仓库
右边部分是注册仓库,在远古时代做开发的都知道,我们以前需要一个第三方包的时候需要去网上下载对应的 Jar 包,很麻烦不说,还容易下的包是不稳定的版本。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

有了 Maven 之后,我们只要在 Maven 配置文件中引入对应的依赖,就可以直接从远程仓库中下载对应版本的 Jar 包了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker 中的仓库与 Maven 的仓库是一个概念,可以远程下载常用的镜像,也可以 Push 包到远程仓库(如图中的 Redis、Nginx 等镜像),同一个镜像又可以有多个版本,在 Docker 中称为 Tag!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

镜像&容器
前面我们有多次提到镜像和容器,这是 Docker 里面很核心的两个概念。那镜像和容器分别是什么呢?镜像和容器的关系是什么呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

①镜像文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

官方给出的定义是:Docker 镜像是一个只读模板,可以用来创建 Docker 容器。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

镜像是一种轻量级的、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

它包含运行某个软件所需要的所有的内容,包括代码、运行时、库、环境变量、配置文件等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们开发的 Web 应用需要 JDK 环境、需要 Tomcat 容器、需要 Linux 操作系统,那我们可以把我们所需要的一切都进行打包成一个整体(包括自己开发的 Web 应用+JDK+Tomcat+CentOS/Ubuntu+各种配置文件)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

打包后的镜像在某台机器上能运行,那它就能够在任何装有 Docker 的机器上运行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

任何镜像的创建会基于其他的父镜像,也就是说镜像是一层套一层,比如一个 Tomcat 镜像,需要运行在 CentOS/Ubuntu 上。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

那我们的 Tomcat 镜像就会基于 CentOS/Ubuntu 镜像创建(在后面的操作部分我们可以通过命令查看)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这样的结构就类似于我们吃的洋葱,如果你愿意一层一层一层地剥开我的心~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

②容器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

官方给出的定义是:Docker 的容器是用镜像创建的运行实例,Docker 可以利用容器独立运行一个或一组应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们可以使用客户端或者 API 控制容器的启动、开始、停止、删除。每个容器之间是相互隔离的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

上一步我们构建的镜像只是一个静态的文件,这个文件需要运行就需要变为容器,我们可以把容器看做是一个简易版的 Linux 系统和运行在其中的应用程序!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

就是前面看到的鲸鱼背上的一个一个的集装箱,每个集装箱都是独立的!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

③镜像与容器关系文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

上面的概念很抽象,可以理解为容器就是镜像的一个实例,相信大家都写过类似下面的代码:
public void Dog extends Animal{
......
}
......
Dog dog = new Dog()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们在代码中定义了一个 Dog 类,这个类就相当于一个镜像,可以根据这个类 New 出很多的实例,New 出来的实例就相当于一个个的容器。镜像是静态的文件,而容器就是有生命的个体!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Dog 类可以继承父类 Animal,如果不显式的指定继承关系,Dog 类就默认继承 Object 类。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

同样上面也说到过 Docker 中的镜像也有继承关系,一个镜像可以继承其他的镜像创建,添加新的功能!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

看到这里的你是不是对 Docker 有了更多的了解了呢?我们再回头看看百度百科对 Docker 的描述,可能你又会有更深的印象:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
容器数据卷
上面说到容器是一个简易版的 Linux 系统和运行在其中的应用程序,那我们的应用程序产生的数据(比如操作日志、异常日志、数据)也是在容器内的系统中存放的,默认不会做持久化,我们可以进入到容器中查看。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

但是万一有一天,Docker 这条鲸鱼不满人类的压迫,反抗了...老子打烂你的集装箱!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

随着容器的关闭,容器内的数据也会丢失,重新开启的容器不会加载原来的数据(简单说就是容器重新启动又是另外一个实例了)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

那对容器内的数据需要持久化到宿主机上就很有必要了,这就需要了解我们的容器数据卷~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

容器数据卷的设计目的就是做数据的持久化和容器间的数据共享,数据卷完全独立于容器的生命周期,也就是说就算容器关闭或者删除,数据也不会丢失。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

简单点说就将宿主机的目录挂载到容器,应用在容器内的数据可以同步到宿主机磁盘上,这样容器内产生的数据就可以持久化了。关于容器卷的命令,我们后面会有操作实例!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

命令操作
上面说了那么多,下面就到了咱们的实操环节啦!这一节的内容会通过一些常用的命令让大家更进一步的了解 Docker。注意!这里只是一些常用的命令来加深理解,而不是命令大全!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

如果没有安装 Docker 的小伙伴可以自己按照官网的文档进行安装,本文不会讲到这部分的内容!所以我假设你在自己的服务器上已经装好了 Docker!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

帮助命令
①docker version:查看 Docker 客户端和服务的版本。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

②docker info:查看 Docker 的基本信息,如有多少容器、多少镜像、Docker 根目录等等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

③docker --help:查看 Docker 的帮助信息,这个命令可以查看所有 Docker 支持的命令~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这几个命令非常简单,有过一点 Linux 基础的小伙伴应该很容易理解!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

镜像命令
①docker images:查看本地主机上所有的镜像。注意是本地主机的!这里能看到镜像的名称、版本、id、大小等基本信息,注意这里的 imageID 是镜像的唯一标识!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

还可以通过 docker images tomcat 指定某个具体的镜像查看对应信息。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这里还要注意的是 CentOS 的镜像才 200MB 的大小,比我们物理机器上装的 CentOS 要小得多的多,这是因为 CentOS 的镜像只保留了 Linux 核心部分,这也是为什么 Docker 虚拟化技术比虚拟机运行效率更高的原因!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

那为什么 Tomcat 的镜像这么大呢?那是因为我们之前说过我们的镜像就像一个洋葱一样,是一层套一层的!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Tomcat 的运行需要基于 CentOS、JDK 等等镜像,Tomcat 在上层所以体积比较大啦!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

②docker rmi:删除本地的镜像,如下图所示,可以加上 -f 参数进行强制删除。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这里的 rmi 命令跟 Linux 中的删除命令就很像啦,只是这里加了一个 i 代表 image!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

③docker search:根据镜像名称搜索远程仓库中的镜像!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

④docker pull:搜索到某个镜像之后就可以从远程拉取镜像啦,有点类似咱们 Git 中的 Pull 命令,当然对应的还有个 dockerpush 的命令。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

如上图,如果我们没有指定 Tag,默认就会拉取 Latest 版本,也可以通过 docker pull tomcat:1.7 的方式拉取指定版本!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

注意这里在拉取镜像的时候打印出来的信息有很多,这也是前面说到的镜像是一层套一层,拉取一个镜像也是一层一层的拉取!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

容器命令文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

通过镜像命令我们就能获取镜像、删除镜像等操作啦!镜像有了下面自然就需要通过镜像创建对应的实例啦,也就是我们的容器。下面我们以 Tomcat 为例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

①docker run [OPTIONS] IMAGE [COMMAND] [ARG...]:可以基于某个镜像运行一个容器,如果本地有指定的镜像则使用本地镜像,如果没有则从远程拉取对应的镜像然后启动!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

由于这个命令非常重要,所以下面列出几个比较重要的参数:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

  • -d:启动容器,并且后台运行(Docker 容器后台运行,就必须要有一个前台进程,容器运行的命令如果不是一直挂起的命令,容器启动后就会自动退出)。
  • -i:以交互模式运行容器,通常与 -t 同时使用。
  • -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用(容器启动后进入到容器内部的命令窗口)。
  • -P:随机端口映射,容器内部端口随机映射到主机的高端口。
  • -p:指定端口映射,格式为:主机(宿主)端口:容器端口。
  • -v:建立宿主机与容器目录的同步。
  • --name="myTomcat":为容器指定一个名称(如果不指定,则有个随机的名字)。
Hello Docker!妈妈不会担心你Docker入不了门?

上面我通过命令启动了一个 Tomcat 的容器,由于使用了 -t 的参数,所以容器启动后就进入到了容器的内部的命令窗口,打印了很多 Tomcat 启动的日志。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

并且使用 -p 参数指定了端口映射,也就是容器内 Tomcat 运行的端口是 8080,并且映射到了宿主机上的 8888 端口,这样我们在外部就可以通过服务器的 ip+8888 端口访问到我们容器内部 Tomcat 部署的服务了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

前面我们提到过容器内的数据会随着容器的关闭而丢失。那我们就需要有容器数据卷的技术能将容器内的数据持久化到宿主机。这里需要用到 -v 参数!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们看下面的截图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

这里第一个要注意的是我们用的 -d 参数,启动后没有进入到容器内部,还是在宿主机。(可以对比一下与上面 -it 参数的区别)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

第二个要注意的是 -v /宿主机:/容器内目录实现了宿主机与容器内指定目录的数据同步!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

容器启动后就可以使用 Linux 的 ll 命令查看宿主机上已经同步到了容器内的文件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

第三个要注意的是这里的同步是双向的,也就是说在宿主机上对文件的修改也会同步到容器内部!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

多个不同的容器映射到宿主机的同一个目录,就可以实现不同容器间的数据共享啦!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

②进入到容器后可以通过 exit 命令退出容器,也可以通过 Ctrl+P+Q 快捷键退出容器,这两种方式的不同之处是 exit 会退出并且关闭容器,而 Ctrl+P+Q 快捷键只是单纯的退出,容器还在运行,并且还能再次进入!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

③docker ps:我们可以通过该命令查看正在运行的容器的信息,这里能看到容器的唯一 id,启动时间等等...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这里跟 Linux 的 ps 命令类似,所以也可以把容器理解为一个运行在 Docker 上的进程!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

docker ps -a 可以查看运行中与停止的所有容器:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

④docker attach [OPTIONS] CONTAINER:上面说过通过 Ctrl+P+Q 快捷键退出容器后容器还在后台运行,那如果想再次进入容器怎么办呢?我们就可以通过 attach 命令+容器的 id 再次进入容器!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

⑤docker exec [OPTIONS] CONTAINER:这个命令与 attach 一样都可以再次进入后台运行的容器,但是该命令可以不进入容器而在运行的容器中执行命令!比 attach 更加强大!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

⑥docker stop、docker kill、docker restart:这三个命令分别用来停止容器、强制停止容器和重启容器,就跟我们在 Linux 上停止、强制停止和重启某个进程一样的啦,这里就不做演示了!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

⑦docker rm:使用这个命令就可以删除某个容器,这里跟删除镜像的区别是这里少了一个 i 啦!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

需要注意的是通过 Stop 和 Kill 停止的容器还存在于 Docker 中,而使用 rm 命令操作后的容器将不再存在!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

⑧docker inspect:查看容器的详情(也能查看镜像详情)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Dockerfile
前面我们对 Docker 以及相关概念、常用命令有了基本的了解,我们也知道了可以从远程 Pull 一个镜像,那远程的镜像是怎么来的呢?如果我们想自己创建一个镜像又该怎么做呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

对,Dockerfile!Dockerfile 是一个包含用户能够构建镜像的所有命令的文本文档,它有自己的语法以及命令,Docker 能够从 Dockerfile 中读取指令自动的构建镜像!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

我们要想编写自己的 Dockerfiler 并构建镜像,那对 Dockerfile 的语法和命令的了解就是必须的,了解规则才好办事嘛!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

相关指令
FROM文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

FROM <image> [AS<name>]
FROM <image>[:<tag>][AS <name>]
FROM<image>[@<digest>] [AS <name>]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

指定基础镜像,当前镜像是基于哪个镜像创建的,有点类似 Java 中的类继承。FROM 指令必是 Dockerfile 文件中的首条命令。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

MAINTAINER文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

MAINTAINER <name>文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

镜像维护者的信息,该命令已经被标记为不推荐使用了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

LABEL文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

LABEL<key>=<value><key>=<value><key>=<value> ...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

给镜像添加元数据,可以用 LABEL 命令替换 MAINTAINER 命令。指定一些作者、邮箱等信息。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ENV文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ENV <key><value>
ENV <key>=<value> ...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

设置环境变量,设置的变量可供后面指令使用。跟 Java 中定义变量差不多的意思!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

WORKDIR文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

WORKDIR /path/to/workdir文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

设置工作目录,在该指令后的 RUN、CMD、ENTRYPOINT, COPY、ADD 指令都会在该目录执行。如果该目录不存在,则会创建!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

RUN文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

RUN <command>
RUN ["executable","param1", "param2"]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

RUN 会在当前镜像的最上面创建一个新层,并且能执行任何的命令,然后对执行的结果进行提交。提交后的结果镜像在 Dockerfile 的后续步骤中可以使用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ADD文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ADD[--chown=<user>:<group>] <src>... <dest>
ADD[--chown=<user>:<group>] ["<src>",..."<dest>"]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

从宿主机拷贝文件或者文件夹到镜像,也可以复制一个网络文件!如果拷贝的文件是一个压缩包,会自动解压缩!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

COPY文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

COPY[--chown=<user>:<group>] <src>... <dest>
COPY[--chown=<user>:<group>] ["<src>",..."<dest>"]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

从宿主机拷贝文件或者文件夹到镜像,不能复制网络文件也不会自动解压缩!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

VOLUME文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

VOLUME ["/data"]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

VOLUME 用于创建挂载点,一般配合 run 命令的 -v 参数使用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

EXPOSE文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

EXPOSE <port>[<port>/<protocol>...]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

指定容器运行时对外暴露的端口,但是该指定实际上不会发布该端口,它的功能是镜像构建者和容器运行者之间的记录文件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

回到容器命令中的 run 命令部分,run 命令有 -p 和 -P 两个参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

如果是 -P 就是随机端口映射,容器内会随机映射到 EXPOSE 指定的端口;如果是 -p 就是指定端口映射,告诉运维人员容器内需要映射的端口号。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

CMD文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

CMD["executable","param1","param2"]
CMD["param1","param2"]
CMD command param1 param2文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

指定容器启动时默认运行的命令,在一个 Dockerfile 文件中,如果有多个 CMD 命令,只有一个最后一个会生效!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

同样是可以执行命令,可能你会觉得跟上面的 RUN 指令很相似,RUN 指令是在构建镜像时候执行的,而 CMD 指令是在每次容器运行的时候执行的!docker run 命令会覆盖 CMD 的命令!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ENTRYPOINT文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ENTRYPOINT["executable", "param1", "param2"]
ENTRYPOINT command param1 param2文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

这个指令与 CMD 指令类似,都是指定启动容器时要运行的命令,如果指定了 ENTRYPOINT,则 CMD 指定的命令不会执行!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

在一个 Dockerfile 文件中,如果有多个 ENTRYPOINT 命令,也只有一个最后一个会生效!不同的是通过 docker run command 命令会覆盖 CMD 的命令!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

执行的命令不会覆盖 ENTRYPOINT,docker run 命令中指定的任何参数都会被当做参数传递给 ENTRYPOINT!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

RUN、CMD、ENTRYPOINT 区别:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

  • RUN 指令是在镜像构建时运行,而后两个是在容器启动时执行!
  • CMD 指令设置的命令是容器启动时默认运行的命令,如果 docker run 没有指定任何的命令,并且 Dockerfile 中没有指定 ENTRYPOINT,那容器启动的时候就会执行 CMD 指定的命令!有点类似代码中的缺省参数!
  • 如果设置了 ENTRYPOINT 指令,则优先使用!并且可以通过 dockerrun 给该指令设置的命令传参!
  • CMD 有点类似代码中的缺省参数。

USER文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

USER <user>[:<group>]
USER <UID>[:<GID>]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

用于指定运行镜像所使用的用户。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ARG文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ARG <name>[=<defaultvalue>]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

指定在镜像构建时可传递的变量,定义的变量可以通过 dockerbuild --build-arg = 的方式在构建时设置。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ONBUILD文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

ONBUILD [INSTRUCTION]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

当所构建的镜像被当做其他镜像的基础镜像时,ONBUILD 指定的命令会被触发!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

STOPSIGNAL文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

STOPSIGNAL signal文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

设置当容器停止时所要发送的系统调用信号!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

HEALTHCHECK文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

HEALTHCHECK [OPTIONS] CMD command (在容器内运行运行命令检测容器的运行情况)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

HEALTHCHECK NONE (禁止从父镜像继承检查)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

该指令可以告诉 Docker 怎么去检测一个容器的运行状况!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

SHELL文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

SHELL ["executable","parameters"]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

用于设置执行命令所使用的默认的 Shell 类型!该指令在 Windows 操作系统下比较有用,因为 Windows 下通常会有 CMD 和 Powershell 两种 Shell,甚至还有 SH。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

构建
Dockerfile 执行顺序是从上到下,顺序执行!每条指令都会创建一个新的镜像层,并对镜像进行提交。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

编写好 Dockerfile 文件后,就需要使用 dockerbuild 命令对镜像进行构建了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

docker build 的格式:
docker build [OPTIONS] PATH | URL | -文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

-f:指定要使用的 Dockerfile 路径,如果不指定,则在当前工作目录寻找 Dockerfile 文件!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

-t:镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

例如我们可以 docker build -t myApp:1.0.1 . 这样来构建自己的镜像,注意后面的 . , 用于指定镜像构建过程中的上下文环境的目录。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

如果大家想了解那些官方镜像的 Dockerfile 文件都是怎么样写的,可以上 hub.docker.com/ 进行搜索。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

以 Tomcat 镜像为例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

能看到 Tomcat 镜像的父镜像是 OpenJDK 镜像,我们再搜索 OpenJDK 的 Dockerfile 文件:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

OpenJDK 镜像的父镜像又是 OracleLinux 镜像,我们再搜索 OracleLinux 的 Dockerfile 文件:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

Hello Docker!妈妈不会担心你Docker入不了门?

OpenJDK 镜像的父镜像是 Scratch,这是根镜像,所有的镜像都会依赖该镜像,就像我们代码中所有的对象的父类都是 Object!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

所以能看到 Tomcat 镜像就是这样一层一层的构建出来的,这也是为什么前面通过 docker images 查看到的 Tomcat 镜像为什么会有四百多兆的原因啦!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

看到这里的你,是否对 Docker 是什么?为什么需要 Docker?Docker 镜像、Docker 容器的概念是什么?Docker 中常用的命令有哪些?Dockerfile 有哪些指令?怎么去构建自己的镜像?这些问题都能明白了呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

作者:苏静文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/14986.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/14986.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定