关于容器您需要了解的一切,第三部分:使用 Kubernetes 进行编排
了解如何使用 Kubernetes 创建、部署和管理数千个容器镜像。
如果您已阅读本系列的前两篇文章,那么您现在应该熟悉 Linux 内核控制组(第一部分)、Linux 容器和 Docker(第二部分)。但是,这里快速回顾一下:曾经,数据中心管理员部署整个操作系统,占用整个硬件服务器来托管少量应用程序。这造成了大量的开销和管理工作。现在将这种情况扩展到多个服务器主机,维护变得越来越困难。这是一个问题——一个不容易解决的问题。技术发展需要时间才能达到能够缩小操作系统并将这些不同的应用程序作为微服务托管在同一物理机器上的多个容器中的时刻。
在本系列的最后一部分中,我将探讨大多数人用来创建、部署和管理容器的方法。这个概念通常被称为容器编排。如果我只关注 Docker 本身,这项技术非常易于使用,同时运行几个镜像也很容易。现在,将其扩展到数百个,甚至数千个镜像。您如何管理?最终,您需要退后一步,依靠专门为解决这个问题而设计的少数编排框架之一。 Kubernetes 就是其中之一。
KubernetesKubernetes,或 k8s(k + 八个字符),最初由 Google 开发。它是一个旨在自动化容器操作的开源平台:“跨主机集群的应用容器的部署、扩展和操作”。 Google 是 Linux 容器技术的早期采用者和贡献者(事实上,Linux 容器为 Google 自己的云服务提供支持)。 Kubernetes 消除了容器化应用程序部署和扩展中涉及的所有手动流程。它能够将托管 Linux 容器的服务器组集群在一起,同时还允许管理员轻松高效地管理这些集群。
Kubernetes 使您能够及时部署应用程序,轻松扩展这些应用程序,并无缝推出新功能,所有这些都在限制硬件资源消耗的同时快速响应消费者需求。它非常模块化,可以轻松地与其他应用程序或框架连接。它还提供额外的自我修复服务,包括容器的自动放置、自动复制和自动重启。
Docker 也有自己的平台,名为 Swarm。它完成了许多相同的任务,并拥有许多相同的功能。两者之间的主要区别在于 Swarm 以 Docker 的使用为中心,而 Kubernetes 倾向于采用更通用的容器支持模型。
有时,生产应用程序将跨越多个容器,而这些容器可能部署在多个物理服务器机器上。 Kubernetes 和 Swarm 都为您提供部署和扩展这些容器以适应不断变化的工作负载需求所需的编排和管理能力。
架构Kubernetes 运行在操作系统(例如 Ubuntu Server、Red Hat Enterprise Linux、SUSE Linux Enterprise Server 等)之上,并采用主从方法来实现其功能。主节点表示控制 Kubernetes 节点的机器(物理或虚拟)。所有任务都源于此。它是集群的主要控制单元,并将接收管理员或 DevOps 团队发出的命令,然后将它们转发到底层节点。主节点可以配置为在单台机器上或跨多台机器在高可用性集群中运行。这是为了确保集群的容错能力并降低停机的可能性。节点是执行主节点分配的任务的机器。节点有时被称为工作节点或 Minion。

图 1. Kubernetes Web UI 仪表板(来源:kubernetes.io)
Kubernetes 被分解为一组组件,其中一些组件管理单个节点,而其余组件是控制平面的一部分。
控制平面管理
- etcd:是一个轻量级且分布式的集群管理器。它是持久性的,可靠地存储集群的配置数据,在任何给定时间点提供集群的一致且准确的表示。
- API 服务器:使用 JSON over HTTP 提供 Kubernetes API。它为 Kubernetes 提供内部和外部接口。服务器处理和验证 RESTful 请求,并实现多个工具和库之间以及跨多个工具和库的通信。
- 调度器:选择未调度的 pod 应在哪个节点上运行。此逻辑基于资源可用性。调度器还跟踪每个节点的资源利用率,确保分配的工作负载永远不会超过物理或虚拟机上的可用资源。
- 控制器管理器:托管 DaemonSet 和复制控制器的进程。控制器与 API 服务器通信以创建、更新或删除托管资源。
节点管理
- kubelet:负责每个节点的运行状态,并确保节点上的所有容器都处于健康状态。它处理 pod 内应用程序容器的启动和停止(请参阅下一节中它与 Docker 的不同之处),由控制平面中的管理器指示。
- kube-proxy:一个网络代理和负载均衡器。它负责将流量路由到适当的容器。
- cAdvisor:一个代理,用于监视和收集每个节点上每个容器的系统资源利用率和性能指标(例如 CPU、内存、文件和网络)。
控制器
控制器通过管理一组 pod 来驱动集群的状态。复制控制器通过在整个节点集群中运行给定 pod 的指定数量的副本来处理 pod 复制和扩展。它还可以在节点发生故障时处理替换 pod 的创建。DaemonSet 控制器负责在每个节点上精确运行一个 pod。作业控制器运行 pod 以完成(即,作为批处理作业的一部分)。
服务
在 Kubernetes 术语中,服务由一组协同工作的 pod 组成(单层或多层应用程序)。由于 Kubernetes 提供服务发现和请求路由(通过分配适当的静态网络参数),因此它可以确保所有服务请求都到达正确的 pod,无论它在集群中移动到哪里。某些移动可能是 pod 或节点故障的结果。最终,Kubernetes 的自我修复功能将使这些运行不正常的服务自动恢复到原始状态。
Pod
当 Kubernetes 主节点将一组或多个容器部署到单个节点时,它通过创建一个 pod 来完成此操作。 Pod 从容器中抽象出网络和存储,并且 pod 内的所有容器将共享相同的 IP 地址、主机名等,从而允许它在集群中移动而不会出现复杂情况。
kubelet 将监视每个 pod。如果它处于不良状态,它会将该 pod 重新部署到同一节点。除此之外,心跳消息传递机制将每隔几秒钟将节点状态中继到主节点。一旦主节点检测到节点故障,复制控制器会将现在受影响的 pod 启动到另一个健康节点上。
那么,Docker 如何融入这一切? Docker 仍然像它应该的那样运行。当 Kubernetes 主节点将 pod 调度到一个节点时,在该节点上运行的 kubelet 将指示 Docker 启动所需的容器。 kubelet 将继续监视这些容器,同时还为主节点收集信息。 Docker 仍然完全控制在节点上运行的容器,并且还将负责启动和停止它们。这里唯一的区别是,现在您有一个自动化系统向 Docker 发送这些请求,而不是系统管理员手动运行相同的任务。

