这多是最为详细的Docker入门吐血总结

这多是最为详细的Docker入门吐血总结

 https://www.cnblogs.com/ECJTUACM-873284962/p/9789130.html

Docker是什么?

在计算机技术突飞猛进的今天, Docker 在国内发展的如火如荼,特别是在一线互联网公司, Docker 的使用是十分广泛的,甚至成为了一些企业面试的加分项,不信的话看看下面这张图。html

这是我在某招聘网站上看到的招聘 Java开发工程师 的招聘要求,其中有一条熟悉 docker 成为了你快速入职的加分项,因而可知熟悉 docker 在互联网公司的地位之重要。python

固然对于咱们 CTF选手 而言,熟悉 docker 能够快速搭建 CTF环境 ,完美地还原比赛真实漏洞的场景,帮助咱们快速提高本身。linux

市面上已经有不少优秀的教程,可是不少原理性的东西,笔者认为那些教程对初学者而言仍是很难理解,感受没有说清楚(笔者本身都以为挺懵逼的),为了让初学者少走弯路,我将以个人学习经历以及做为一个 CTF选手 的角度,编写此套教程,来带你们去了解并熟练运用 docker ,祝愿各位读者朋友们学完此套教程后,在将来企业面试中可以多一项加分的筹码,可以帮助到你们,我以为就很值了。nginx

既然说了这么多, docker 究竟是个什么东西呢?git

咱们在理解 docker 以前,首先咱们得先区分清楚两个概念,容器虚拟机github

可能不少读者朋友都用过虚拟机,而对容器这个概念比较的陌生。web

咱们用的传统虚拟机如 VMware , VisualBox 之类的须要模拟整台机器包括硬件,每台虚拟机都须要有本身的操做系统,虚拟机一旦被开启,预分配给它的资源将所有被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操做系统。面试

而容器技术是和咱们的宿主机共享硬件资源及操做系统,能够实现资源的动态分配。容器包含应用和其全部的依赖包,可是与其余容器共享内核。容器在宿主机操做系统中,在用户空间以分离的进程运行。sql

容器技术是实现操做系统虚拟化的一种途径,可让您在资源受到隔离的进程中运行应用程序及其依赖关系。经过使用容器,咱们能够轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器能够帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予咱们对资源更多的精细化控制能力,让咱们的基础设施效率更高。经过下面这幅图咱们能够很直观的反映出这二者的区别所在。docker

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

而 Linux 容器是 Linux 发展出了另外一种虚拟化技术,简单来说, Linux 容器不是模拟一个完整的操做系统,而是对进程进行隔离,至关因而在正常进程的外面套了一个保护层。对于容器里面的进程来讲,它接触到的各类资源都是虚拟的,从而实现与底层系统的隔离。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行同样。有了 Docker ,就不用担忧环境问题。

整体来讲, Docker 的接口至关简单,用户能够方便地建立和使用容器,把本身的应用放入容器。容器还能够进行版本管理、复制、分享、修改,就像管理普通的代码同样。

Docker的优点

Docker相比于传统虚拟化方式具备更多的优点:

  • docker 启动快速属于秒级别。虚拟机一般须要几分钟去启动
  • docker 须要的资源更少, docker 在操做系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于经过 Hypervisor 层与内核层的虚拟化
  • docker 更轻量, docker 的架构能够共用一个内核与共享应用程序库,所占内存极小。一样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率很是高
  • 与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离
  • 安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提高为root权限,它就直接具有了宿主机的root权限,进而可进行无限制的操做。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,而且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术能够防止虚拟机突破和彼此交互,而容器至今尚未任何形式的硬件隔离,这使得容器容易受到攻击
  • 可管理性: docker 的集中化管理工具还不算成熟。各类虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力
  • 高可用和可恢复性: docker 对业务的高可用支持是经过快速从新部署实现的。虚拟化具有负载均衡,高可用,容错,迁移和数据保护等通过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
  • 快速建立、删除:虚拟化建立是分钟级别的, Docker 容器建立是秒级别的, Docker 的快速迭代性,决定了不管是开发、测试、部署均可以节约大量时间
  • 交付、部署:虚拟机能够经过镜像实现环境交付的一致性,但镜像分发没法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署

