Docker的用途是什么?面向初学者的Docker容器教程

2020年12月30日10:56:25 发表评论 32 次浏览

本文概述

作为开发人员, 你可能在职业生涯中的某个时候听说过Docker。你可能已经意识到, 它已成为任何应用程序开发人员都知道的重要技术。

如果你不知道我在说什么, 就不用担心–这就是本文的目的。

我们将继续探索每个人都在谈论这个Docker以及你可以使用它做什么。最后, 我们还将创建, 发布和运行我们的第一个Docker映像。

但是首先, 让我们为我们的故事打下基础。我会用这个很棒的文章拉尼·奥斯纳特(Rani Osnat)撰写的文章更深入地介绍了容器的整个历史。我将在这里进行总结, 以便我们专注于重要部分。

一点集装箱历史

Docker是容器运行时。许多人认为Docker是同类产品中的第一个, 但事实并非如此-Linux容器自1970年代就已经存在。

Docker对开发社区和容器社区都非常重要, 因为它使使用容器变得非常容易, 每个人都开始这样做。

什么是容器?

容器或Linux容器是一项技术, 它使我们能够隔离某些内核进程, 并诱使他们认为它们是在一台全新计算机上运行的唯一进程。

与虚拟机不同, 容器可以共享操作系统的内核, 同时只加载它们不同的二进制文件/库。

换句话说, 你不需要拥有完全不同的操作系统(称为来宾操作系统)安装在你的主机操作系统中。你可以在单个操作系统中运行多个容器, 而无需安装多个不同的来宾操作系统。

Docker的用途是什么?面向初学者的Docker容器教程1

虚拟机和Docker容器之间的区别(来源:Docker)

这使容器更小, 更快, 更高效。虚拟机启动可能需要一分钟左右的时间, 并且可能重达几千兆字节, 而一个容器平均重达400至600mb(最大)。

他们也只需要几秒钟就可以旋转起来。这主要是因为他们在运行进程之前不必旋转整个操作系统。

这一切都始于六个字符。

容器的开始

容器的历史始于1979年的Unix v7。那时, 我还没有出生, 父亲只有15岁。 1979年是否已有容器?没有!

1979年, Unix版本7引入了名为chroot, 这就是我们今天所知的开始处理 虚拟化.

的chroot调用允许内核更改进程及其子进程的明显根目录。

简而言之, 该进程认为它是在计算机中单独运行的, 因为其文件系统与所有其他进程是隔离的。 1982年, 在BSD中引入了相同的系统调用。但是仅在二十年后, 我们才首次广泛使用它。

2000年, 托管服务提供商正在寻找更好的方法来管理客户的网站, 因为它们都安装在同一台计算机上, 并且竞争着相同的资源。

这个解决方案叫做监狱, 这是在流程级别隔离事物的最早的真实尝试之一。 Jails允许任何FreeBSD用户将系统划分为几个独立的, 较小的系统(称为监狱)。每个监狱都可以有自己的IP配置和系统配置。

监狱是第一个扩大使用范围的解决方案chroot不仅允许在文件系统级别进行隔离, 而且还可以虚拟化用户, 网络, 子系统等。

2008年, LXC(大号犬X C演艺人员)。当时, 它是集装箱管理系统的第一个也是最完整的实施。它使用了控制组, 名称空间以及在此之前构建的许多内容。最大的进步是它是直接从Unix内核使用的, 不需要任何补丁。

码头工人

最终, 在2010年, Solomon Hykes和Sebastien Pahl在Y Combinator创业孵化器小组期间创建了Docker。该平台于2011年启动。

最初, Hykes在法国启动了Docker项目, 这是dotCloud内部项目的一部分, dotCloud是一家PaaS公司, 于2016年被关闭。

Docker当时并没有为容器运行时增加太多– Docker对容器生态系统的最大贡献是意识。它易于使用的CLI和概念将容器的使用推广到普通开发人员, 而不仅是出于某些原因需要容器的深层次黑客公司。

2013年之后, 几家公司开始采用Docker作为默认容器运行时, 因为它在全球范围内标准化了容器的使用。 2013年, 红帽宣布与Docker合作, 2014年是时候微软, AWS, Stratoscale和IBM。

2016年, 发布了适用于与Linux不同的操作系统的Docker的第一个版本。 Windocks发布了旨在在Windows上运行的Docker OSS项目的一部分。而且, 到同年年底, 微软宣布Docker现已获得本地支持视窗通过超V.

