容器化技术笔记

前言

现在的团队必须快速发布应用,以吸引和留住客户。 由于存在这种要求,软件开发和支持团队必须始终考虑可节省时间和成本的解决方案。 理想的解决方案将减少创建和配置部署环境所花费的时间,并简化软件部署过程。

普遍认为可以将软件容器化技术用作节省时间和降低成本的解决方案。 容器化的一项优势是,无需配置硬件和花费时间安装操作系统和软件来托管部署。 容器之间彼此隔离,并且多个容器可以在相同硬件上运行。 此配置可帮助我们更加高效地使用硬件,并且可以帮助提升应用程序的安全性。

假设你就职于一家在线零售公司,你们公司计划开发一些内部应用。 你的团队在本地开发和测试所有应用程序,然后将其部署到服务器进行预生产测试和最终生产托管。 你希望在进行很少配置更改或不进行任何配置更改的情况下在每个环境中实现最大兼容性。 使用 Docker 作为容器化解决方案似乎是理想的选择。

什么是容器?

就像运输行业使用物理容器来隔离不同的货物,以便通过轮船和火车运输,软件开发技术也越来越多地使用一种称为容器化的方法。

容器是一种松散隔离的环境,可用于生成和运行软件包。 这些软件包包括在任何计算环境中快速可靠地运行应用程序所需的代码和所有依赖项。 我们将这些包称为容器映像。

容器映像是我们用于分发应用程序的单位。

容器为应用程序提供标准化、可移植的打包。

标准软件包(也称为容器)将应用程序的代码与相关配置文件、库以及运行应用所需的依赖项捆绑在一起。这使得开发人员和 IT 专业人员能够跨环境无缝部署应用程序。

什么是软件容器化?

软件容器化是一种操作系统虚拟化方法,用于在不使用虚拟机 (VM) 的情况下部署和运行容器。 容器可在物理硬件上、云和 VM 中运行,还可以在多个操作系统上运行。

为什么要使用容器?

应用程序移动到其他环境就无法正确运行,这个问题从有软件开发就存在了。会出现这种问题,通常是由于各环境的配置基础库要求和其他依赖项存在差异。

容器为应用程序打包和部署提供轻量级、不可变的基础结构来解决此问题。应用程序或服务、其依赖项及其配置打包为容器映像。容器化应用程序可以作为一个单元进行测试,并作为容器映像实例部署到主机操作系统。

这样,开发人员和 IT 专业人员利用容器,只需进行少量修改,甚至不需要进行任何修改,即可跨环境部署应用程序。

容器与虚拟机

人们考虑虚拟化时,通常会想到虚拟机 (VM)。事实上,虚拟化可以采用多种形式,容器就是其中之一。那么,VM 和容器之间的区别是什么?

大体说来,VM 虚拟化基础硬件,让多个操作系统 (OS) 实例可以在相同的硬件上运行。每个 VM 运行一个 OS,并有权访问表示基础硬件的虚拟化资源。

VM 有许多好处。其中包括,能够在同一服务器上运行不同操作系统,还可以更高效、更经济地利用物理资源,更快完成服务器配置。另一方面,每个 VM 都包含 OS 映像、库、应用程序等,因此可能会变得相当大。

容器虚拟化基础 OS,并使容器化应用能够感知其本身具备 OS,包括 CPU、内存、文件存储和网络连接。由于对基础 OS 和基础结构的差异进行了抽象,因此只要基本映像一致,就可以在任何地方部署并运行容器。对于开发人员来说,这有很大的吸引力。

由于容器共享主机 OS,因此它们不需要启动 OS 或加载库。这使得容器更加高效和轻量。容器化应用程序可以在几秒钟内启动,与 VM 方案相比,应用程序的更多实例可以适应计算机。共享 OS 方法具有额外的好处,即减少维护(如修补和更新)开销。

尽管容器是可移植的,但它们被限制于为其定义的操作系统。例如,适用于 Linux 的容器无法在 Windows 上运行,反之亦然。

为什么选择容器?

灵活
开发人员生成应用程序并将其打包到容器中,将其提供给 IT 以在标准化平台上运行时,这将减少部署应用程序的总体工作量,并可以简化整个开发和测试周期。这还可以促进开发和运营团队协作,并提升其工作效率,以加快应用交付。

可移植性
容器提供打包和保存运行所需应用程序的所有必要组件的标准化格式。这解决了“它能否在我的计算机上正常工作”这一典型问题,实现 OS 平台和云之间的移植。在任何位置部署容器时,它都会在一致的环境中执行,该环境在多次部署中保持不变。现在,你拥有一致的格式,从开发框到生产。