咱们能够从下面这张表格很清楚地看到容器相比于传统虚拟机的特性的优点所在:

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 通常为MB 通常为GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 通常是几十个

Docker的三个基本概念

从上图咱们能够看到,Docker 中包括三个基本的概念:

  • Image(镜像)
  • Container(容器)
  • Repository(仓库)

镜像是 Docker 运行容器的前提,仓库是存放镜像的场所,可见镜像更是 Docker 的核心。

Image (镜像)

那么镜像究竟是什么呢?

Docker 镜像能够看做是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建以后也不会被改变。

镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,下面的这张图可以帮助读者理解镜像的定义。

从左边咱们看到了多个只读层,它们重叠在一块儿。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker 内部的实现细节,而且可以在主机的文件系统上访问到。统一文件系统 (union file system) 技术可以将不一样的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。咱们能够在图片的右边看到这个视角的形式。

Container (容器)

容器 (container) 的定义和镜像 (image) 几乎如出一辙,也是一堆层的统一视角,惟一区别在于容器的最上面那一层是可读可写的。

因为容器的定义并无说起是否要运行容器,因此实际上,容器 = 镜像 + 读写层。

Repository (仓库)

Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,能够很容易的在当前宿主上运行,可是, 若是须要在其它服务器上使用这个镜像,咱们就须要一个集中的存储、分发镜像的服务,Docker Registry (仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository) 和仓库注册服务器 (Registry) 混为一谈,并不严格区分。Docker 仓库的概念跟 Git 相似,注册服务器能够理解为 GitHub 这样的托管服务。实际上,一个 Docker Registry 中能够包含多个仓库 (Repository) ,每一个仓库能够包含多个标签 (Tag),每一个标签对应着一个镜像。因此说,镜像仓库是 Docker 用来集中存放镜像文件的地方相似于咱们以前经常使用的代码仓库。

一般,一个仓库会包含同一个软件不一样版本的镜像,而标签就经常使用于对应该软件的各个版本 。咱们能够经过<仓库名>:<标签>的格式来指定具体是这个软件哪一个版本的镜像。若是不给出标签,将以 latest 做为默认标签.。

仓库又能够分为两种形式:

  • public(公有仓库)
  • private(私有仓库)

Docker Registry 公有仓库是开放给用户使用、容许用户管理镜像的 Registry 服务。通常这类公开服务容许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

除了使用公开服务外,用户还能够在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 镜像,能够直接使用作为私有 Registry 服务。当用户建立了本身的镜像以后就可使用 push 命令将它上传到公有或者私有仓库,这样下次在另一台机器上使用这个镜像时候,只须要从仓库上 pull 下来就能够了。

咱们主要把 Docker 的一些常见概念如 Image , Container , Repository 作了详细的阐述,也从传统虚拟化方式的角度阐述了 docker 的优点,咱们从下图能够直观地看到 Docker 的架构:

framework

Docker 使用 C/S 结构,即客户端/服务器体系结构。 Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像。 Docker 客户端和服务端能够运行在一台机器上,也能够经过 RESTful 、 stock 或网络接口与远程 Docker 服务端进行通讯。

docker-framework

这张图展现了 Docker 客户端、服务端和 Docker 仓库(即 Docker Hub 和 Docker Cloud ),默认状况下Docker 会在 Docker 中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念相似于 Git ,固然这个仓库是能够经过修改配置来指定的,甚至咱们能够建立咱们本身的私有仓库。

Docker的安装和使用

Docker 的安装和使用有一些前提条件,主要体如今体系架构和内核的支持上。对于体系架构,除了 Docker 一开始就支持的 X86-64 ,其余体系架构的支持则一直在不断地完善和推动中。

Docker 分为 CE 和 EE 两大版本。 CE 即社区版(免费,支持周期 7 个月), EE 即企业版,强调安全,付费使用,支持周期 24 个月。

