Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Kubernetes 基础知识

 

本章介绍 Kubernetes 架构中的 Kubernetes 以及基本 terminologies、主要概念以及大多数经常引用的组件。本章还提供了 Kubernetes 群集环境中的一些示例,展示有关基本 Kubernetes 对象的主要想法。

什么是 Kubernetes?

您可以在此处找到 Kubernetes 的官方定义(https://kubernetes.io/):

“Kubernetes (K8s)是一种开源系统,可实现容器化应用程序的自动化部署、扩展和管理。它将组成应用程序的容器组合为一个逻辑单元,以便于管理和发现。Kubernetes 构建在 Google 上运行生产工作负载的15年经验,再加上来自社区的一流想法和实践。”

以下是有关 Kubernetes 的重要信息:

  • 它’是 Google 发起的开源项目

  • 它’是一种成熟且稳定的产品

  • 它’是一种编排工具

  • 它’是一种处理更高级别的容器的平台

Kubernetes 由 Google a for 2014 中的一组工程师创建,设计和开发模型受 Google’s 内部系统、Borg 的影响。Kubernetes 定义了一组构建对象,共同提供的机制可基于系统资源(CPU、内存或其他自定义指标)编排分布式群集节点的容器化应用程序。Kubernetes 通过为所需功能提供 REST Api 来掩盖管理一组容器的复杂性。

简而言之,像 Docker 这样的容器技术为您提供了打包和分发容器化应用程序的功能,而编排系统(如 Kubernetes)允许您在相对较高的级别部署和管理容器还有一种更简单的方法。

Note

许多 Kubernetes 文档通常将技术缩写为 k8s (或 K-8 字符),而当前主要版本(本书籍的书写部分)为 v 1.14。

第1章指出 Docker 是一种有影响和成熟的容器技术,因此为什么需要 Kubernetes?从技术角度讲,Kubernetes 在相对较高的级别上工作,而不是 Dockers,因此这究竟意味着什么呢?

当您将 Kubernetes 与 Docker 进行比较时,有一个有益的类比是将 Python 与 C 语言进行比较。C 强大,足以构建几乎所有内容,包括一整套基本操作系统组件和 Api,但实际上您可能希望编写脚本来自动化工作负载中的任务,这意味着使用 Python 要比使用 C 更多。借助 Python,您只需考虑已有的模块已提供必要的功能,将其导入应用程序,然后快速集中精力完成所需的功能。您很少需要担心低级别系统 API 调用和硬件详细信息。

网络类比是 TCP/IP 互联网协议。开发类似 FTP 的文件传输工具时,自然希望基于 TCP 套接字而非原始套接字开始工作。通过将 TCP 套接字放在 TCP 协议的顶部,它提供了一个更加坚实的基础,具有所有内置可靠性功能,如错误检测、流和拥塞控制、重新传输等。您需要考虑的是如何从一端交付数据并在另一端上接收。使用原始套接字处理 IP 协议和更低层,因此在开始处理工具的文件传输功能之前,您必须考虑并实施所有可靠性功能。

因此,回到 Kubernetes。如果您希望跨多台机器运行多个容器,则当您直接与 Docker 交互时,您将有许多工作要做。以下任务至少应在您关心的事项列表中列出:

  • Loging 在不同的机器上,并在网络中生成容器

  • 通过添加或删除容器,在需求变化时向上或向下扩展

  • 使存储与应用程序的多个实例保持一致

  • 在不同节点中运行的容器之间分配负载

  • 在不同的机器上启动新容器(如果发生故障)

您会发现,通过 Docker 手动完成所有这些工作将会很困难。借助高层抽象以及在 Kubernetes API 中表示它们的对象,所有这些任务都变得更加简单。

Note

Kubernetes 不是其种类的唯一工具,Docker 具有自己的名为 Swarm 的编排工具。但这’是另一本书的讨论。这本书重点讨论 Kubernetes。

Kubernetes 架构和组件

Kubernetes 集群中有两种类型的节点,每一种都运行定义完善的一组流程:

  • 头节点:也称为主设备或主节点,它是执行所有思考并做出所有决策的头和大脑。所有智能都位于此处。

  • 辅助节点:又称为节点或 minion,这’是开展劳动力的手和脚。

节点由主设备控制,大多数情况下,您只需与主设备对话即可。

您与群集之间最常见的接口之一就是命令行工具 kubectl。它作为客户端应用程序安装在同一主节点或单独的计算机中,例如在 PC 中。无论是在哪里,它都可以通过主设备公开的 REST API 与主设备交谈。

在这本书后面,您可以看到一个使用 kubectl 创建 Kubernetes 对象的示例。但现在只需记住,无论您何时使用 kubectl 命令,您都将’与群集’的主设备进行通信。

Note

术语节点可能语义上不明确– ,这意味着这本书的上下文中有两个方面。通常,节点指的是集群中的逻辑单元,就像服务器,可以是物理或虚拟的。在 Kubernetes 群集的环境中,一个节点通常只是专用于一个辅助节点。

Note

您很少需要绕过主设备并使用节点,但您可以登录到节点并运行所有 Docker 命令以检查容器的运行状态。本章稍后将显示一个示例。

Kubernetes 主机

Kubernetes 主节点(即主设备)就是大脑。集群原件提供了控制平面,可做出所有有关群集的全球决策。例如,当您需要集群来生成容器时,主设备将决定调度任务的节点并生成新容器。此过程称为计划。

主服务器负责维护群集所需的状态。为此 web 服务器提供订单时,请确保始终有两个容器相互备份!主监视器将监控运行状态,并在由于任何故障而运行的任何时间少于两个 web 服务器容器时,会产生一个新容器。

在群集中,通常只需要一个主节点,但也可以复制主设备以获得更高的可用性和冗余。主要’功能由主节点中运行的进程集合来实施:

  • kube-apiserver可以:是控制平面的前端,提供 REST Api。

  • kube-scheduler可以:根据系统重新 quirements (CPU、内存、存储等)和其他自定义参数或约束(例如,关联规格),调度和决定放置容器的位置。

  • kube-controller-manager可以:控制大多数不同类型控制器的单个进程,可确保系统的状态正是其应有的。控制器示例可能是:

    • 复制控制器

    • ReplicaSet

    • 部署

    • 服务控制器

  • etcd可以:用于存储系统状态的数据库。

Note

为了简单起见,一些组件未列出(例如,云控制器管理器、DNS 服务器、kubelet)。它们不是微不足道或可忽略的组件,但现在跳过它们可以帮助我们实现 Kubernetes 基础知识。

Kubernetes 节点

集群中的 Kubernetes 节点是运行用户最终应用程序的机器。在生产环境中,一个集群中可能有数十个或数百个节点,具体取决于设计时的规模,因为它们在集群提供的环境中工作。通常所有容器和工作负载都在节点上运行。节点运行以下进程:

  • Kubelet 在主设备和所有节点上运行的 Kubernetes 代理进程。它与 master (通过 kube-apiserver 进程)交互,并管理本地主机中的容器。

  • Kube-代理:此进程在节点中使用 Linux iptable 实施 Kubernetes 服务(第3章中引入)。

  • 容器-运行时:或本地容器–多数在当今’的市场中 Docker,以容纳所有正在运行的 Dockerized 应用程序。

Note

术语代理可能听不到 Kubernetes 初学者的混乱,’因为它并不是当前 Kubernetes 架构中的一个代理。Kube-代理是操纵节点中的 Linux IP 表的系统,使机箱和节点之间的流量正确流动。

Kubernetes 工作流

到目前为止’,您已经阅读了每个主机和节点以及其中运行的主进程的相关信息。’现在,我来可视化各事物如何协同工作,如Figure 1所示。

Figure 1: Kubernetes 架构
Kubernetes 架构

Figure 1顶部,通过 kubectl命令时,您与 Kubernetes master 进行了通信,该主控形状管理右侧的两个节点框。Kubectl 通过其在系统中暴露给用户和其他进程的 REST API 与主进程 kube-apiserver 交互。

让’s 发送一些 kubectl 命令– ,如 kubectl create x,以生成新容器。您可以提供有关要生成的容器及其正在运行的行为的详细信息,并且这些规范可提供为 kubectl在配置文件中定义的命令行参数或选项和值(很快就会显示一个例子)。工作流将:

  1. Kubectl客户端将首先将 CLI 命令转换为一个以上的 REST API 调用,并将其发送至 kube-apiserver。

  2. 验证这些 REST API 调用之后,kube-apiserver 了解该任务并调用 kube-时间表进程,从可用的节点中选择一个可执行此项作业。这是计划过程。

  3. 一旦 kube-时间表返回目标节点,kube-apiserver 将使用描述该任务的所有详细信息调度该任务。

  4. 目标节点中的 kubelet 进程接收任务并与容器引擎进行交谈,例如Figure 1中的 Docker 引擎,以生成具有所有提供参数的容器。

  5. 此作业及其规格将记录在集中式数据库 etcd 中。其工作是保留和提供对群集中所有数据的访问。

Note

实际上,主设备也可以是功能全面的节点,并像节点一样携带箱工作。因此,节点中现有的 kubelet 和 kube 代理组件也可以存在于主设备中。在Figure 1中,我们’未在主设备中包含这些组件,从而简化了 master 和 node 的概念分离。您可以在设置中使用命令 kubectl get pods --all-namespaces -o wide列出所有盒箱及其位置。在主设备中生成的盒通常作为 Kubernetes 系统–的一部分在 kube 系统命名空间中运行。Kubernetes 命名空间将在第3章中讨论。

当然,这是一个简化的工作流程,但您应该了解基本想法。事实上,随着 Kubernetes 的威力,您很少需要直接使用容器。您可以使用更高级别的对象来隐藏大部分低级别操作详细信息。

例如, Figure 1在为生成容器而不是说:创建两个容器,并确保在其中任何一台出现故障时都将其生成,实践中您只需:使用副本2创建 RC 对象(复制控制器)。

在两个 Docker 容器启动并运行后,kubeapiserver 将与 kube 控制器管理器进行交互,以保持监控作业状态并采取所有必要的措施,确保运行状态是其定义。例如,如果任何 Docker 容器都关闭,将自动生成一个新容器,然后将断开的移动器删除。

此示例中的 RC 是 Kubernetes kube manager 进程提供的一个对象。Kubernetes 对象提供了额外的抽象层,以更简单、更整洁的方式在后台获得相同(通常情况下)工作。由于您在更高级别的工作,而不是从低层次的细节,Kubernetes 对象可显著降低整体部署时间、大脑工作和故障排除的麻烦。让’我们来研究一下。

Kubernetes 对象

现在,您了解了 Kubernetes 群集中 master 和 node 的角色,并了解Kubernetes Architecture中的工作流程模型,让’我们在 Kubernetes 架构中查看更多对象。

Kubernetes’s 对象表示:

  • 部署容器化应用程序和工作负载

  • 相关网络和磁盘资源

  • 有关群集正在进行的操作的其他信息。

最常使用的对象包括:

  • Pod

  • 服务

  • 音量

  • 名称空间

更高级别的对象(控制器)包括:

  • ReplicationController

  • ReplicaSet

  • 部署

  • StatefulSet

  • DaemonSet

  • 工作

Note

高级别对象基于基本对象构建,提供附加功能和便利功能。

在前端,Kubernetes 通过一组对象进行操作,因此,Kubernetes 您只需考虑如何在对象的配置文件中描述您的任务,您就’不必担心如何在容器级别中实施它。Kubernetes 在后台与容器引擎进行交互,以协调 Kubelets 上的容器的计划和执行。容器引擎本身负责运行实际容器映像(例如,通过 Docker build)。

第3章提供了有关每个对象及其幻功率的更多示例。首先,让’我们来了解最基本的对象:pod.

构建 Kubernetes 箱

Pod 是您将学习的第一个 Kubernetes 对象。Kubernetes 网站介绍了盒:

一个或多个容器(如 whales 或 pea 箱中的一盒)的一组(如 Docker 容器)、共享存储/网络以及有关如何运行容器的规范。

表明

  • Pod 本质上是一组容器。

  • 箱中的所有容器都共享存储和网络资源。

与处理’每个单独容器的方法相比,使用 pod 的优势是什么?让’我们来考虑一个简单的用例:您正在使用 Docker 部署 web 服务,您不仅需要前端服务(例如 Apache 服务器),而且可以像数据库服务器、日志服务器、监控服务器等支持服务等。每个支持服务都需要在自己的容器中运行。因此,当需要 web 服务容器时,实质上您会发现自己始终使用一组坞站。在生产中,同一情景也适用于其他大多数服务。最终,您会问:是否有一种方法可以在更高级别的单元中对一组 Docker 容器进行分组,以便您只需考虑低级容器间交互详细信息?

通过将一个或多个容器包装到一个对象中,Pod 提供您所需的完全更高的抽象级别。如果您的 web 服务变得过于流行,并且单个 pod’实例不能进行负载,则可以使用其他对象(RC、部署)的帮助,在几秒内正常地复制和扩展相同的容器组(现在以一个 pod 对象的形式)。这种显著提高了部署和维护效率。

此外,同一 pod 中的容器可共享相同的网络空间,因此容器可以与同一盒中的其他容器轻松通信,就像它们位于同一台机器上一样,同时保持其他设备的隔离程度。在这本书后面,您可以了解更多有关这些优势的信息。

现在,让’我们湿脚,了解如何使用配置文件在 Kubernetes 群集中启动盒中的 pod。

Kubernetes 的 YAML 文件

YAML 是 Kubernetes 配置文件中使用的标准格式,以及许多其他多种配置 Kubernetes 的方式。YAML 广泛使用,很可能您已经熟悉它。否则,这并’不是一件很大的交易,因为 YAML 是一种非常简单的学习语言。每行 YAML 配置都是详细的,您应了解 YAML 格式作为您的 pod 学习流程的附带结果。

YAML 格式的 pod 配置文件为:

YAML 使用三种基本数据类型:

  1. 标量(字符串/数字):atom 数据项,如 pod-1 的字符串,端口号80。

  2. 映射(哈希/字典):键/值对可嵌套。apiVersion: v1 是一个映射。key apiVersion 的值为 v1。

  3. 序列(数组/列表):有序值集合,无键。列表项以-号指示。密钥容器的值是包括两个容器的列表。

在此示例中,您还会看到嵌套的 YAML 数据结构:

  • 映射映射:规格是地图的关键,您可以在其中定义 pod’规格。在此示例中,您仅定义要在盒中启动的容器的行为。该值是带有容器键的另一个映射。

  • 列表的映射。密钥容器的值为两个项目的列表:每个服务器和客户端容器都是一个映射,它描述了具有几个属性(如名称、图像和端口)的个别容器。

您还应了解有关 YAML 的其他特性:

  • 区分大小写

  • 相同级别中的元素共享相同的左缩进,缩进量无关紧要

  • 不允许使用制表符作为缩进

  • 空行无关紧要

  • 使用 # 注释线路

  • 使用一个单引号来转义任何字符的特殊含义

在深入了解有关 YAML 文件的更多详细信息’之前,请先完成盒创建:

有. 我们创建了第一个 Kubernetes 对象– ,该 pod 称为 pod-1。但容器在哪里?输出内容提供线索:已分配 IP 地址为10.47.255.237 的 pod pod-1 (名称),包含两个容器(就绪/2),已在 Kubernetes 辅助节点 cent333 中启动。盒中的两个容器均已启动(就绪 2/),并且已处于27s 状态,无需重新启动。下面’简要逐行评论 YAML 配置的用途: "

  • 第1行:这是对文本使用编号前的注释行,您可以将任何注释放入 YAML 文件中。(在这本书中,我们使用此第一行为 YAML 文件提供文件名。在从 YAML 文件创建对象时,此命令稍后将用于该文件名。)

  • 第2、3、4行:四个 YAML 映射是 pod 定义的主要组件:

    • ApiVersion: 有不同版本,例如 v2。这里特别是版本1。

    • 种类请记住,存在不同类型的 Kubernetes 对象,此处我们希望 Kubernetes 创建 pod 对象。稍后,您将在我们的其他对象示例中看到 ReplicationController 或服务的种类。

    • 元数据以识别创建的对象。除了要创建的对象名称之外,另一个重要的元数据是标签。您将在第3章中详细了解这一点。

    • 指标这将提供有关 pod 行为的规格。

  • 线路9-15:此处的 pod 规格仅限于两个容器。系统将下载映像,启动每个具有名称的容器,并分别公开指定端口。

下面’是盒’内运行的内容:

毫无疑问,pod-1 由 Kubernetes 群集分配并在所有容器之间共享的 IP 地址包含在 YAML 文件、服务器和客户端中声明的两个容器中,如Figure 2中所示:

Figure 2: 节点、盒和容器
节点、盒和容器

暂停容器

如果登录到 node cent333,’将看到在盒内运行的 Docker 容器:

第三个带有图像名称 k8s.gcr.io/pause 的容器是 Kubernetes 系统为每个 pod 创建的特殊容器。创建的暂停容器用于管理盒的网络资源,该 pod 由该 pod 的所有容器共享。

Figure 3显示了一个盒箱,其中包括几个用户容器和一个暂停容器。

Figure 3: 箱、用户容器和特殊暂停容器
箱、用户容器和特殊暂停容器

Pod 内通信

在 Kubernetes 主设备中,’从主设备登录到一个容器:

Note

如果您曾使用 Docker 玩,您将立即意识到这相当整洁。请记住,容器在一个节点上启动,因此如果您使用 Docker,则必须先登录到正确的远程节点,然后使用类似的 Docker exec 命令登录每个容器。Kubernetes 隐藏这些详细信息。它允许您从一个节点–到主设备,执行所有操作。

现在,检查容器中运行的进程:

服务器容器

客户端容器

此 ps 命令输出显示,每个容器都在运行自己的进程。但是,ss 和 ip 命令输出指示两个容器共享相同的网络环境,因此两者都可以看到彼此公开的端口。因此,盒中容器之间的通信只需使用 localhost 即可发生。让’我们通过使用卷曲命令启动 TCP 连接来测试这种情况。

假设从客户端容器,您希望从服务器容器获取网页。您只需使用 localhost IP 地址启动曲线:

您可以看到连接已建立,网页已成功下载。

现在,’让我们来监控 TCP 连接状态:已成功建立连接:

完全相同的连接可从服务器容器中看到:

Kubectl 工具

到目前为止’,您已看到由 kubectl 命令创建的对象。与 Docker 世界中的 docker 命令一样,此命令是 Kubernetes world 中的一个接口,用于与群集进行交谈,或者更准确地说是通过 Kubernetes API 的 Kubernetes 主设备。这’是一种多用途工具,可提供满足您需要处理 Kubernetes 的所有任务的选项。

作为一个快速示例,假设您已为 kubectl 启用了自动完成功能,则可以登录到 master 和 kubectl,然后键入两个 tab 键,以列出您当前环境中支持的所有选项:

Note

要设置 kubectl 命令的自动完成,请遵循完成选项的说明:

kubectl 完成-h

请放心,您’会在本书其余部分看到并了解其中的部分选项。