图 2. Pod 创建/管理的一般模型
启动 Kubernetes 安装现代 Linux 发行版使 Kubernetes 主机的安装和配置变得非常简单。以下示例我使用 Ubuntu Server 16.04。注意:您需要大量的内存和存储才能正确运行此示例。
首先,安装 conjure-up
$ sudo snap install conjure-up --classic
conjure-up
是 Juju、MAAS 和 LXD 的一个简洁的包装器。它被宣传为启用大型复杂软件堆栈(包括 Kubernetes)的统包解决方案。 conjure-up
本质上处理利用先前命名技术的脚本集合。
接下来,安装 lxd
$ sudo snap install lxd
LXD 是 Canonical(Ubuntu)的本土容器技术。虽然 Docker 更侧重于部署应用程序,但 LXD 专注于部署 Linux 虚拟机。
为了满足在 localhost 上安装的所有要求,您需要至少创建一个 LXD 存储池
$ sudo /snap/bin/lxc storage create kube-test dir source=/mnt
Storage pool kube-test created
您可以使用以下命令查看新创建的池
$ sudo /snap/bin/lxc storage list
+-----------+-------------+--------+--------+---------+
| NAME | DESCRIPTION | DRIVER | SOURCE | USED BY |
+-----------+-------------+--------+--------+---------+
| kube-test | | dir | /mnt | 0 |
+-----------+-------------+--------+--------+---------+
您还需要创建一个网络桥接
$ /snap/bin/lxc network create lxdbr0 ipv4.address=auto
↪ipv4.nat=true ipv6.address=none ipv6.nat=false
Network lxdbr0 created
运行 conjure-up
$ conjure-up
您将看到一个菜单,您可以在其中选择 Canonical Kubernetes 发行版。