咱们在安装前能够参看官方文档获取最新的 Docker 支持状况,官方文档在这里:

https://docs.docker.com/install/

Docker 对于内核支持的功能,即内核的配置选项也有必定的要求(好比必须开启 Cgroup 和 Namespace 相关选项,以及其余的网络和存储驱动等), Docker 源码中提供了一个检测脚原本检测和指导内核的配置,脚本连接在这里:

https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh

在知足前提条件后,安装就变得很是的简单了。

Docker CE 的安装请参考官方文档:

  • MacOS:https://docs.docker.com/docker-for-mac/install/
  • Windows:https://docs.docker.com/docker-for-windows/install/
  • Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/
  • Debian:https://docs.docker.com/install/linux/docker-ce/debian/
  • CentOS:https://docs.docker.com/install/linux/docker-ce/centos/
  • Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/
  • 其余 Linux 发行版:https://docs.docker.com/install/linux/docker-ce/binaries/

这里咱们以 CentOS7 做为本文的演示。

环境准备

  • 阿里云服务器(1核2G,1M带宽)
  • CentOS 7.4 64位

因为 Docker-CE 支持 64 位版本的 CentOS7 ,而且要求内核版本不低于 3.10

首先咱们须要卸载掉旧版本的 Docker

$ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine

咱们执行如下安装命令去安装依赖包:

$ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2

这里我事先已经安装过了,因此提示我已经安装了最新版本

安装Docker

Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。所以想要安装 docker,只须要运行下面的 yum 命令

$ sudo yum install docker

固然在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可使用这套脚本安装:

curl -fsSL get.docker.com -o get-docker.sh sh get-docker.sh

具体能够参看 docker-install 的脚本:

https://github.com/docker/docker-install

执行这个命令后,脚本就会自动的将一切准备工做作好,而且把 Docker CE 的 Edge 版本安装在系统中。

安装完成后,运行下面的命令,验证是否安装成功:

docker version or docker info

返回docker的版本相关信息,证实 docker 安装成功

启动Docker-CE

$ sudo systemctl enable docker $ sudo systemctl start docker

Docker的简单运用---Hello World

因为服务器平常崩溃了, docker 出了点问题,因此如下案例的演示是基于 Kali Linux 环境下进行的。

咱们经过最简单的 image 文件 hello world,感觉一下 Docker 的魅力吧!

咱们直接运行下面的命令,将名为 hello-world 的 image 文件从仓库抓取到本地。

docker pull library/hello-world

docker pull images 是抓取 image 文件, library/hello-world 是 image 文件在仓库里面的位置,其中 library 是 image 文件所在的组, hello-world 是 image 文件的名字。

抓取成功之后,就能够在本机看到这个 image 文件了。

docker images

咱们能够看到以下结果:

如今,咱们能够运行 hello-world 这个 image 文件

docker run hello-world

咱们能够看到以下结果:

输出这段提示之后,hello world 就会中止运行,容器自动终止。有些容器不会自动终止,由于提供的是服务,好比Mysql镜像等。

是否是很 easy 呢?咱们从上面能够看出, docker 的功能是十分强大的,除此以外,咱们还能够拉去一些 Ubuntu , Apache 等镜像,在将来的教程中咱们将会一一提到。

Docker 提供了一套简单实用的命令来建立和更新镜像,咱们能够经过网络直接下载一个已经建立好了的应用镜像,并经过 Docker RUN 命令就能够直接使用。当镜像经过 RUN 命令运行成功后,这个运行的镜像就是一个 Docker 容器啦,容器能够理解为一个轻量级的沙箱, Docker 利用容器来运行和隔离应用,容器是能够被启动、中止、删除的,这并不会影响 Docker 镜像。

咱们能够看看下面这幅图:

Docker 客户端是 Docker 用户与 Docker 交互的主要方式。当您使用 docker 命令行运行命令时, Docker 客户端将这些命令发送给服务器端,服务端将执行这些命令。 docker 命令使用 docker API 。 Docker 客户端能够与多个服务端进行通讯。

咱们将剖析一下 Docker 容器是如何工做的,学习好Docker容器工做的原理,咱们就能够本身去管理咱们的容器了。

