Docker 入门三部曲

690 阅读8分钟

容器基础概念

Docker是供开发人员和系统管理员使用容器构建,运行和共享应用程序的平台。 使用容器部署应用程序称为容器化。 容器并不是新事物,但用于轻松部署应用程序的容器却是新事物。 容器化越来越受欢迎,因为容器是:

  • 灵活:即使最复杂的应用程序也可以容器化。
  • 轻量级:容器利用并共享了主机内核,在系统资源方面比虚拟机更加有效。
  • 可移植:您可以在本地构建,部署到云并在任何地方运行。
  • 松散耦合:容器是高度自给自足并封装的容器,使您可以在不破坏其他容器的情况下更换或升级它们。
  • 可扩展:您可以在数据中心内增加并自动分布容器副本。
  • 安全:容器对进程应用主动约束和隔离,而不需要用户进行任何配置。

镜像和容器

根本上讲,一个容器不过是一个正在运行的进程,并对其应用了一些附加的封装功能,以使其与主机和其他容器隔离 容器隔离的最重要方面之一是每个容器都与自己的专用文件系统进行交互。 该文件系统由Docker映像提供。 映像包括运行应用程序所需的一切-代码或二进制文件,运行时,依赖项以及所需的任何其他文件系统对象。

容器和虚拟机

容器在Linux上本地运行,并与其他容器共享主机的内核。 它运行一个独立进程,不占用任何其他可执行文件更多的内存,从而使其轻巧。

相比之下,虚拟机(VM)运行具有“虚拟机管理程序”对主机资源的虚拟访问权的成熟“来宾”操作系统。 通常,VM会产生大量开销,超出了应用程序逻辑所消耗的开销。

Docker

VM

设置Docker环境

Docker Desktop是适用于Mac或Windows环境的易于安装的应用程序,可让您在几分钟内开始编码和容器化。 Docker Desktop包含直接从您的机器构建,运行和共享容器化应用程序所需的一切。 具体环境可以去官网上下载相应的安装包

测试安装

$ docker --version

构建和运行镜像

通常,开发工作流程如下所示:

  • 1.首先创建Docker镜像,为应用程序的每个组件创建和测试单独的容器。
  • 2.将您的容器和支持基础结构组装成一个完整的应用程序
  • 3.测试,共享和部署完整的容器化应用程序。

在本教程的这个阶段,让我们关注这个工作流的第1步:创建镜像。记住,Docker镜像捕获我们的容器化进程将在其中运行的私有文件系统;我们需要创建一个包含应用程序所需运行内容的镜像。 让我们看一个实例:

git clone https://github.com/dockersamples/node-bulletin-board
cd node-bulletin-board/bulletin-board-app

node-bulletin-board项目是一个简单的公告板应用程序,使用Node.js编写。 在此示例中,假设您编写了此应用,现在正尝试对其进行容器化.

通过Dockerfile定义一个容器

在公告栏应用程序中查看名为Dockerfile的文件。Dockerfiles描述如何为容器装配专用文件系统,还可以包含一些元数据,这些元数据描述如何基于此映像运行容器。公告板上的应用程序Dockerfile是这样的:

FROM node:current-slim


WORKDIR /usr/src/app
COPY package.json .
RUN npm install

EXPOSE 8080
CMD [ "npm", "start" ]

COPY . .

编写Dockerfile是容器化应用程序的第一步。 您可以将这些Dockerfile命令视为有关如何构建映像的逐步指南。 此步骤采取以下步骤:

  • From先前存在的镜像node:current-slim开始.这是一个官方镜像, 这是一个官方镜像,由node.js供应商构建,并经过Docker验证,是一个高质量的图像,包含node.js长期支持(LTS)解释器和基本依赖。
  • 使用 WORKDIR指定所有的后续操作都是基于镜像文件系统中目录/usr/src/app,而不是主机文件系统。
  • COPY指令从你的主机的当前路径.拷贝 package.json 到镜像中。所以在这种情况下,镜像中文件的目录为/usr/src/app/package.json
  • RUN指令在镜像文件系统中运行命令npm install,该命令将读取package.json文件来决定你的应用程序的node依赖,并安装他们。
  • COPY指令从主机将应用的其余源代码复制到镜像文件系统中。