在2019年, 微软宣布了WSL2, 这使得Docker可以在Windows上运行而无需Hyper-V上的虚拟机。 Docker现在本机为多平台, 同时仍在利用Linux的容器方法。

最终, 在2020年, Docker成为全世界容器的选择。发生这种情况并不一定是因为它比其他方法更好, 而是因为它通过CLI和Daemon在一个易于使用的平台下统一了所有实现。它使用了将在下一部分中探讨的简单概念来完成所有这些工作。

Docker如何工作?

Docker将应用程序及其所有依赖项打包在可以在任何Linux服务器上运行的虚拟容器中。这就是为什么我们称它们为容器。因为它们具有包含在单个软件中的所有必要依赖项。

Docker由以下元素组成:

  • 守护程序, 用于构建, 运行和管理容器
  • 高级API, 允许用户与守护程序进行通信,
  • 还有一个CLI, 我们用来使所有这些都可用的界面。

Docker容器

容器是应用程序层的抽象。他们将所有代码, 库和依赖项打包在一起。这使得多个容器可以在同一主机中运行, 因此你可以更有效地使用该主机的资源。

每个容器在用户空间中作为一个独立的进程运行, 并且由于其分层体系结构, 因此它们比常规VM占用更少的空间。

这些层称为中间图像, 并且每次你在Docker文件例如, 如果你有一个像这样的Dockerfile:

FROM node:stable

COPY . /usr/src/app

WORKDIR /usr/src/app

RUN npm install grpc

RUN npm install

ENTRYPOINT ["npm", "start"]

在每个命令像复制or运行你将在容器图像的顶部创建另一个图层。这使Docker可以将每个命令拆分和分离为一个单独的部分。所以如果你最终使用这个节点:稳定再次安装该映像, 因为你已经安装了该映像, 所以它不需要拉所有的层。

此外, 所有层都被哈希化, 这意味着Docker可以缓存这些层并优化在整个构建中未更改的层的构建时间。如果COPY步骤未更改, 则无需重建和重新复制所有文件, 这大大减少了在构建过程中花费的时间。

在构建过程的最后, Docker在所有称为的层之上创建了一个新的空层。薄的可写层。该层是你使用时访问的层docker exec -it <容器> <命令>。这样, 你可以在图像中执行交互式更改, 并使用码头工人提交, 就像处理Git跟踪文件一样。

由于AuFS文件系统, 这种散列扩散层体系结构是可能的。这是分层的FS, 它允许文件和目录一层一层地堆叠在一起。

AuFS在处理DnD(Docker中的Docker)时会带来一些问题, 但这是其他文章的主题!你可以在中查看更深入的解释本文.

Docker的用途是什么?面向初学者的Docker容器教程2

层可以在版本之间进行哈希散列。这样, Docker可以在构建映像时检查图层是否已更改, 并决定是否重建它, 从而节省了大量时间。

因此, 如果你已经在计算机上下载了Ubuntu映像, 并且你正在构建依赖于该映像的一个或多个层的新映像, 则Docker将不会再次构建它们。它只会重复使用相同的层。

Docker的用途是什么?面向初学者的Docker容器教程3

(来源:Packt)Docker层解释

如果你想更深入地研究各层, 本文详细介绍了如何查找, 列出和管理它们。

为什么Docker容器很棒

你可能已经听过标志性的短语"它可以在我的机器上工作"。好吧, 为什么我们不把那台机器交给客户呢?

这正是Docker和容器通常解决的问题。 Docker容器是所有应用程序库和依赖项的打包集合, 这些库和依赖项已经预先构建并可以执行。

许多公司已经从VM迁移到了容器, 这不仅是因为它们更轻, 更快地启动, 而且还因为它们非常易于维护。

单个容器可以使用其版本控制Docker文件(我们将在下一节中获取图像), 因此对于一个开发人员(甚至是一小组开发人员)来说, 运行和维护整个容器生态系统非常容易。另一方面, 你将需要一名基础架构人员才能运行和维护VM。

Docker的用途是什么?面向初学者的Docker容器教程4

(来源:Docker)带有虚拟机和容器的数据中心

这是否意味着我们不再需要VM?不, 相反, 如果你想为每个客户拥有一个完整的操作系统, 或者只需要整个环境作为沙盒, 那么仍然非常需要VM。当你有一个大型服务器机架并需要使用多个客户时, VM通常用作中间层。