Docker架构

在上面的学习中,咱们简单地讲解了Docker的基本架构。了解到了Docker 使用的是 C/S 结构,即客户端/服务器体系结构。明白了 Docker 客户端与 Docker 服务器进行交互时, Docker 服务端负责构建、运行和分发 Docker 镜像。 也知道了Docker 客户端和服务端能够运行在一台机器上,能够经过 RESTful 、 stock 或网络接口与远程 Docker 服务端进行通讯。

咱们从下图能够很直观的了解到Docker的架构:

Docker 的核心组件包括:

  1. Docker Client
  2. Docker daemon
  3. Docker Image
  4. Docker Registry
  5. Docker Container

Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器能够运行在同一个 Host 上,客户端也能够经过 socket 或 REST API 与远程的服务器通讯。可能不少朋友暂时不太理解一些东西,好比 REST API 是什么东西等,不过不要紧,在后面的文章中会一一给你们讲解清楚。

Docker Client

Docker Client ,也称 Docker 客户端。它其实就是 Docker 提供命令行界面 (CLI) 工具,是许多 Docker 用户与 Docker 进行交互的主要方式。客户端能够构建,运行和中止应用程序,还能够远程与Docker_Host进行交互。最经常使用的 Docker 客户端就是 docker 命令,咱们能够经过 docker 命令很方便地在 host 上构建和运行 docker 容器。

Docker daemon

Docker daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,咱们也把它称为守护进程。它负责响应来自 Docker Client 的请求,而后将这些请求翻译成系统调用完成容器管理操做。该进程会在后台启动一个 API Server ,负责接收由 Docker Client 发送的请求,接收到的请求将经过Docker daemon 内部的一个路由分发调度,由具体的函数来执行请求。

咱们大体能够将其分为如下三部分:

  • Docker Server
  • Engine
  • Job

Docker Daemon的架构以下所示:

Docker Daemon 能够认为是经过 Docker Server 模块接受 Docker Client 的请求,并在 Engine 中处理请求,而后根据请求类型,建立出指定的 Job 并运行。 Docker Daemon 运行在 Docker host 上,负责建立、运行、监控容器,构建、存储镜像。

运行过程的做用有如下几种可能:

  • 向 Docker Registry 获取镜像
  • 经过 graphdriver 执行容器镜像的本地化操做
  • 经过 networkdriver 执行容器网络环境的配置
  • 经过 execdriver 执行容器内部运行的执行工做

因为 Docker Daemon 和 Docker Client 的启动都是经过可执行文件 docker 来完成的,所以二者的启动流程很是类似。 Docker 可执行文件运行时,运行代码经过不一样的命令行 flag 参数,区分二者,并最终运行二者各自相应的部分。

启动 Docker Daemon 时,通常可使用如下命令来完成

docker --daemon = true docker d docker d = true

再由 docker 的 main() 函数来解析以上命令的相应 flag 参数,并最终完成 Docker Daemon 的启动。

下图能够很直观地看到 Docker Daemon 的启动流程:

默认配置下, Docker daemon 只能响应来自本地 Host 的客户端请求。若是要容许远程客户端请求,须要在配置文件中打开 TCP 监听。咱们能够照着以下步骤进行配置:

一、编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service ,在环境变量 ExecStart 后面添加 -H tcp://0.0.0.0,容许来自任意 IP 的客户端链接。

二、重启 Docker daemon

systemctl daemon-reload systemctl restart docker.service

三、咱们经过如下命令便可实现与远程服务器通讯

docker -H 服务器IP地址 info

-H 是用来指定服务器主机, info 子命令用于查看 Docker 服务器的信息

Docker Image

Docker 镜像能够看做是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建以后也不会被改变。咱们可将 Docker 镜像当作只读模板,经过它能够建立 Docker 容器。

镜像有多种生成方法:

  1. 从无到有开始建立镜像
  2. 下载并使用别人建立好的现成的镜像
  3. 在现有镜像上建立新的镜像

咱们能够将镜像的内容和建立步骤描述在一个文本文件中,这个文件被称做 Dockerfile ,经过执行 docker build <docker-file> 命令能够构建出 Docker 镜像,在后续的教程中,咱们会用一篇专门讨论这个问题。

Docker Registry

Docker registry 是存储 docker image 的仓库,它在 docker 生态环境中的位置以下图所示:

运行docker pushdocker pulldocker search时,其实是经过 docker daemon 与 docker registry 通讯。

Docker Container

Docker 容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。 Docker Container 提供了系统硬件环境,咱们可使用 Docker Images 这些制做好的系统盘,再加上咱们所编写好的项目代码, run 一下就能够提供服务啦。

Docker组件是如何协做运行容器

看到这里,我相信各位读者朋友们应该已经对Docker基础架构已经熟悉的差很少了,咱们还记得运行的第一个容器吗?如今咱们再经过hello-world这个例子来体会一下 Docker 各个组件是如何协做的。

容器启动过程以下:

  • Docker 客户端执行 docker run 命令
  • Docker daemon 发现本地没有 hello-world 镜像
  • daemon 从 Docker Hub 下载镜像
  • 下载完成,镜像 hello-world 被保存到本地
  • Docker daemon 启动容器

具体过程能够看以下这幅演示图:

咱们能够经过docker images 能够查看到 hello-world 已经下载到本地

咱们能够经过docker ps 或者 docker container ls 显示正在运行的容器,咱们能够看到, hello-world 在输出提示信息之后就会中止运行,容器自动终止,因此咱们在查看的时候没有发现有容器在运行。

咱们把 Docker 容器的工做流程剖析的十分清楚了,咱们大致能够知道 Docker 组件协做运行容器能够分为如下几个过程:

  1. Docker 客户端执行 docker run 命令
  2. Docker daemon 发现本地没有咱们须要的镜像
  3. daemon 从 Docker Hub 下载镜像
  4. 下载完成后,镜像被保存到本地
  5. Docker daemon 启动容器

了解了这些过程之后,咱们再来理解这些命令就不会以为很突兀了,下面我来给你们讲讲 Docker 经常使用的一些命令操做吧。

Docker经常使用命令

咱们能够经过 docker -h 去查看命令的详细的帮助文档。在这里我只会讲一些日常平常比赛或者生活中咱们可能会用的比较多的一些命令。

例如,咱们须要拉取一个 docker 镜像,咱们能够用以下命令:

docker pull image_name

image_name 为镜像的名称,而若是咱们想从 Docker Hub 上去下载某个镜像,咱们可使用如下命令:

docker pull centos:latest

centos:lastest 是镜像的名称, Docker daemon 发现本地没有咱们须要的镜像,会自动去 Docker Hub 上去下载镜像,下载完成后,该镜像被默认保存到 /var/lib/docker 目录下。

接着咱们若是想查看下主机下存在多少镜像,咱们能够用以下命令:

docker images

咱们要想知道当前有哪些容器在运行,咱们能够用以下命令:

docker ps -a

-a 是查看当前全部的容器,包括未运行的

咱们该如何去对一个容器进行启动,重启和中止呢?咱们能够用以下命令:

docker start container_name/container_id docker restart container_name/container_id docker stop container_name/container_id

这个时候咱们若是想进入到这个容器中,咱们可使用 attach 命令:

docker attach container_name/container_id

那若是咱们想运行这个容器中的镜像的话,而且调用镜像里面的 bash ,咱们可使用以下命令:

docker run -t -i container_name/container_id /bin/bash

那若是这个时候,咱们想删除指定镜像的话,因为 image 被某个 container 引用(拿来运行),若是不将这个引用的 container 销毁(删除),那 image 确定是不能被删除。咱们首先得先去中止这个容器:

docker ps docker stop container_name/container_id

而后咱们用以下命令去删除这个容器:

docker rm container_name/container_id

而后这个时候咱们再去删除这个镜像:

docker rmi image_name

此时,经常使用的 Docker 相关的命令就讲到这里为止了,咱们在后续的文章中还会反复地提到这些命令。