可快速伸缩
由于容器没有 VM 的典型开销(包括单独的 OS 实例),因此同一基础结构上可以支持更多容器。容器的轻量特性意味着可以快速启动和停止它们,从而实现快速伸缩的方案。

什么是 Docker?

Docker 是一个用于开发、交付和运行容器的容器化平台。 Docker 不使用虚拟机监控程序,如果要开发和测试应用程序,可以在台式机或笔记本电脑上运行 Docker。 桌面版 Docker 支持 Linux、Windows 和 macOS。 对于生产系统,Docker 适用于服务器环境,包括 Linux 的多种变体和 Microsoft Windows Server 2016 及更高版本。 许多云(包括 Azure)都支持 Docker。

Docker 体系结构

Docker 平台包含多个用于生成、运行和管理容器化应用程序的组件。

Docker 引擎

Docker 引擎包含配置为客户端-服务器实现的多个组件,其中,客户端和服务器在同一主机上同时运行。 客户端使用 REST API 与服务器通信,该 API 还让客户端能够与远程服务器实例通信。在这里插入图片描述

Docker 客户端

Docker 客户端是一个名为 docker 的命令行应用程序,它为我们提供了一个命令行接口 (CLI),用于与 Docker 服务器进行交互。 docker 命令使用 Docker REST API 将指令发送到本地或远程服务器,并作为用于管理容器的主要接口。

Docker 服务器

Docker 服务器是一个名为 dockerd 的守护程序。 dockerd 守护程序通过 Docker REST API 响应来自客户端的请求,并且可以与其他守护程序进行交互。 此外,Docker 服务器还负责跟踪容器的生命周期。

Docker 对象

你将创建并配置多个对象以支持容器部署。 这些对象包括网络、存储卷、插件和其他服务对象。 我们不会在这里介绍所有这些对象,但请记住,我们可以根据需要创建和部署这些对象。

Docker Hub

Docker Hub 是一个软件即服务 (SaaS) Docker 容器注册表。 Docker 注册表是用于存储和分发创建的容器映像的存储库。 Docker Hub 是 Docker 用于映像管理的默认公共注册表。

请记住,可以创建和使用专用 Docker 注册表,也可以使用可用的多个云提供商选项之一。 例如,可以使用 Azure 容器注册表来存储容器映像,以便在多个启用了 Azure 容器的服务中使用。

Docker 映像的工作原理

回忆一下,我们说过,容器映像是用于分发应用程序的单位。 此外,我们还提到了容器采用开发者团队和运营团队使用的标准化格式。

在这里,我们将探讨在 Docker 中使用的软件、程序包和映像之间的差异。 了解这些概念之间的差异将帮助我们更好地理解 Docker 映像的工作原理。

我们还将简要介绍在主机上运行的操作系统以及在容器中运行的操作系统的角色。

打包到容器中的软件

打包到容器中的软件并不限于开发者生成的应用程序。 我们说的软件,是指在容器中运行的应用程序代码、系统包、二进制文件、库、配置文件和操作系统。

例如,假设我们要开发一个订单跟踪门户,供公司的各个专卖店使用。 我们需要全面地看待将运行 Web 应用的软件。 我们要生成的应用程序是一个 .NET Core MVC 应用,并且我们计划使用 Nginx 作为反向代理服务器在 Ubuntu Linux 上部署应用程序。 所有这些软件组件都属于容器映像。

什么是容器映像?

容器映像是一种包含软件的可移植程序包。 它在运行时便成为了我们的容器。 容器是映像的内存中实例。

容器映像是不可变的。 生成映像后,无法更改该映像。 更改映像的唯一方法是创建新映像。 此特性可保证在生产环境中使用的映像与在开发环境和 QA 环境中使用的相同。

什么是主机操作系统?

主机操作系统是 Docker 引擎运行于的操作系统。 在 Linux 上运行的 Docker 容器共享主机操作系统内核,只要二进制文件可以直接访问操作系统内核,便无需容器操作系统。在这里插入图片描述
但是,Windows 容器需要容器操作系统。 容器依靠操作系统内核来管理服务,例如文件系统、网络管理、进程调度和内存管理。

什么是容器操作系统?

容器操作系统是已打包映像包含的操作系统。 我们可以灵活地在容器中包含不同版本的 Linux 或 Windows 操作系统。 这种灵活性使我们能够访问特定操作系统功能或安装应用程序可能使用的其他软件。在这里插入图片描述

