KCNA 2:容器编排
1. 概述
在本章中,我们将了解容器编排的挑战和机遇,以及它对网络和存储有特殊要求的原因。
在开始讨论容器的编排之前,让我们先后退几步,了解什么是容器,以及是什么使它在构建和操作应用程序时如此有用。
2. 学习目标
在本章结束时,你应该能够:
解释什么是容器,以及它与虚拟机的区别。
描述容器编排的基本原理。
讨论容器网络和存储的挑战。
解释服务网格的好处。
3. 使用容器
应用程序开发的历史也是将这些应用程序打包为不同平台和操作系统的历史。 让我们以一个用流行的编程语言Python编写的简单web应用程序为例。要在服务器或本地机器上运行应用程序,系统通常需要满足以下特定要求:
安装和配置基本操作系统
安装核心Python包来运行程序
安装程序使用的Python扩展
为您的系统配置网络
连接到第三方系统,如数据库、缓存或存储。
虽然开发人员最了解自己的应用程序及其依赖关系,但通常是由系统管理员提供基础设施、安装所有依赖关系并配置应用程序运行的系统。这个过程非常容易出错,而且很难维护,因此服务器只用于单一目的配置,比如运行数据库或应用服务器,然后通过网络连接。
为了更有效地利用服务器硬件,可以使用虚拟机来模拟一个具有cpu、内存、存储、网络、操作系统和软件的完整服务器。这允许在同一硬件上运行多个隔离的服务器。
在广泛采用容器之前,服务器虚拟化是运行独立且易于处理的应用程序的最有效方式,但由于必须运行包括内核在内的整个操作系统,如果需要运行大量服务器,那么它总是会带来一些开销。
容器可以用来解决这两个问题,管理应用程序的依赖关系,并比旋转大量虚拟机更有效地运行。
4. 容器基础
与普遍的看法相反,容器技术比人们预期的要古老得多。现代容器技术的最早祖先之一是chroot
命令,它于1979年在Version 7 Unix中引入。chroot命令可用于将进程与根文件系统隔离开来,并基本上将文件从进程中“隐藏”起来,并模拟一个新的根目录。隔离环境是所谓的chroot监狱,在这种环境中,进程无法访问文件,但文件仍然存在于系统中。
可以在文件系统的不同位置创建Chroot目录
虽然chroot是一项相当古老的技术,但它仍然在一些流行的软件项目中使用。我们今天拥有的容器技术仍然体现了这一概念,但是是一个现代化的版本,并且有很多特性。 为了比chroot更能隔离进程,当前的Linux内核提供了像命名空间和cgroup这样的特性。 命名空间用于隔离各种资源,例如网络。可以使用网络名称空间提供网络接口和路由表的完整抽象。这允许进程拥有自己的IP地址。Linux Kernel 5.6目前提供了8个命名空间:
pid
-进程ID提供了一个具有自己的进程ID集的进程。net
- network允许进程拥有自己的网络堆栈,包括IP地址。MNT
- mount抽象文件系统视图并管理挂载点。Ipc
-进程间通信提供了命名共享内存段的分离。user
-为进程提供自己的一组用户id和组id。uts
- Unix时间共享允许进程拥有自己的主机名和域名。cgroup
-一个新的命名空间,允许进程拥有自己的一组Cgroup根目录。time
-最新的命名空间可以用来虚拟化系统的时钟。
cgroup被用来组织层次结构组中的进程,并为它们分配资源,如内存和CPU。当你想限制你的应用程序容器的内存,比方说4GB, cgroup被用来确保这些限制。 Docker于2013年推出,成为building and running containers的代名词。虽然Docker并没有发明用于运行容器的技术,但他们以一种智能的方式将现有的技术结合在一起,使容器对用户更加友好和方便。 乍一看,容器似乎与虚拟机非常相似,但是理解它们之间的差异是至关重要的。虽然虚拟机模拟一个完整的机器,包括操作系统和内核,但容器共享主机的内核,正如所述,它们只是独立的进程。 虚拟机会带来一些开销,比如启动时间、大小或运行操作系统的资源使用情况。另一方面,容器实际上是进程,就像您可以在机器上启动的浏览器一样,因此它们启动得更快,占用的空间也更小。
传统部署vs虚拟化部署vs容器部署 在许多情况下,这不是使用容器或虚拟机的问题,而是使用这两种技术来从容器的效率中获益,但仍然使用虚拟机的更大隔离带来的安全优势。
5. 运行容器
6. 构建镜像
Container Images 可以通过从一个名为Dockerfile
的构建文件中读取说明来构建映像。这些说明几乎与在服务器上安装应用程序时使用的说明相同。下面是一个Dockerfile的例子,它包含了一个Python脚本:
如果你已经在你的机器上安装了Docker,你可以用下面的命令来构建镜像:
使用-t my-python-image
参数可以为映像指定一个名称标记,使用-f Dockerfile
可以指定可以找到Dockerfile
的位置。这使开发人员能够管理应用程序的所有依赖项,并将其打包以便运行,而不是将该任务留给另一个人或团队。 要分发这些images,可以使用container registry。这只不过是一个你可以上传和下载图片的网络服务器。Docker有内置的推和拉命令:
7. 容器安全
8. 容器编排
在本地机器或单个服务器上运行几个容器是相当容易的,但是容器的使用方式带来了关于容器操作的新挑战。这个概念的高效率导致应用程序和服务变得越来越小,您会发现现代应用程序可以由许多容器组成。 拥有大量松散耦合、隔离和独立的小容器是所谓的微服务体系结构的基础。这些小容器是自包含的业务逻辑的小部分,它们是更大的应用程序的一部分。 如果必须管理和部署大量容器,那么很快就需要一个系统来帮助管理这些容器。需要解决的问题包括:
提供可以运行容器的虚拟机之类的计算资源
以一种有效的方式将容器调度到服务器
为容器分配CPU和内存等资源
管理容器的可用性,并在它们失败时更换它们
如果负载增加,缩放容器
提供网络将容器连接在一起
如果容器需要持久化数据,则提供存储。
容器编排系统提供了一种方法来构建多个服务器的集群,并在其上托管容器。大多数容器编排系统由两部分组成:负责管理容器的控制平面和实际托管容器的工作节点。 多年来,已经有几种系统可以用于编排,但大多数系统在今天已经不再重要,行业已经选择Kubernetes作为编排容器的标准系统。
9. 容器网络
微服务架构在很大程度上依赖于网络通信。与单片应用程序不同,微服务实现了一个接口,可以调用该接口来发出请求。例如,在电子商务应用程序中,您可以有一个响应产品列表的服务。 网络命名空间允许每个容器拥有自己唯一的IP地址,因此多个应用程序可以打开相同的网口;例如,您可以有多个容器化的web服务器,它们都开放端口8080。 为了使应用程序可以从主机系统外部访问,容器能够将容器中的一个端口映射到主机系统中的一个端口。 为了允许容器跨主机进行通信,我们可以使用overlay network
,将它们放在跨越主机系统的虚拟网络中。 这使得容器之间的通信非常容易,而系统管理员不需要在主机和容器之间配置复杂的网络和路由。 大多数覆盖网络还需要处理IP地址管理,如果手动实现,这将是大量的工作。在这种情况下,覆盖网络管理哪个容器获得哪个IP地址,以及流量如何流动以访问各个容器。
10. 服务发现 & DNS
在很长一段时间里,传统数据中心的服务器管理是可以管理的。许多系统管理员甚至记得他们必须使用的重要系统的所有IP地址。大量的服务器列表、它们的主机名、IP地址和用途——都是手动维护的——都是日常事务。 在容器编排平台中,事情要复杂得多:
成百上千个带有独立IP地址的容器
容器被部署在不同的主机、不同的数据中心甚至地理位置上
容器或服务需要DNS进行通信。使用IP地址几乎是不可能的
关于container的信息在删除时必须从系统中删除。
解决这个问题的方法还是自动化。所有信息都放在Service Registry中,而不是手工维护的服务器列表(在本例中是容器)。在网络中查找其他服务并请求关于它们的信息称为服务发现(Service Discovery)。
拥有服务API的现代DNS服务器可以用于在创建新服务时注册它们。这种方法非常简单,因为大多数组织已经拥有具有适当功能的DNS服务器。
11. 服务网格(Service Mesh)
12. 容器存储
13. 其它资源
13.1 容器的历史
13.2 Chroot
13.3 容器性能
13.4 如何构建容器映像的最佳实践
13.5 经典Dockerfile容器构建的替代方案
13.6 服务发现
13.7 容器网络
13.8 容器存储
13.9 容器与kubernetes安全
13.10 Docker Container Playground
最后更新于