易用性和可维护性使我们进入了容器为何如此重要的另一个重要方面:与完全成熟的VM相比, 公司使用容器的成本更低。

这不是因为基础设施或硬件价格便宜, 而是因为你需要更少的人来保管容器, 这意味着你可以更好地组织团队将精力集中在产品上, 而不是集中在保管上。

仍然与节省有关, 单个中型VM可以运行大约3到8个容器。这取决于容器使用多少资源以及在运行整个应用程序之前需要引导多少底层操作系统。

某些语言(例如Go)允许你仅使用已编译的二进制文件构建映像, 而无需使用其他任何代码。这意味着Docker容器的负载将更少, 因此将使用更少的资源。这样, 你可以为每个VM启动更多容器, 并更有效地使用硬件。

由于容器是临时性的, 这意味着删除容器后, 其中的所有数据都会丢失。这很棒, 因为我们可以将容器用于诸如CI之类的易爆任务。

容器的使用带来了DevOps全新的进步。现在, 你可以简单地旋转许多容器, 每个容器只需要执行部署流程的一小步, 然后就可以杀死它们, 而不必担心是否遗留了任何东西。

容器的无状态性质使它们成为快速工作负载的理想工具。

既然我们已经了解了容器的出色表现, 那么让我们了解如何构建其中一个容器!

什么是Docker映像?

Docker映像是在称为a的特殊文件中编写的指令Docker文件。它具有自己的语法, 并定义了Docker将采取哪些步骤来构建你的容器。

由于容器只是变化的一层又一层, 因此你在Docker映像中创建的每个新命令都会在容器中创建一个新层。

最后一层是我们所说的薄的可写层。空层, 用户可以更改并使用码头工人提交命令。

这是Node.js应用程序的简单映像的示例:

FROM node:stable
COPY . /usr/src/app/
RUN npm install && npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "start"]

在这个简单的示例中, 我们将创建一个新图像。所有图片均基于现有图片或草稿图片(我在葡萄牙语中的博客文章中对此进行了解释, 这里, 这里和这里)。