容器操作系统独立于主机操作系统,我们要在这一环境中部署和运行应用程序。 结合映像的不可变性,这种隔离意味着应用程序开发环境和生产环境相同。

在我们的示例中,我们使用 Ubuntu Linux 作为容器操作系统,并且此操作系统不会因开发或生产而改变。 我们所使用的映像始终是同一映像。

什么是可堆叠的统一文件系统 (Unionfs)?

Unionfs 用于创建 Docker 映像。 Unionfs 是一种文件系统,允许以看似合并内容的方式堆叠多个目录(称为分支)。 但是,内容在物理上是保持分开的。 Unionfs 允许在生成文件系统时添加和删除分支。在这里插入图片描述
例如,假设我们要为之前的 Web 应用生成一个映像。 我们将 Ubuntu 发行版作为基础映像叠加到引导文件系统之上。 接下来,我们将安装 Nginx 和 Web 应用。 我们有效地将 Nginx 和 Web 应用叠加到原始 Ubuntu 映像之上。

在通过映像运行容器后,将创建最终的可写层。 但是,当容器被销毁时,此层将不复存在。

什么是基础映像?

基础映像是使用 Docker scratch 映像的映像。 scratch 映像是一种空容器映像,不会创建文件系统层。 此映像假设要运行的应用程序可以直接使用主机操作系统内核。

什么是父级映像?

父级映像是用于创建映像的容器映像。

例如,我们将使用已基于 Ubuntu 的映像,而不是从 scratch 创建映像再安装 Ubuntu。 我们甚至可以使用已安装 Nginx 的映像。 父级映像通常包含一个容器操作系统。

基础映像与父级映像之间的主要区别是什么?

这两种映像类型都可用于创建可重复使用的映像。 但是,基础映像使我们能够更好地控制最终映像的内容。 回想一下前面的内容,映像是不可变的,只能对映像进行添加操作而不能进行删减操作。

什么是 Dockerfile?

Dockerfile 是一种文本文件,其中包含用于生成和运行 Docker 映像的说明。 已定义映像的以下方面:

用于创建新映像的基础映像或父级映像
用于更新基础操作系统和安装其他软件的命令
要包含的生成项目,例如开发的应用程序
要公开的服务,例如存储和网络配置
要在启动容器时运行的命令

让我们将这些方面一一对应到示例 Dockerfile。 假设我们要为 ASP.NET Core 网站创建 Docker 映像。 Dockerfile 可能与以下示例类似。

# Step 1: Specify the parent image for the new image
FROM ubuntu:18.04

# Step 2: Update OS packages and install additional software
RUN apt -y update &&  apt install -y wget nginx software-properties-common apt-transport-https \
    && wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
    && dpkg -i packages-microsoft-prod.deb \
    && add-apt-repository universe \
    && apt -y update \
    && apt install -y dotnet-sdk-3.0

# Step 3: Configure Nginx environment
CMD service nginx start

# Step 4: Configure Nginx environment
COPY ./default /etc/nginx/sites-available/default

# STEP 5: Configure work directory
WORKDIR /app

# STEP 6: Copy website code to container
COPY ./website/. .

# STEP 7: Configure network requirements
EXPOSE 80:8080

# STEP 8: Define the entry point of the process that runs in the container
ENTRYPOINT ["dotnet", "website.dll"]

我们不会在此介绍 Dockerfile 文件规范,也不会详细解释以上示例中的每个命令。 但是,请注意,此文件中有多个命令可用于操纵映像的结构。

回忆一下,我们之前提到过,Docker 映像使用 unionfs。 在生成最终的容器映像时,这些步骤中的每一步都会创建一个缓存的容器映像。 这些临时映像会叠加在上一步生成的映像之上,并在所有步骤完成后显示为单个映像。

最后,请注意最后一个步骤,即步骤 8。 文件中的 ENTRYPOINT 表示从映像运行容器后将执行的进程。

如何管理 Docker 映像

Docker 映像是最初存储在电脑上的大型文件,需要使用工具来管理这些文件。

可通过 Docker CLI 来管理映像,包括生成、列出、删除和运行映像。 我们使用 docker 客户端来管理 Docker 映像。 客户端不直接执行命令,它会将所有查询发送到 dockerd 守护程序。

我们不会在这里介绍所有客户端命令和命令标志,但将介绍一些常用命令。 本模块的“了解详细信息”部分包括 Docker 文档的链接,其中详细介绍了所有命令和命令标志。

如何生成映像

我们使用 docker build 命令生成 Docker 映像。 假设我们使用之前的 Dockerfile 定义来生成映像。 以下示例演示了 build 命令。

docker build -t temp-ubuntu .

由 build 命令生成的输出如下:

Sending build context to Docker daemon  4.69MB
Step 1/8 : FROM ubuntu:18.04
 ---> a2a15febcdf3
Step 2/8 : RUN apt -y update && apt install -y wget nginx software-properties-common apt-transport-https && wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && dpkg -i packages-microsoft-prod.deb && add-apt-repository universe && apt -y update && apt install -y dotnet-sdk-3.0
 ---> Using cache
 ---> feb452bac55a
Step 3/8 : CMD service nginx start
 ---> Using cache
 ---> ce3fd40bd13c
Step 4/8 : COPY ./default /etc/nginx/sites-available/default
 ---> 97ff0c042b03
Step 5/8 : WORKDIR /app
 ---> Running in 883f8dc5dcce
Removing intermediate container 883f8dc5dcce
 ---> 6e36758d40b1
Step 6/8 : COPY ./website/. .
 ---> bfe84cc406a4
Step 7/8 : EXPOSE 80:8080
 ---> Running in b611a87425f2
Removing intermediate container b611a87425f2
 ---> 209b54a9567f
Step 8/8 : ENTRYPOINT ["dotnet", "website.dll"]
 ---> Running in ea2efbc6c375
Removing intermediate container ea2efbc6c375
 ---> f982892ea056
Successfully built f982892ea056
Successfully tagged temp-ubuntu:latest

如果不理解以上输出,请不要担心。 但是,请注意输出中列出的步骤。 执行每个步骤时,都会向正在生成的映像添加一个新层。

另请注意,我们将执行多个命令以安装软件和管理配置。 例如,在步骤 2 中,我们将运行 apt -y update 和 apt install -y 命令来更新操作系统。 这些命令在为该步骤创建的正在运行的容器中执行。 命令运行后,将删除中间容器。 基础缓存映像保存在生成主机上,并且不会自动删除。 此优化可确保以后的生成可重复使用这些映像来缩短生成时间。

什么是映像标记?

映像标记是用于对映像进行版本设置的文本字符串。

在之前的示例生成中,请注意最后一个生成消息,该消息显示“已成功标记 temp-ubuntu: latest”。 生成映像时,我们使用 -t 命令标志来命名和标记(可选)映像。 在我们的示例中,我们使用 -t temp-ubuntu 命名映像,而生成的映像名称标记为 temp-ubuntu: latest。 如果未指定标记,将向映像应用 latest 标记。

单个映像可以分配有多个标记。 按照约定,最新版本的映像分配有 latest 标记以及描述其映像版本号的标记。 当发布新版本的映像时,可以重新分配 latest 标记以引用新映像。

以下是另一个示例。 假设要使用 .NET Core 示例 Docker 映像。 在这里,有四个平台版本可供选择:

mcr.microsoft.com/dotnet/core/samples:dotnetapp

mcr.microsoft.com/dotnet/core/samples:aspnetapp

mcr.microsoft.com/dotnet/core/samples:wcfservice

mcr.microsoft.com/dotnet/core/samples:wcfclient

如何列出映像

Docker 软件会在计算机上自动配置本地映像注册表。 可以使用 docker images 命令查看此注册表中的映像。

docker images

输出如以下示例所示。

REPOSITORY          TAG                     IMAGE ID            CREATED                     SIZE
tmp-ubuntu          latest             f89469694960        14 minutes ago         1.69GB
tmp-ubuntu          version-1.0        f89469694960        14 minutes ago         1.69GB
ubuntu              18.04                   a2a15febcdf3        5 weeks ago            64.2MB

请注意如何使用“名称”、“标记”以及“映像 ID”列出映像。 回忆一下,我们可以向一个映像应用多个标签。 下面就是这样一个示例。 虽然映像名称不同,但我们可以看到 ID 是相同的。

当映像的名称或标记可能有歧义时,映像 ID 是用于标识和管理映像的有用方法。

如何删除映像

可以使用 docker rmi 命令从本地 docker 注册表中删除映像。 指定要删除的映像的名称或 ID。 此示例使用映像名称删除示例 Web 应用的映像:

docker rmi temp-ubuntu:version-1.0

如果容器仍在使用某一映像,则不能删除该映像。 docker rmi 命令返回一条错误消息,其中列出了依赖于映像的容器。

我们已探讨了 Docker 映像的基础知识、如何管理这些映像以及如何从映像运行容器。 接下来,我们将介绍如何管理容器。

Docker 容器的工作原理

回想一下,你发现容器是用于分发应用的单位。 你还了解到容器采用开发者团队和运营团队使用的标准化格式。

在示例中,你要开发一个订单跟踪门户,供公司的各个专卖店使用。 生成 Docker 映像后,现在由运营团队负责订单跟踪门户的部署、更新推出和管理。

在之前的单元中,你了解了如何生成 Docker 映像。 在这里,你将简单了解下 Docker 容器的生命周期以及如何管理容器。 你还将了解如何考虑为容器配置数据存储和网络选项。

如何管理 Docker 容器

Docker 容器具有可用于管理和跟踪容器状态的生命周期。
在这里插入图片描述
若要将容器置于运行状态,请使用 run 命令。 还可重启已在运行的容器。 重启容器时,容器将收到一个 termination 信号,以允许任何正在运行的进程在容器的内核终止之前正常关闭。

容器在暂停、停止或终止之前将被视为处于运行状态。 但是,容器也可能会自行退出运行状态。 当正在运行的进程完成或者进程进入错误状态时,容器可自行退出。

若要暂停正在运行的容器,请使用 pause 命令。 此命令会暂停容器中的所有进程。

若要停止正在运行的容器,请使用 stop 命令。 Stop 命令通过向正在运行的进程发送 termination 信号来正常关闭该进程。 进程关闭后,容器的内核将终止。

如果需要终止容器,请使用 kill 命令发送 kill 信号。 正在运行的进程不会捕获 kill 信号,而仅捕获容器的内核。 此命令将强制终止容器中正在运行的进程。

最后,若要删除处于停止状态的容器,请使用 remove 命令。 删除容器后,将销毁存储在容器中的所有数据。

如何查看可用容器

若要列出正在运行的容器,请使用 docker ps 命令。 若要查看处于所有状态的所有容器,请传递 -a 参数。

示例如下。

docker ps -a

该命令的输出如下所示。

CONTAINER ID    IMAGE        COMMAND         CREATED       STATUS           PORTS        NAMES
d93d40cc1ce9    tmp-ubuntu:latest  "dotnet website.dll …"  6 seconds ago    Up 5 seconds        8080/tcp      happy_wilbur
33a6cf71f7c1    tmp-ubuntu:latest  "dotnet website.dll …"  2 hours ago     Exited (0) 9 seconds ago            adoring_borg

需要查看以上输出中的以下三个项:

“IMAGE”列中列出的映像名称。 在本例中,该名称为 tmp-ubuntu: latest。 请注意,你可以从同一映像创建多个容器。 此功能是一种强大的管理功能,用于在解决方案中实现缩放。

“STATUS”列中列出的容器状态。 在本例中,一个容器正在运行,一个容器已退出。 容器的状态通常是容器运行状况的第一个指标。

“NAMES”列中列出的容器名称。 除了第一列中的容器 ID 之外,容器还将接收名称。 在本例中,由于你没有为每个容器显式提供名称,因此,Docker 为容器提供了随机名称。 若要使用 --name 标志为容器提供显式名称,请使用 run 命令。

为什么要为容器命名?

借助此功能,可运行同一映像的多个容器实例。 容器名称是唯一的,这意味着,如果指定了某一名称,则不能重复使用该名称来创建新的容器。 重复使用特定名称的唯一方法是删除之前的容器。

如何运行容器

若要启动容器,请运行 docker run 命令。 只需按名称或 ID 指定要运行的映像,即可从映像启动容器。 通过此方式启动的容器提供交互式体验。

此处,若要在网站处于后台的情况下运行容器,请添加 -d 标志。

docker run -d tmp-ubuntu

在此示例中,该命令仅返回新容器的 ID。

指定要运行的映像后,Docker 将查找该映像,从该映像加载容器,并执行指定为入口点的命令。 此时,容器可供管理。

如何暂停容器

若要暂停容器,请运行 docker pause 命令。 下面是一个示例。

docker pause happy_wilbur

暂停容器将暂停所有进程。 通过此命令,容器可在后续阶段继续执行进程。 docker unpause 命令将取消挂起指定容器中的所有进程。

如何重启容器

若要重启容器,请运行 docker restart 命令。 下面是一个示例。

docker restart happy_wilbur