图 3. conjure-up
框架选择菜单
然后,系统将提示您选择将各种有用的附加软件包安装到您的 Kubernetes 部署中。
将显示更多选项,例如部署位置(例如,云或本地)。对于此示例,让我们安装并部署到 localhost,因此在以下菜单中,选择您先前创建的网络桥接 (lxdbr0
) 和存储池 (kube-test
)。在回答几个简单问题后,安装过程开始。整个过程将花费相当长的时间。
希望安装 Kubernetes 主要组件不会花费太长时间,但让我们假设到目前为止,一切都已完成。作为安装后过程的一部分,将安装 kubectl 客户端应用程序,然后主机系统将捕获 Kubernetes 集群状态。您将获得安装摘要。
一切完成后,运行以下 kubectl
命令
$ ~/kubectl cluster-info
您将看到集群运行组件的简短显示,包括指向各种仪表板和服务的地址。
云原生计算云原生计算,通常称为无服务器计算,不仅是数据中心最新的流行语,而且还提供了一种新的应用程序托管方式。这个想法挑战了传统的规范,并将更多权力放入应用程序本身,同时抽象化其下的所有内容。但在深入了解无服务器计算的细节之前,这里有一个云计算速成课程。
走向无服务器
云原生计算是一个相对较新的术语,用于描述部署和管理应用程序的更现代趋势。这个想法非常简单明了。每个应用程序或进程都打包到自己的容器中,然后动态地编排(即,调度和管理)在节点集群中。这种方法使应用程序脱离物理硬件和操作系统的依赖性,并进入到它们自己的自包含和沙盒环境中,该环境可以在数据中心内的任何位置透明且无缝地运行。云原生方法是关于分离应用程序交付的各个组件。
云中容器的演变
正如您所期望的那样,容器技术帮助加速了云的采用。想想看。您拥有这些持久的容器化应用程序镜像,它们可以在几秒钟内根据需要启动或关闭,并在多个节点或数据中心位置之间进行平衡,以实现最佳服务质量 (QoS)。即使是大型公共云提供商也使用相同的容器技术,并且出于相同的原因:快速应用程序部署。例如,Amazon、Microsoft 和 Google 都使用 Docker 提供其容器服务。并且正如它适用于更大的无服务器生态系统一样,托管在这些容器中的应用程序是无状态且事件触发的。这意味着第三方组件将管理对此应用程序的访问,因为它在需要和调用时才会被访问。
现在,当我想象真正的无服务器解决方案时,首先想到的就是亚马逊的 AWS Lambda。亚马逊通过 Lambda 将无服务器提升到一个新的水平,通过启动一个容器来托管您需要的应用程序,确保您的业务或服务的访问和可用性。在这种模式下,无需配置或管理物理或虚拟服务器。假设它处于稳定或生产状态,您只需部署您的代码,就完成了。使用 Lambda,您无需管理容器(进一步减少了您的开销)。您的代码只是部署在隔离的容器化环境中。这非常简单明了。 AWS Lambda 使最终用户定义的代码函数能够通过用户定义的 HTTPS 请求直接触发。 Lambda 与传统容器化部署的不同之处在于,亚马逊为开发人员提供了一个框架,用于上传其事件驱动的应用程序代码(用 Node.js、Python、Java 或 C# 编写)并在几毫秒内响应事件,例如网站点击。运行您大部分代码的所有库和依赖项都在容器内提供。 Lambda 自动扩展以支持您的应用程序的精确需求。
至于触发应用程序或代码处理程序的事件类型(标记为事件源),亚马逊使其可以根据网站访问或点击、到其 API 网关的 REST HTTP 请求、物联网 (IoT) 设备上的传感器读数,甚至是将照片上传到 S3 存储桶来触发。此 API 网关构成了连接 AWS Lambda 所有部分的桥梁。例如,开发人员可以编写一个处理程序来触发 HTTPS 请求事件。
假设您需要为您的代码启用一定程度的粒度。 Lambda 通过允许开发人员编写模块化处理程序来适应这一点。例如,您可以为每个 API 方法编写一个处理程序,并且每个处理程序都可以独立于其他处理程序进行调用、更新和更改。
Lambda 允许开发人员将所有必需的依赖项(即,库、本机二进制文件甚至外部 Web 服务)组合到您的函数中到一个包中,从而使处理程序可以自由地根据需要访问任何这些依赖项。
现在,这与 Amazon AWS Elastic Cloud Computing (EC2) 实例相比如何?好吧,简短的答案是它要简单得多,而所谓的简单得多,我的意思是配置或维护您的操作环境几乎没有开销。如果您需要更多超出您的环境范围之外的东西,需要访问完整的操作系统或容器,则可以启动 EC2 虚拟实例。 EC2 为用户提供了灵活性,可以自定义其虚拟机及其将托管的硬件和软件。如果您只需要托管一个函数或特殊用途的应用程序,那么 Lambda 就成为更好的选择。使用 Lambda,没有太多可自定义的内容——有时,少即是多。
云原生计算基金会
云原生计算基金会 (CNCF) 成立于 2015 年,旨在帮助标准化云服务托管中这些最新的范式转变——即,统一和定义云原生时代。虽然基金会的主要目标是成为托管云原生软件项目的最佳场所。该基金会是许多以云为中心的项目的所在地,包括 Kubernetes 编排框架。
为了帮助标准化这种新的计算趋势,该基金会将整个架构划分为一组子系统,每个子系统都有一组用于组件间通信的标准化 API。子系统包括编排、资源调度和分布式系统服务。
您可以通过访问基金会的官方网站来了解有关该基金会的更多信息。
总结Kubernetes 扩展了传统容器的管理范围,使您能够有效且高效地扩展以满足消费者需求。借助现代和主要的 Linux 发行版,部署 Kubernetes 集群就像运行脚本和回答几个问题一样简单。
当您进一步探索这项出色的技术时,请知道您并不孤单。有一些公司提供围绕 Kubernetes 的服务和解决方案。一家这样的公司是 Heptio,它由 Kubernetes 的联合创始人 Craig McLuckie 和 Joe Beda 创立。 Heptio 的产品和服务以开发人员和系统管理员为中心,简化和扩展了 Kubernetes 生态系统。
还需要维护同一生态系统中容器镜像的安全性和合规性。同样,当您扩展到数千个时,对此类事物的管理几乎是不可能的。这就是 Twistlock 等公司为您承担繁重工作的地方。 Twistlock 开发和分发同名产品,专注于 Docker 镜像安全性和合规性。它也可以从包括 Kubernetes 在内的编排平台操作和管理。
资源Kubernetes 主要网站是这里。
Linux Journal 上关于 Kubernetes 的进一步阅读