这些图像是从集装箱登记处, 用于存储容器图像的存储库。其中最常见的是Docker中心, 但你也可以使用云解决方案(例如Azure容器注册表.

当你跑步码头工人建设。在与Dockerfile相同的目录中, Docker守护程序将开始构建映像并将其打包, 以便你可以使用它。那你就可以跑泊坞窗运行<image-name>开始一个新的容器。

请注意, 我们在Dockerfile中公开了某些端口。 Docker允许我们在自己的操作系统内分离网络, 这意味着你可以将端口从计算机映射到容器, 反之亦然。另外, 你可以在容器内部执行命令码头工人.

让我们将这些知识付诸实践。

如何部署Dockerized应用程序

这将是关于如何使用Node.js服务器创建基本Docker映像并使其在计算机上运行的简单轻松的演练。

首先, 在你选择的目录中启动一个新项目, 然后运行npm初始化-y创建一个新的package.json文件。现在让我们创建另一个目录src。在此目录中, 我们将创建一个名为server.js.

现在, 在你的package.json文件, 更改主要关键src / server.js。另外, 删除测试创建的脚本并将其替换为" start":"节点src / server.js"。你的文件应如下所示:

{
  "name": "your-project", "version": "1.0.0", "description": "", "main": "src/server.js", "scripts": {
    "start": "node src/server.js"
  }, "keywords": [], "author": "", "license": "ISC"
}

现在, 创建一个名为Docker文件(无扩展名)。让我们来写我们的形象!

FROM node:lts-alpine
COPY . /usr/src/app/
WORKDIR /usr/src/app
EXPOSE 8089
ENTRYPOINT ["npm", "start"]

让我们解释一下:

  1. 首先, 我们从Docker Hub获取节点映像。由于图像是通过名称保存的, 因此我们通过标签来区分图像。你可以检查所有标签这里.
  2. 接下来, 我们使用复制复制当前目录中的所有文件(使用.)到容器中的新目录/ usr / src / app。目录是自动创建的。这是必需的, 因为我们在那里需要所有的应用程序文件。
  3. 现在, 我们将开始目录更改为/ usr / src / app目录, 因此我们可以从应用程序的根目录运行内容。
  4. 我们暴露我们的港口,
  5. 我们说, 一旦容器运行, 我们将执行" npm start"。

让我们通过运行来构建图像码头工人建设。 -t简单节点图像。这样, 我们将标记图像并为其命名。

Docker的用途是什么?面向初学者的Docker容器教程5

你将看到它将创建和下载图像以及所有必要的图层。让我们使用以下命令运行该图像:

docker run -p 80:8089 simple-node-image

我们正在映射我们的港口80到港口8089在容器内。我们可以通过输入来检查码头工人ps像这样:

Docker的用途是什么?面向初学者的Docker容器教程6

现在尝试访问本地主机:80, 然后看看会发生什么:

Docker的用途是什么?面向初学者的Docker容器教程7

Docker的用途是什么?

既然我们已经了解了如何构建Docker容器, 那么让我们进入Docker的一些实际用途以及如何充分利用Docker。

临时数据库

你是否曾经尝试开发需要数据库才能运行的应用程序?或更糟糕的是, 尝试运行需要你未安装的数据库的其他人的应用程序吗?

旧的解决方案是先安装数据库, 然后运行应用程序。使用Docker, 你只需要运行数据库容器。让我们运行一个简单的MongoDB容器:

$ docker run -p 27017:27017 --name my-ephemeral-db mongo

而已!现在, 你可以像平常一样通过端口27017从计算机访问数据库。

永久数据库

上一个示例的问题在于, 如果删除容器, 则所有数据都将丢失。因此, 如果你要运行本地数据库而不需要安装它, 但是在删除后保留数据, 会发生什么呢?你可以将Docker绑定到一个卷上!

将Docker绑定到本地卷时, 实际上是在将文件系统安装到容器中, 反之亦然。让我们来看看:

$ docker run -p 27017:27017 -v /home/my/path/to/db:/data/db --name my-persistent-db mongo

在此命令中, 我们正在安装/数据/数据库进入/ home / my / path / to / db。现在, 如果我们使用泊坞窗停止my-persistent-db和docker rm my-persistent-db我们所有的数据将继续存储在此处。

稍后, 如果我们再次需要该数据库, 则可以使用同一命令安装该数据库, 并且所有数据都将返回。

一次性工具

所有开发人员要做的另一件事:我们安装仅使用一次的应用程序。例如, 该简单的CLI可以访问该旧数据库, 或者该简单的GUI可以访问某些CI服务器。

许多工具已经具有Docker容器, 你可以像这样使用它们, 因此你不必在笔记本中安装其他工具。

最好的例子是Redis。它具有redis-cli内置在另一个容器中, 因此你无需安装redis-cli如果你几乎不使用它, 可以在外壳中使用它。

假设你使用以下命令启动Redis实例docker run -d --name redis redis --bind 127.0.0.1绑定到本地主机接口。你可以使用以下方法通过另一个容器访问它:

$ docker run --rm -it --network container:redis redis-cli -h 127.0.0.1

的- R M标志告诉Docker它应该在容器停止后立即删除它, 而-它标志告诉它我们想要一个交互式会话(带有一个shell), 我们需要一个TTY。

运行整个堆栈

如果你需要测试依赖于另一个应用程序的应用程序, 你将如何做? Docker通过提供码头工人组成。这是你工具箱中的另一个工具, 可让你编写docker-compose.yml描述你的环境的文件。

该文件如下所示:

version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"

  redis:
    image: "redis:alpine"
    ports:
      - "6379:6379"

如你所见, 我们正在定义两种服务, 一种称为网路并运行码头工人在web.build路径。那是一个Docker文件.

之后, 它暴露端口5000在主机和容器中。另一个服务是Redis, 然后拉动并运行Redis图像在端口上6379.

最好的部分是网络层是共享的, 也就是说, 你可以访问Redis来自网路只需键入即可提供服务Redis和港口。

你可以通过简单的方式启动此文件码头工人组成, 并查看魔术的发生。

总结

而已!这就是Docker的历史, 它的发展历程以及它以3000字为单位的工作方式。我希望你喜欢它, 并希望这使你在Docker方面的进步变得容易一些。

如你所见, Docker的大多数用途是使开发人员在开发应用程序时更轻松。但是还有许多其他用途, 例如基础结构层和使你的应用程序的整理工作变得更加容易。

如果你想与我联系, 请在以下任何社交网络上对我进行ping操作:我的网站.

封面照乔治·沃尔夫on不飞溅

一盏木

发表评论

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