容器会收到 stop 命令,然后是 start 命令。 如果容器未响应 stop 命令,将发送 kill 信号。

如何停止容器

若要停止正在运行的容器,请运行 docker stop 命令。 下面是一个示例。

docker stop happy_wilbur

stop 命令会将 termination 信号发送到容器和容器中正在运行的进程。

如何删除容器

若要删除容器,请运行 docker rm 命令。 示例如下。

docker rm happy_wilbur

删除容器后,将销毁容器中的所有数据。 考虑存储数据时,始终将容器视为临时容器非常重要。

Docker 容器存储配置

如前文所述,如果容器中的应用需要存储数据,则始终将容器视为临时容器。

假设我们的跟踪门户在应用根的子文件夹(即直接到容器的文件系统)中创建了一个日志文件。 当应用将数据写入日志文件时,系统会将数据写入可写容器层。

虽然此方法很有效,但遗憾的是,它存在一些缺点。

容器存储是临时的

日志文件不会在容器实例之间存留。 例如,假设你停止并删除容器。 当你启动新容器实例时,新实例将基于指定的映像,而以前的所有数据将丢失。 请记住,删除容器时,将随容器销毁容器中的所有数据。

容器存储与底层主机耦合

容器与底层主机耦合时,很难从容器访问或移动日志文件。 必须连接到容器实例来访问该文件。

容器存储驱动程序性能较低

容器实现存储驱动程序,以允许应用写入数据。 此驱动程序引入额外抽象来与主机操作系统内核通信,比直接写入主机文件系统的性能要低。

容器可以使用两种选项来保持数据。 第一种选项是使用卷,第二种选项则是绑定装载。

什么是卷?

卷存储在主机文件系统上的特定文件夹位置。 选择一个文件夹,确保其中的数据只能由 Docker 进程修改。

Docker 通过运行 docker volume create 命令创建和管理新卷。 此命令可以构成 Dockerfile 定义的一部分,这意味着你可以在容器创建过程中创建卷。 如果在第一次尝试将卷装载到容器中时,该卷不存在,则 Docker 将创建该卷。

卷存储在主机文件系统上的目录中。 Docker 将装载并管理容器中的卷。 装载后,这些卷将与主机隔离。

多个容器可以同时使用相同的卷。 当容器停止使用卷时,不会自动删除这些卷。

在本例中,你可以在容器主机上创建一个目录,并在创建跟踪门户容器时将此卷装载到容器中。 当跟踪门户记录数据时,你可以通过容器主机的文件系统访问此信息。 即使删除了容器,你仍可以访问此日志文件。

什么是绑定装载?

绑定装载在概念上与卷相同,但是,你可以在主机上装载任何文件或文件夹,而不是使用特定文件夹。 你还希望主机可以更改这些装载的内容。 与卷一样,如果你要装载的绑定不存在于主机上,系统将创建该绑定装载。

与卷相比,绑定装载的功能有限,虽然性能更高,但仍依赖于具主机上的特定文件夹结构。

卷是公认的用于容器的首选数据存储策略。

Docker 容器网络配置

默认 Docker 网络配置允许在 Docker 主机上隔离容器。 借助此功能,可以生成和配置可彼此安全通信的应用。

Docker 提供了三种预配置的网络配置:

桥接
主机
无

根据容器的网络要求选择要向其应用的网络配置。

什么是桥接网络?

启动容器而未指定任何其他网络配置时,默认应用桥接网络配置。 此网络是容器使用的内部专用网络,它将容器网络与 Docker 主机网络隔离。

桥接网络中的每个容器都分配有一个 IP 地址和子网掩码,主机名默认为容器名称。 允许连接到默认桥接网络的容器按 IP 地址访问其他通过桥接网络连接的容器。 桥接网络不允许使用主机名在容器之间进行通信。

默认情况下,Docker 不会发布任何容器端口。 若要在容器端口和 Docker 主机端口之间启用端口映射,请使用 Docker 端口 --publish 标志。

publish 标志可有效配置映射端口的防火墙规则。

在本例中,浏览到端口 80 的客户端可以访问你的跟踪门户。 必须将端口 80 从容器映射到主机上的可用端口。 你在主机上打开了端口 8080,因此可设置如下标志。

--publish 8080:80

任何浏览到 Docker 主机 IP 和端口 8080 的客户端都可以访问跟踪门户。

什么是主机网络?

通过主机网络,你可以直接在主机网络上运行容器。 此配置在网络级别有效地消除了主机与容器之间的隔离。

在本例中,假设你决定将网络配置更改为主机网络选项。 仍可使用主机 IP 访问跟踪门户。 现在,可以使用已知端口 80,而不是映射的端口。

请记住,容器只能使用主机尚未使用的端口。

什么是“无”网络?

若要禁止容器使用网络,请使用“无”网络选项。

操作系统注意事项

请记住,各桌面操作系统上的 Docker 网络配置选项存在差异。 例如,使用桥接网络时,Docker0 网络接口在 macOS 上不可用;Windows 和 macOS 桌面版均不支持使用主机网络配置。

这些差异可能会影响开发者配置用于管理容器开发的工作流。

何时使用 Docker 容器

我们已经看到,Docker 提供了几项功能供我们使用。 在这里,我们将探讨 Docker 向开发和运营团队提供的好处。 此外,我们还将介绍 Docker 可能并非最佳选择的一些场景。

这些方面将帮助确定 Docker 是否适合你的容器化策略。

回忆一下,之前我们讲到过,我们的团队在开发和发布订单跟踪门户时遇到了许多挑战。 他们正寻求一种解决方案,以便:

轻松管理托管环境
保证连续交付软件
确保高效使用服务器硬件
允许实现应用程序可移植性

Docker 便是应对这些挑战的解决方案。 让我们来看一下目前所介绍的所有优点。

Docker 的优点

使用 Docker 时,可以立即获得容器化所提供的好处。

硬件的高效使用

容器可在不使用虚拟机 (VM) 的情况下运行。 正如我们所见,容器依靠主机内核来实现文件系统、网络管理、进程调度和内存管理等功能。在这里插入图片描述
与 VM 相比,我们发现,VM 需要安装操作系统来为 VM 中正在运行的应用程序提供内核功能。 请记住,VM 操作系统还需要磁盘空间、内存和 CPU 时间。 通过消除 VM 和附加的操作系统要求,可以释放主机上的资源,并将其用于运行其他容器。

容器隔离

Docker 容器提供了安全功能,可在同一主机上同时运行多个容器,而不会相互影响。 正如我们所见,我们可以配置数据存储和网络配置,以便隔离容器或在特定容器之间共享数据和连接。

让我们将此功能与使用 VM 进行比较。在这里插入图片描述
假设我们有一个运行两个 VM 的物理主机。 我们有三个需要彼此独立运行的应用程序。 我们决定将第一个应用部署到 VM 1,将第二个应用部署到 VM 2,以便将这两个应用彼此隔开。 如果我们现在选择安装第三个应用程序,则需要安装另一个 VM 以沿用此模式。

应用程序可移植性

容器几乎可在任何地方运行,包括桌面、物理服务器、VM 和云中。 利用此运行时兼容性,可以轻松在不同环境之间移动容器化应用程序。

由于容器是轻型的,因此它们不会像 VM 那样启动或关闭速度缓慢。 因此,可以顺利且快速地重新部署和使用其他部署方案,如扩展或缩减。

应用程序交付

借助 Docker,我们可以将容器用作分发应用程序的单位。 这一概念可确保我们具有开发者团队和运营团队使用的标准化容器格式。 开发者可以专注于开发软件,而运营团队可以专注于部署和管理软件。

在开发团队发布应用程序版本后,我们便可以在部署系统的每个步骤中使用容器。 容器非常适合用于持续集成,并且可以加快从生成到生产的时间。

托管环境的管理

我们在内部将应用程序的环境配置到容器。 由于这种包含关系,我们的运营团队可以更加密切地灵活管理应用程序的环境。 我们的团队可以监视操作系统更新,应用一次安全修补程序,并根据需要推出更新后的容器。

此外,我们的团队还可以在不影响其他容器的情况下管理要安装、更新和删除的应用程序。 每个容器都是隔离的,并且其资源限制的分配与其他容器是分开的。

云部署

Docker 容器是 Azure 容器化服务中使用的默认容器体系结构,在许多其他云平台上均受支持。

例如,可以将 Docker 容器部署到 Azure 容器实例、Azure 应用服务和 Azure Kubernetes 服务。 其中的每个选项都提供了不同的特性与功能。

例如,通过 Azure 容器实例,你可以专注于设计和生成应用程序,没有管理基础结构的开销。 当需要安排多个容器时,可以通过 Azure Kubernetes 服务轻松部署和管理大规模容器部署。

何时不使用 Docker 容器

正如我们所见,Docker 容器为我们提供了许多好处。 请记住,容器不一定能满足你的所有需求。 需要注意以下几个方面。

