关注公众号:登峰大数据,阅读Kubernetes实战(第二版)(完整中文版),系统学习Kubernetes!

Kubernetes实战(第二版)----第2章 理解容器

本章包括:

  • 理解什么是容器

  • 容器和虚拟机之间的区别

  • 创建、运行并与Docker共享容器镜像

  • linux内核特性与容器

Kubernetes主要管理在容器中运行的应用程序——因此在开始研究Kubernetes之前,您需要对容器有一个很好的理解。本章解释了一个Kubernetes用户需要知道的Linux容器的基础知识。

2.1 容器简介

在第1章中提到,在相同操作系统中运行的不同微服务,需要不同的、潜在冲突的动态链接库版本,或者具有不同的环境需求。

当一个系统包含少量应用程序时,可以为每个应用程序分配一个专用的虚拟机,并在其自己的操作系统中运行每个应用程序。但是,随着微服务越来越小,数量开始增长,如果您想保持较低的硬件成本,并且不浪费资源,那么可能无法为每个微服务提供自己的VM。

这不仅仅是浪费硬件资源的问题——每个VM通常都需要单独配置和管理,这意味着运行更多的VM也会导致更高的人员需求,以及需要更好、通常更复杂的自动化系统。由于转向了微服务体系结构,其中系统由数百个已部署的应用程序实例组成,因此需要一种vm的替代方案。容器就是另一种选择。

2.1.1比较容器和虚拟机(vm)

大多数开发和运维团队现在更喜欢使用容器,而不是使用虚拟机来隔离单个微服务(通常是软件进程)的环境。它们允许您在同一台主机上运行多个服务,同时使它们彼此隔离。类似于vm,但是开销更少。

vm是运行具有多个系统进程的独立操作系统,而在容器中运行的进程在现有主机操作系统中运行。因为只有一个操作系统,所以不存在重复的系统进程。尽管所有应用程序进程都运行在相同的操作系统中,但它们的环境是隔离的。对于容器中的进程,这种隔离使得它看起来像是计算机上没有其他进程存在。在接下来的几节中,您将了解如何实现这一点,但首先让我们深入了解容器和虚拟机之间的差异。

比较容器和虚拟机的开销

与vm相比,容器要轻得多,因为它们不需要单独的资源池或任何额外的os级进程。虽然每个VM通常运行自己的一组系统进程,除了用户应用程序本身的进程所消耗的计算资源之外,还需要额外的计算资源,但容器不过是运行在现有主机OS中的一个孤立的进程,它只消耗应用程序所消耗的资源。他们几乎没有开销。

图2.1显示了两台裸机,其中一台运行两个虚拟机,另一台运行容器。后者有空间用于其他容器,因为它只运行一个操作系统,而前者运行三个操作系统--一个主机和两个来宾操作系统。

Kubernetes实战(第二版)----第2章 理解容器

图2.1 使用vm隔离应用程序组与使用容器隔离单个应用程序

由于VM的资源开销,经常将多个应用程序分组到一个VM中。无法为每个应用程序提供一个完整的VM。但是容器不会带来任何开销,这意味着您可以为每个应用程序创建一个单独的容器。实际上,永远不应该在同一个容器中运行多个应用程序,因为这将使管理容器中的进程更加复杂。此外,所有处理容器的现有软件,包括Kubernetes本身,都是在容器中只有一个应用程序的前提下设计的。

比较容器和虚拟机的启动时间

除了较低的运行时开销之外,容器启动应用程序的速度也更快,因为只需要启动应用程序进程本身。与启动新的虚拟机不同,不需要先启动其他系统进程。

比较容器和虚拟机的隔离性