Dockerfile是什么

前面咱们已经提到了 Docker 的一些基本概念。以 CTF 选手的角度来看,咱们能够去使用 Dockerfile 定义镜像,依赖镜像来运行容器,能够去模拟出一个真实的漏洞场景。所以毫无疑问的说, Dockerfile 是镜像和容器的关键,而且 Dockerfile 还能够很轻易的去定义镜像内容,说了这么多,那么 Dockerfile 究竟是个什么东西呢?

Dockerfile 是自动构建 docker 镜像的配置文件, 用户可使用 Dockerfile 快速建立自定义的镜像。Dockerfile 中的命令很是相似于 linux 下的 shell 命令。

咱们能够经过下面这幅图来直观地感觉下 Docker 镜像、容器和 Dockerfile 三者之间的关系。

咱们从上图中能够看到, Dockerfile 能够自定义镜像,经过 Docker 命令去运行镜像,从而达到启动容器的目的。

Dockerfile 是由一行行命令语句组成,而且支持已 # 开头的注释行。

通常来讲,咱们能够将 Dockerfile 分为四个部分:

  • 基础镜像(父镜像)信息指令 FROM
  • 维护者信息指令 MAINTAINER
  • 镜像操做指令 RUN 、 EVN 、 ADD 和 WORKDIR 等
  • 容器启动指令 CMD 、 ENTRYPOINT 和 USER 等

下面是一段简单的Dockerfile的例子:

FROM python:2.7 MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> COPY . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["app.py"]

咱们能够分析一下上面这个过程:

  • 一、从 Docker Hub 上 pull 下 python 2.7 的基础镜像
  • 二、显示维护者的信息
  • 三、copy 当前目录到容器中的 /app 目录下 复制本地主机的 <src> ( Dockerfile 所在目录的相对路径)到容器里 <dest>
  • 四、指定工做路径为 /app
  • 五、安装依赖包
  • 六、暴露 5000 端口
  • 七、启动 app

这个例子是启动一个 python flask app 的 Dockerfile ( flask 是 python 的一个轻量的 web 框架),相信你们从这个例子中可以稍微理解了Dockfile的组成以及指令的编写过程。

Dockerfile经常使用的指令

根据上面的例子,咱们已经差很少知道了Dockerfile的组成以及指令的编写过程,咱们再来理解一下这些经常使用命令就会驾轻就熟了。

因为 Dockerfile 中全部的命令都是如下格式:INSTRUCTION argument ,指令 (INSTRUCTION) 不分大小写,可是推荐大写,和sql语句是否是很类似呢?下面咱们正式来说解一下这些指令集吧。

FROM

FROM 是用于指定基础的 images ,通常格式为 FROM <image> or FORM <image>:<tag> ,全部的 Dockerfile 都用该以 FROM 开头,FROM 命令指明 Dockerfile 所建立的镜像文件以什么镜像为基础,FROM 之后的全部指令都会在 FROM 的基础上进行建立镜像。能够在同一个 Dockerfile 中屡次使用 FROM 命令用于建立多个镜像。好比咱们要指定 python 2.7 的基础镜像,咱们能够像以下写法同样:

FROM python:2.7

MAINTAINER

MAINTAINER 是用于指定镜像建立者和联系方式,通常格式为 MAINTAINER <name> 。这里我设置成个人 ID 和邮箱:

MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>

COPY

COPY 是用于复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest>

当使用本地目录为源目录时,推荐使用 COPY 。通常格式为 COPY <src><dest> 。例如咱们要拷贝当前目录到容器中的 /app 目录下,咱们能够这样操做:

COPY . /app

WORKDIR

WORKDIR 用于配合 RUNCMDENTRYPOINT 命令设置当前工做路径。能够设置屡次,若是是相对路径,则相对前一个 WORKDIR 命令。默认路径为/。通常格式为 WORKDIR /path/to/work/dir 。例如咱们设置/app 路径,咱们能够进行以下操做:

WORKDIR /app

RUN