安全性和虚拟化

容器提供了一定程度的隔离。 但是,容器共享单个主机操作系统内核,也就是说共享单个攻击点。

此外,我们还需要考虑存储和网络等配置方面的问题,确保我们考虑到了所有安全性方面。 例如,默认情况下,所有容器都将使用桥接网络,并且可以通过 IP 地址相互访问。

并非所有应用程序都将受益于容器化。 在这些情况下,使用 VM 可能更理智。

服务监视

管理应用程序和容器比传统的 VM 部署更加复杂。 通过日志记录功能,我们可以了解正在运行的容器的状态。 但是,我们很难监视有关容器中服务的更详细的信息。

例如,Docker 为我们提供了 docker stats 命令。 此命令返回有关容器的信息,例如 CPU 使用百分比、内存使用百分比、写入磁盘的 I/O、发送和接收的网络数据以及分配的进程 ID。 此信息作为即时数据流很有用,但是,由于不会存储数据,因此不会进行聚合。 我们必须安装第三方软件,以便在一段时间内捕获有意义的数据。

最后

你要寻找这样一种容器化解决方案:只需很少配置或无需配置更改,即可在每个环境中提供最大兼容性。 我们发现,Docker 是一种不错的解决方案,它使我们能够创建应用程序及其所有依赖项的快照。 然后,我们在开发、测试和生产环境中部署这一快照。

提问

1

Docker Desktop 是一种用于构建和共享容器化应用和微服务的应用,可以在以下哪个操作系统上使用?

仅 macOS
Docker Desktop 可在 macOS 上运行,但它并非唯一受支持的桌面操作系统。

仅限 Linux
Docker Desktop 目前还不能用于 Linux 桌面操作系统。 不过,适用于 Windows 的 Docker Desktop 支持通过适用于 Linux 的 Windows 子系统使用 Linux 命令行。

Windows、macOS 和适用于 Linux 的 Windows 子系统 (WSL)
虽然 Docker Desktop 仅适用于 Windows 和 macOS,但它支持通过适用于 Linux 的 Windows 子系统 (WSL) 使用 Linux 命令行。 有关详细信息和设置,请参阅 WSL + Docker 文档。

答案
Windows、macOS 和适用于 Linux 的 Windows 子系统 (WSL)

2

以下哪一项是用于重新生成容器映像的正确 Docker 命令?

docker rebuild
Docker CLI 没有 rebuild 命令。

docker compile
Docker CLI 没有 compile 命令。

docker build
使用 docker build 命令重新生成容器映像。 生成映像后,无法更改该映像。 更改映像的唯一方法是创建新映像。

答案
docker build

3

以下哪一句是容器映像的最恰当描述?

容器映像是一种只读的可移植程序包,其中包含软件,并且可能包含一个操作系统。
容器映像是一种不可变的程序包,其中包含在容器中运行的所有应用程序代码、系统包、二进制文件、库、配置文件和操作系统。 在 Linux 上运行的 Docker 容器共享主机操作系统内核,只要二进制文件可以直接访问操作系统内核,便无需容器操作系统。

容器映像是用于生成容器的一组命令。
容器映像不包含用于生成容器的命令。

容器映像是一种包含软件的只读可移植程序包。
容器映像是一种不可变的程序包,其中包含在容器中运行的所有应用程序代码、系统包、二进制文件、库、配置文件和操作系统。

答案
容器映像是一种只读的可移植程序包,其中包含软件,并且可能包含一个操作系统。

4

使用 --publish 80:8080 标志启动容器。 以下哪个选项最有可能是为容器配置的网络?

无
“无”是禁止容器使用网络的网络配置。

桥接
“桥接”网络配置是容器使用的内部专用网络,它将容器网络与 Docker 主机网络隔离。 我们使用 publish 标志在容器和主机端口之间映射端口。

主机
“主机”网络配置允许容器使用主机的 IP 地址和端口。 此网络不使用 publish 标志。

答案
桥接

5

以下哪个存储选项是允许主机和容器共享文件以管理名称服务器解析(例如 Linux 上的 resolve.conf 文件)的最佳选择?

卷
卷存储在主机文件系统上的特定文件夹位置。 但是,卷数据不应由主机更新。

绑定装载
与卷一样,绑定装载也存储在主机文件系统上的特定文件夹位置。 但是,绑定装载数据应由主机更新。 resolve.conf 内容应随主机更改,并由容器和主机使用。

答案
绑定装载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值