您可能会同意容器在使用资源方面明显更好,但它也有一个缺点。在虚拟机中运行应用程序时,每个虚拟机运行自己的操作系统和内核。在这些VM之下是hypervisor(可能还有一个额外的操作系统),它将物理硬件资源分割成更小的虚拟资源集,每个VM中的操作系统都可以使用这些虚拟资源。如图2.2所示,在这些VM中运行的应用程序对VM中的来宾操作系统内核进行系统调用(sys-call),然后内核在虚拟CPU上执行的机器指令通过hypervisor被转发到主机的物理CPU。

Kubernetes实战(第二版)----第2章 理解容器

图2.2 应用程序在虚拟机和容器中运行时如何使用硬件

 

请注意

存在两种类型的管理程序hypervisors。类型1管理程序hypervisors不需要运行主机操作系统,而类型2管理程序hypervisors需要。

另一方面,容器都对主机操作系统中运行的单一内核进行系统调用。这个单一的内核是唯一在主机的CPU上执行指令的内核。CPU不需要像处理vm那样处理任何类型的虚拟化。

查看图2.3,查看在裸机上运行三个应用程序、在两个独立的虚拟机中运行它们或在三个容器中运行它们之间的区别。

Kubernetes实战(第二版)----第2章 理解容器

图2.3 在裸机、虚拟机和容器中运行的应用程序之间的差异

在第一种情况下,所有三个应用程序都使用同一个内核,而且根本没有隔离。在第二种情况下,应用程序A和B在同一个VM中运行,因此共享内核,而应用程序C完全与其他两个隔离,因为它使用自己的内核。它只与前两个共享硬件。

第三种情况是在容器中运行相同的三个应用程序。虽然它们都使用同一个内核,但它们彼此隔离,完全不知道其他内核的存在。隔离是由内核本身提供的。每个应用程序只看到物理硬件的一部分,并将自己视为操作系统中唯一运行的进程,尽管它们都在同一个操作系统中运行。

理解容器隔离的安全性含义

与容器相比,使用虚拟机的主要优点是它们提供了完全的隔离,因为每个虚拟机都有自己的Linux内核,而容器都使用相同的内核。这显然会带来安全风险。如果内核中有错误,一个容器中的应用程序可能使用它来读取其他容器中的应用程序的内存。如果应用程序运行在不同的vm中,因此只共享硬件,这种攻击的概率会低得多。当然,完全隔离只能通过在单独的物理机器上运行应用程序来实现。

此外,容器共享内存空间,而每个VM使用自己的内存块。因此,如果不限制容器可以使用的内存量,则可能导致其他容器耗尽内存或将其数据交换到磁盘。

注意:这在Kubernetes中不可能发生,因为它要求在所有节点上禁用交换

理解什么启用了容器,什么启用了虚拟机

虽然虚拟机是通过CPU中的虚拟化支持和主机上的虚拟化软件启用的,但容器是由Linux内核本身启用的。稍后使用容器技术时,将了解它们。为此,您需要安装Docker,所以让我们了解一下它是如何适应容器故事的。

2.1.2 Docker容器平台介绍

虽然容器技术已经存在了很长时间,但直到Docker的兴起才被广泛知晓。Docker是第一代容器系统,使用Docker可以方便地在不同的计算机之间移植。Docker简化了将应用程序及其所有库和其他依赖项(甚至整个OS文件系统)打包成一个简单、可移植的包的过程,该包可用于在任何运行Docker的计算机上部署应用程序。

容器、镜像和注册中心简介

Docker是一个打包、分发和运行应用程序的平台。如前所述,它允许您将应用程序与其整个环境打包。这可以是应用程序需要的几个动态链接库,或者是操作系统通常附带的所有文件。Docker允许您通过公共存储库将这个包分发到任何其他启用Docker的计算机上。

Kubernetes实战(第二版)----第2章 理解容器

图2.4 Docker的三个主要概念是镜像、注册中心和容器