您会看到,这些步骤与在主机上设置和安装应用程序所采取的步骤几乎相同。 但是,将它们捕获为Dockerfile允许我们在可移植的隔离Docker映像内执行相同的操作。

上面的步骤构建了映像的文件系统,但是Dockerfile中还有其他行。

实例中CMD指令指定了镜像中的一些描述如何基于我们镜像运行容器的元数据。在这个例子中,就是说,此镜像旨在支持的容器化进程是npm start

EXPOSE 8080通知Docker该容器在运行时正在侦听端口8000。

上面您看到的是组织一个简单的Dockerfile的好方法。 总是以FROM命令开头,按照它的步骤构建专用文件系统,并以任何元数据规范作为结束。Dockerfile指令比上面看到的要多。 有关完整列表。请参阅Dockerfile参考

构建并测试镜像

现在我们已经有了一些源代码和一个Dockerfile,是时候构建我们的第一个映像了,并确保从其中启动的容器按预期工作。确保现在在node-bulletin-board/bulletin-board-app目录下。然后开始构建镜像 docker image build -t bulletinboard:1.0 . 您将看到Docker一步一步地遍历Dockerfile中的每个指令,在此过程中构建映像。如果成功,构建过程应该以一条消息结束Successfully tagged bulletinboard:1.0.

➜  bulletin-board-app git:(master) docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
bulletinboard       1.0                 13adcd31251b        40 seconds ago      152MB

基于镜像运行容器

docker container run --publish 8000:8080 --detach --name bb bulletinboard:1.0

我们在这里使用了几个常见的选项:

  • --publish要求Docker转发主机端口8000上传入的流量,到容器的端口8080(容器具有自己的专用端口集,因此,如果我们要从网络访问一个端口,则必须以这种方式将流量转发到该端口;否则,防火墙规则将阻止所有网络流量到达您的容器 ,作为默认的安全状态)。
  • --detach要求Docker在后台运行此容器。
  • --name让我们指定一个名称,在后续命令中可以使用该名称来引用我们的容器,实例中我们命名为bb.

另请注意,我们没有指定我们要运行容器的进程。 我们没有必要,因为在构建Dockerfile时使用了CMD指令; 因此,Docker知道在启动时会自动在容器内运行npm start进程。

在浏览器中的localhost:8000上访问您的应用程序。 您应该看到公告板应用程序已启动并正在运行。 在这一步,我们通常会竭尽所能,以确保我们的容器按预期的方式工作; 例如,现在是运行单元测试的时候了。

对电子公告板容器正常工作感到满意后,可以将其删除:

docker container rm --force bb

--force选项删除正在运行的容器。

本小结总结:

至此,我们已经成功构建了图像,对应用程序进行了简单的容器化,并确认我们的应用程序已在其容器中成功运行。 下一步将是在Docker Hub上共享您的映像,以便可以轻松下载它们并在任何目标计算机上运行它们。

在Docker Hub上共享镜像

1.如果你还没有docker hub 账号,首先登陆docker hub 注册一个

2.创建docker hub 仓库,然后push镜像

本小结总结

现在,您的映像已在Docker Hub上可用,您将可以在任何地方运行它。 如果您尝试在尚未安装的新机器上使用它,则Docker会自动尝试从Docker Hub下载。 通过以这种方式移动映像,您不再需要在要运行我们的软件的计算机上安装除Docker以外的任何依赖项。 容器化应用程序的依赖关系已完全封装并隔离在您的映像中,如上所述,我们可以使用Docker Hub进行共享。

需要记住的另一件事:目前,我们仅将您的映像推送到Docker Hub; 那你的Dockerfile呢? 一个关键的最佳实践是将它们保留在版本控制中,或者与应用程序的源代码一起保留。 您可以在Docker Hub存储库描述中添加链接或注释,以指示可以在何处找到这些文件,不仅保留有关图像构建方式以及作为完整应用程序运行的方式的记录。