RUN 用于容器内部执行命令。每一个 RUN 命令至关于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。通常格式为 RUN <command> 。例如咱们要安装 python 依赖包,咱们作法以下:

RUN pip install -r requirements.txt

EXPOSE

EXPOSE 命令用来指定对外开放的端口。通常格式为 EXPOSE <port> [<port>...]

例如上面那个例子,开放5000端口:

EXPOSE 5000

ENTRYPOINT

ENTRYPOINT 可让你的容器表现得像一个可执行程序同样。一个 Dockerfile 中只能有一个 ENTRYPOINT,若是有多个,则最后一个生效。

ENTRYPOINT 命令也有两种格式:

  • ENTRYPOINT ["executable", "param1", "param2"] :推荐使用的 exec形式
  • ENTRYPOINT command param1 param2 :shell 形式

例以下面这个,咱们要将 python 镜像变成可执行的程序,咱们能够这样去作:

ENTRYPOINT ["python"]

CMD

CMD 命令用于启动容器时默认执行的命令,CMD 命令能够包含可执行文件,也能够不包含可执行文件。不包含可执行文件的状况下就要用 ENTRYPOINT 指定一个,而后 CMD 命令的参数就会做为ENTRYPOINT的参数。

CMD 命令有三种格式:

  • CMD ["executable","param1","param2"]:推荐使用的 exec 形式。
  • CMD ["param1","param2"]:无可执行程序形式
  • CMD command param1 param2:shell 形式。

一个 Dockerfile 中只能有一个CMD,若是有多个,则最后一个生效。而 CMD 的 shell 形式默认调用 /bin/sh -c 执行命令。

CMD 命令会被 Docker 命令行传入的参数覆盖:docker run busybox /bin/echo Hello Docker 会把 CMD 里的命令覆盖。

例如咱们要启动 /app ,咱们能够用以下命令实现:

CMD ["app.py"]

固然还有一些其余的命令,咱们在用到的时候再去一一讲解一下。

构建Dockerfile

咱们大致已经把Dockerfile的写法讲述完毕,咱们能够本身动手写一个例子:

mkdir static_web cd static_web touch Dockerfile 而后 vi Dockerfile 开始编辑该文件 输入 i 开始编辑 如下是咱们构建的Dockerfile内容 `````````` FROM nginx MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html `````````` 编辑完后  esc 退出编辑 而后 :wq 写入 退出

咱们在 Dockerfile 文件所在目录执行:

docker build -t angelkitty/nginx_web:v1 .

咱们解释一下, -t 是为新镜像设置仓库和名称,其中 angelkitty 为仓库名, nginx_web 为镜像名, :v1 为标签(不添加为默认 latest )

咱们构建完成以后,使用 docker images 命令查看全部镜像,若是存在 REPOSITORY 为 nginx 和 TAG 是 v1 的信息,就表示构建成功。

接下来使用 docker run 命令来启动容器

docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1

这条命令会用 nginx 镜像启动一个容器,命名为 nginx_web ,而且映射了 8080 端口,这样咱们能够用浏览器去访问这个 nginx 服务器:http://localhost:8080/ 或者 http://本机的IP地址:8080/,页面返回信息:

hello-docker

这样一个简单使用 Dockerfile 构建镜像,运行容器的示例就完成了!

参考文献


做  者:Angel_Kitty 
出  处:https://www.cnblogs.com/ECJTUACM-873284962/ 
关于做者:阿里云ACE,目前主要研究方向是Web安全漏洞以及反序列化。若有问题或建议,请多多赐教! 
版权声明:本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接。 
特此声明:全部评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 
声援博主:若是您以为文章对您有帮助,能够点击文章右下角推荐】一下。您的鼓励是做者坚持原创和持续写做的最大动力! 

欢迎你们关注个人微信公众号IT老实人(IThonest),若是您以为文章对您有很大的帮助,您能够考虑赏博主一杯咖啡以资鼓励,您的确定将是我最大的动力。thx.

公众号

微信打赏

支付宝打赏

 
 
 
 
 
« 上一篇: 我终于开通了微信公众号
相关文章
相关标签/搜索