图2.4显示了刚才描述的过程中出现的三个主要Docker概念。下面是它们各自的含义:

  • 镜像—容器镜像是将应用程序及其环境打包到其中的镜像。比如zip文件或tarball。它包含应用程序将使用的整个文件系统和其他元数据,例如执行映像时要运行的可执行文件的路径、应用程序监听的端口以及关于镜像的其他信息。

  • 注册中心——注册中心是容器镜像的存储库,支持不同的人和计算机之间的镜像交换。在构建镜像之后,您可以在同一台计算机上运行它,或者将镜像推(上传)到注册中心,然后将其拉(下载)到另一台计算机。某些注册中心是公开的,允许任何人从其中提取图像,而其他注册中心是私有的,只能由具有所需身份验证凭证的个人、组织或计算机访问。

  • 容器——容器从容器镜像实例化。运行中的容器是在主机操作系统中运行的正常进程,但是它的环境与主机的环境和其他进程的环境是隔离的。容器的文件系统来源于容器镜像,但是其他文件系统也可以挂载到容器中。容器通常受到资源限制,这意味着它只能访问和使用分配给它的CPU和内存等资源。

构建、分发和运行容器镜像

为了理解容器、镜像和注册中心如何相互关联,让我们看看如何构建容器镜像、通过注册中心分发它,并从镜像创建一个运行的容器。这三个过程如图2.5到2.7所示。

Kubernetes实战(第二版)----第2章 理解容器

图2.5 构建容器镜像

如图2.5所示,开发人员首先构建一个镜像,然后将其推入注册中心,如图2.6所示。现在,任何人都可以访问注册中心。

Kubernetes实战(第二版)----第2章 理解容器

图2.6上传容器镜像到注册中心

如下图所示,另一个人现在可以将镜像拉到任何其他运行Docker的计算机上并运行它。Docker基于镜像创建一个隔离的容器,并调用镜像中指定的可执行文件。

Kubernetes实战(第二版)----第2章 理解容器

图2.7 在不同的计算机上运行容器

在任何计算机上运行应用程序都是可行的,因为应用程序的环境与主机的环境是解耦的。

理解应用程序看到的环境

当您在容器中运行应用程序时,它会准确地看到您绑定到容器镜像中的文件系统内容,以及您挂载到容器中的任何其他文件系统。无论在您的笔记本电脑上还是在生产服务器上运行,即使生产服务器使用完全不同的Linux发行版,应用程序看到的文件都是相同的。应用程序通常不能访问主机操作系统中的文件,因此,如果服务器安装的库与您的开发计算机完全不同,也没有关系。

例如,如果您将应用程序与整个Red Hat Enterprise Linux (RHEL)操作系统的文件打包在一起,然后运行它,那么无论您是在基于红帽Linux的计算机上运行还是在基于debian的计算机上运行,应用程序都会认为它是在RHEL中运行的。主机上安装的Linux发行版与此无关。唯一重要的可能是内核版本和它所加载的内核模块。稍后我会解释原因。

这类似于创建VM映像,创建一个新的VM,在其中安装操作系统和应用程序,然后分发整个VM映像,以便其他人可以在不同的主机上运行它。Docker也实现了同样的效果,但是它没有使用VMs来实现应用程序隔离,而是使用Linux容器技术来实现(几乎)相同级别的隔离。

理解镜像层

与虚拟机镜像不同,虚拟机镜像是安装在VM中的操作系统所需的整个文件系统的大块,容器镜像由层组成,这些层通常要小得多。这些层可以在多个镜像之间共享和重用。这意味着,如果一个镜像的其他层已经作为包含相同层的另一个镜像的一部分下载到主机,那么只需要下载其中的某些层。

层使镜像分发非常有效,但也有助于减少镜像的存储空间占用。Docker每层只存储一次。正如您在图2.8中看到的,由包含相同层的两个镜像创建的两个容器使用相同的文件。

Kubernetes实战(第二版)----第2章 理解容器

图2.8 容器可以共享镜像层

(未完待续......)  欢迎关注公众号,及时获得最新翻译内容:

Kubernetes实战(第二版)----第2章 理解容器

相关文章: