基本概述

Kubernetes是容器集群管理系统(简单来说就是一个开源的、用于管理云平台中多个主机的容器化应用),是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
(docker compose管理的是单机的, 并不是容器化的)

K8S的目标是: 让部署容器化的应用简单并且高效。k8s提供了应用部署、规划、更新、维护的一种机制。

几种不同时代的部署方式
![image.png]/images/1710744258125-9bc0cf2f-ac2b-4da2-b0b1-1b63a0816fc4.png)

  1. 传统的部署方式是直接部署在操作系统上, 就像我们现在开发阶段一样, 直接将项目在操作系统上进行运行。 (但是存在的问题就是环境不隔离, 导致多个应用同时使用系统中的共享资源而发生的冲突问题。)
  1. 接着就进入了虚拟化的部署方式, 虚拟化技术允许你在单个物理服务器的 CPU 上运行多台虚拟机(VM)。 虚拟化能使应用程序在不同 VM 之间被彼此隔离,且能提供一定程度的安全性, 因为一个应用程序的信息不能被另一应用程序随意访问。

每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。这样会出现占用资源过多的问题

  1. 最后就是我们现在比较主流的使用容器化部署的方式, 这种方式和虚拟化方式有着异曲同工之妙。 但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)

容器能够实现文件系统、网络、内存空间等公共资源的隔离。
因为容器本身就是基于操作系统的来实现的。他是和我们当前服务器也就是宿主机共用同一个操作系统资源的。所以他占用资源更少。

且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

容器那么好, 为什么还要用k8s?

为什么这三种方式中, 容器化部署会逐渐的流行起来呢? 原因就是因为他有着很多的优点:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
  • 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

为什么需要Kubernetes, 它能够做什么 ?

首先, 我们知道,** 容器是我们打包部署和运行应用程序的最好方式。** 在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?
这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。

K8S能够提供的功能

  • 服务发现和负载均衡

Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  • 存储编排

Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚

你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  • 自动完成装箱计算你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。

** **你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。

  • 自我修复

Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理

Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

  • 批处理执行

除了服务外,Kubernetes 还可以管理你的批处理和 CI(持续集成)工作负载,如有需要,可以替换失败的容器。

  • 水平扩缩

使用简单的命令、用户界面或根据 CPU 使用率自动对你的应用进行扩缩。

  • IPv4/IPv6 双栈

为 Pod(容器组)和 Service(服务)分配 IPv4 和 IPv6 地址。

  • 为可扩展性设计

在不改变上游源代码的情况下为你的 Kubernetes 集群添加功能。

K8s不是什么 ?

Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 是在容器级别运行,而非在硬件级别,它提供了 PaaS 产品共有的一些普遍适用的功能, 例如部署、扩展、负载均衡,允许用户集成他们的日志记录、监控和警报方案。 但是,Kubernetes 不是单体式(monolithic)系统,那些默认解决方案都是可选、可插拔的。 Kubernetes 为构建开发人员平台提供了基础,但是在重要的地方保留了用户选择权,能有更高的灵活性。

操作K8s —- K8s对象

![image.png]/images/1710746096577-d35d50bc-86e2-4042-a879-d733cd8de1c7.png)

我们这里只是了解了最基本的,剩下的内容暂时没有学习到。

**操作 Kubernetes 对象 —— 无论是创建、修改或者删除 —— 需要使用 **Kubernetes API。 比如,当使用 kubectl 命令行接口(CLI)时,CLI 会调用必要的 Kubernetes API; 也可以在程序中使用客户端库, 来直接调用 Kubernetes API。
几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置: 对象 spec(规约) 和对象 status(状态)。 对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State)

描述 Kubernetes 对象

创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态, 以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(直接创建或经由 kubectl 创建),** API 请求必须在请求主体中包含 JSON 格式的信息。** 大多数情况下,你会通过 清单(Manifest) 文件为 kubectl 提供这些信息。 按照惯例,清单是 YAML 格式的(你也可以使用 JSON 格式)。 像 kubectl 这样的工具在通过 HTTP 进行 API 请求时, 会将清单中的信息转换为 JSON 或其他受支持的序列化格式。
这里有一个清单示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

与上面使用清单文件来创建 Deployment 类似,另一种方式是使用 kubectl 命令行接口(CLI)的 kubectl apply 命令, 将 .yaml 文件作为参数。下面是一个示例:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
输出类似下面这样:
deployment.apps/nginx-deployment created

必需字段

在想要创建的 Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态

对每个 Kubernetes 对象而言,其 spec 之精确格式都是不同的,包含了特定于该对象的嵌套字段。 Kubernetes API 参考可以帮助你找到想要使用 Kubernetes 创建的所有对象的规约格式。

Pod是什么?

Kubernetes 中的 Pod 是 Kubernetes 集群中最小的、可以创建和管理的部署单元。每个 Pod 都包含一个或多个容器(例如 Docker 容器),这些容器共享存储、网络和一个运行规范。Pod 里的容器总是被同时调度到同一台主机上,并且在同一命名空间中运行,这意味着它们可以很容易地共享资源。
Pod 是 Kubernetes 应用程序的基本构建块,每个 Pod 都被设计为运行一个特定的实例的应用程序。如果应用程序需要水平扩展,则可以通过增加 Pod 的副本数量来实现。

主要特性:

  • 共享网络:Pod 中的所有容器共享一个 IP 地址和端口空间,它们可以使用 localhost 相互通信。
  • 共享存储:Pod 可以定义共享存储卷,这些存储卷可以被 Pod 中的所有容器访问。
  • 生命周期管理:Kubernetes 以 Pod 为单位管理容器的生命周期。Pod 中的容器会同时被创建和销毁。
  • 资源共享和通信:由于 Pod 中的容器共享相同的网络命名空间,它们可以使用标准的进程间通信(IPC)和同一主机上的其他进程通信,如通过共享内存。
  • 独立管理:虽然一个 Pod 可以包含多个容器,但它们作为一个整体被 Kubernetes 管理,这简化了部署和管理过程。

在设计应用时,通常会将相互密切相关且需要紧密协作的容器放在同一个 Pod 中。例如,一个应用程序容器和一个辅助的日志收集容器可以被部署在同一个 Pod 中。这种设计模式有助于简化相关容器间的通信和资源共享。

容器

每个运行的容器都是可重复的; 包含依赖环境在内的标准,意味着无论你在哪里运行它都会得到相同的行为。
容器将应用程序从底层的主机设施中解耦。 这使得在不同的云或 OS 环境中部署更加容易。
Kubernetes 集群中的每个节点都会运行容器, 这些容器构成分配给该节点的 Pod。 单个 Pod 中的容器会在共同调度下,于同一位置运行在相同的节点上。

容器镜像

容器镜像是一个随时可以运行的软件包, 包含运行应用程序所需的一切:代码和它需要的所有运行时、应用程序和系统库,以及一些基本设置的默认值。
容器旨在设计成无状态且不可变的: 你不应更改已经运行的容器的代码。如果有一个容器化的应用程序需要修改, 正确的流程是:先构建包含更改的新镜像,再基于新构建的镜像重新运行容器。

容器运行时

这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerdCRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
通常,你可以允许集群为一个 Pod 选择其默认的容器运行时。如果你需要在集群中使用多个容器运行时, 你可以为一个 Pod 指定 RuntimeClass, 以确保 Kubernetes 会使用特定的容器运行时来运行这些容器。

K8s组件

当你部署完 Kubernetes,便拥有了一个完整的集群。
主节点可以即作为主节点 也 可以作为从节点
一组工作机器,称为节点, 会运行容器化应用程序。每个集群至少有一个工作节点。

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器

**工作节点会托管 **Pod,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。

本段概括了一个正常的k8s集群所需要的各种组件

![image.png]/images/1711084841976-c6b81509-7142-4ecd-b65b-6e9f496675e5.png)

控制平面组件(Control Plame控制面板)—-在master上

![image.png]/images/1711087871903-813f6130-5389-4413-a94a-f0d97b044314.png)
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足部署的 replicas 字段时,要启动新的 Pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。

控制平面组件有:
kube-apiserver 、kube-scheduler、 etcd、kube-controller-manager …

kube-apiserver

API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。

接口服务,基于REST风格开发k8s接口的服务

kube/cloud-controller-manager

控制器管理器: 管理各个类型的控制器。 对k8s中的各种资源进行管理
从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,他们都被编译到同一个可执行文件,并在同一个进程中运行。
我们上述中讲述了两个控制器管理器, 但是对于我们项目而言, cloud-controller-manager是第三方平台提供的控制器API对接管理功能。主要使用的是kube-controller-manager
这些控制器主要包括以下几种。

控制器包括: 节点控制器

节点控制器负责在云基础设施中创建了新服务器时为之更新节点(Node)对象。** 节点控制器从云提供商获取当前租户中主机的信息。**节点控制器执行以下功能:

  1. 使用从云平台 API 获取的对应服务器的唯一标识符更新 Node 对象;
  2. 利用特定云平台的信息为 Node 对象添加注解和标签,例如节点所在的区域 (Region)和所具有的资源(CPU、内存等等);
  3. 获取节点的网络地址和主机名;
  4. 检查节点的健康状况。如果节点无响应,控制器通过云平台 API 查看该节点是否已从云中禁用、删除或终止。如果节点已从云中删除, 则控制器从 Kubernetes 集群中删除 Node 对象。

某些云驱动实现中,这些任务被划分到一个节点控制器和一个节点生命周期控制器中。

路由控制器

Route 控制器负责适当地配置云平台中的路由,以便 Kubernetes 集群中不同节点上的容器之间可以相互通信。
取决于云驱动本身,路由控制器可能也会为 Pod 网络分配 IP 地址块。

服务控制器

服务(Service)与受控的负载均衡器、 IP 地址、网络包过滤、目标健康检查等云基础设施组件集成。 服务控制器与云驱动的 API 交互,以配置负载均衡器和其他基础设施组件。 你所创建的 Service 资源会需要这些组件服务。

kube-scheduler调度器

kube-scheduler 是控制平面的组件,** 负责监视新创建的、未指定运行**节点(node)**的 **Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
主要作用简单来说就是通过一定的调度算法,将pod调度到更合适的节点上。

etcd

一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。
如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。
你可以在官方文档中找到有关 etcd 的深入知识

Node组件

节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
![image.png]/images/1711087487672-a29b5067-59e7-4dc9-93f7-a027e6921177.png)

一台服务器是一个节点, 一个节点下面可能有多个Pod, 一个Pod下面可能会有多个容器

kubelet

kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)**都运行在 Pod 中。(简单来说就是负责pod的生命周期、存储、网络)
kubelet 接收一组通过各类机制提供给它的 PodSpec,确保这些 PodSpec 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

kube-proxy

kube-proxy是集群中每个**节点(node)**上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。(简单来说就是负责Service的服务发现,负载均衡(4层负载))
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。

容器运行时环境(Container Runtime)

对应Java的运行时环境jre

这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerd(容器)、 CRI-O (是 Kubernetes CRI(容器运行时接口)的实现,支持使用 OCI(开放容器计划)兼容的运行时。)以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。

总共有很多, 这里简单介绍这几个。 剩下的后面在进行学习

附加组件———插件(Addons)

插件使用 Kubernetes 资源(DaemonSetDeployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间。
下面描述众多插件中的几种。有关可用插件的完整列表,请参见 插件(Addons)

DNS

尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。

Web 界面(仪表盘)

Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。

容器资源监控

容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。

集群层面日志

集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。

网络插件

网络插件 是实现容器网络接口(CNI)规范的软件组件。它们负责为 Pod 分配 IP 地址,并使这些 Pod 能在集群内部相互通信。

Kubernetes API

**Kubernetes **控制面**的核心是 **API 服务器。 API 服务器负责提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信。
Kubernetes API 使你可以在 Kubernetes 中查询和操纵 API 对象 (例如 Pod、Namespace、ConfigMap 和 Event)的状态。
大部分操作都可以通过 kubectl 命令行接口或类似 kubeadm 这类命令行工具来执行, 这些工具在背后也是调用 API。不过,你也可以使用 REST 调用来访问这些 API。

每个 Kubernetes 集群都会发布集群所使用的 API 规范。 Kubernetes 使用两种机制来发布这些 API 规范;这两种机制都有助于实现自动互操作。

  • **发现(Discovery) API 提供有关 Kubernetes API 的信息:API 名称、资源、版本和支持的操作。 **此 API 是特定于 Kubernetes 的一个术语,因为它是一个独立于 Kubernetes OpenAPI 的 API。 其目的是为可用的资源提供简要总结,不详细说明资源的具体模式。有关资源模式的参考,请参阅 OpenAPI 文档。
  • **Kubernetes OpenAPI 文档为所有 Kubernetes API 端点提供(完整的) **OpenAPI v2.0 和 v3.0 模式OpenAPI v3 是访问 OpenAPI 的首选方法, 因为它提供了更全面和准确的 API 视图。其中包括所有可用的 API 路径,以及每个端点上每个操作所接收和生成的所有资源。 它还包括集群支持的所有可扩展组件。这些数据是完整的规范,比 Discovery API 提供的规范要大得多。

Discovery API

Kubernetes 通过 Discovery API 发布集群所支持的所有组版本和资源列表。对于每个资源,包括以下内容:

  • 名称
  • 集群作用域还是名字空间作用域
  • 端点 URL 和所支持的动词
  • 别名
  • 组、版本、类别

OpenAPI 接口定义

有关 OpenAPI 规范的细节,参阅 OpenAPI 文档
Kubernetes 同时提供 OpenAPI v2.0 和 OpenAPI v3.0。OpenAPI v3 是访问 OpenAPI 的首选方法, 因为它提供了对 Kubernetes 资源更全面(无损)的表示。由于 OpenAPI v2 的限制, 所公布的 OpenAPI 中会丢弃掉一些字段,包括但不限于 default、nullable、oneOf。

持久化

**Kubernetes 通过将序列化状态的对象写入到 **etcd中完成存储操作。

Kubernetes整体的架构

上述中我们学习到的相关名词, 在这里都可以找到对应的标识
![image.png]/images/1710747807342-7dd88056-06b2-490d-9c46-b108bfbb89d5.png)

这张图片展示的是一个Kubernetes集群的架构图,这是一个用于自动化部署、扩展和管理容器化应用程序的系统。
图中上方的“CONTROL PLANE”是控制平面,它负责整个集群的管理和协调工作。控制平面的组件包括:

  • etcd:一个轻量级的分布式键值存储,用于保存所有集群数据,确保数据的一致性。
  • kube-api-server:作为Kubernetes API的服务端,是控制平面的前端,与其他组件交互。
  • scheduler(kube-scheduler):负责调度决策,选择哪个节点运行未分配的Pod。
  • Controller Manager(kube-controller-manager):运行控制器进程,这些进程包括节点控制器、端点控制器、命名空间控制器等。
  • cloud-control-manager:链接到各种云服务提供商的控制器,以便Kubernetes可以使用云提供商的特定资源。

图中中间的“CLUSTER”是(cluster)集群本身,通常包含多个Node 节点,图中展示了两个节点。
每个节点包含:

  • kubelet:确保容器运行在Pod中。它接受来自kube-api-server的指令,管理Pod和容器运行。
  • kube-proxy:维护节点网络规则,执行连接转发。

节点内部还包括:

  • Pod:最小的部署单元,可以包含一个或多个容器。
  • CRI:容器运行时接口,允许kubelet使用多种容器运行时。

图中最右边的“CLOUD PROVIDER API”表示Kubernetes集群可以与云提供商的API进行交互,以利用云平台提供的资源和服务。
这个图清晰地展示了Kubernetes集群的不同组件以及它们之间的关系。控制平面负责集群的整体运行,而节点则是实际运行工作负载的地方。

K8S分层架构图

![image.png]/images/1711088807653-6441d837-4ce5-44fc-8454-30b8b5f32e85.png)

  1. Ecosystem生态系统层

最顶层是指 Kubernetes 的生态系统,包括所有与 Kubernetes 集成的额外工具和服务,比如 CI/CD 工具、监控和日志工具、各种扩展和插件等。这些不是 Kubernetes 的必要部分,但它们丰富了 Kubernetes 的功能,使其能够更好地服务于不同的使用场景。

  1. Interface Layer接口层:客户端库和工具

这一层为开发者和管理员提供与 Kubernetes 集群交互的客户端库和命令行工具,如 kubectl 和 Kubernetes 的客户端 SDK。

  1. Governance Layer 治理层:自动化和策略执行

此层包含了自动化操作和策略执行的工具和组件,如自动扩缩容、Pod 生命周期管理、策略的定义和执行等。

  1. Appication Layer 应用层:部署和路由

位于核心层之上,负责应用的部署、服务发现和路由。这涉及到部署应用、更新和回滚、服务发现和负载均衡。

  1. Nucleus 核心层( 也就是我们之前说的control plane 控制平面层的相关组件)

这是 Kubernetes 架构的基础,包含了核心的 API 服务器和执行逻辑。这一层负责处理和响应 API 请求,以及维护集群的状态。这一层的组件包括:

  • Container Runtime:容器运行时,负责运行容器,如 Docker、containerd 等。
  • Network Plugin:网络插件,管理 Pod 间和集群内部的网络通信,如 Calico、Flannel 等。
  • Volume Plugin:存储卷插件,管理存储挂载和卷的生命周期。
  • Image Registry:镜像仓库,用于存储容器镜像,如 Docker Hub、Google Container Registry。
  • Cloud Provider:云服务提供者,与云平台集成,实现服务的自动化部署和扩缩容。
  • Identity Provider:身份提供者,用于认证和授权。

:::info
在 Kubernetes 的核心层,这些组件共同工作,提供了创建、调度、运行和管理容器化应用所需的所有功能。API Server 作为核心服务,其他组件都通过它与 Kubernetes 的控制平面进行通信,它负责接受和处理 REST 请求,操作 etcd(存储集群状态的键值数据库)来保存集群状态,以及调度工作到具体的节点上。核心层的设计是为了确保集群的稳定和高效运作,它处理的是更低级别、更接近系统的操作,为集群的其他部分提供服务。
:::

节点Node

Kubernetes 通过将容器放入在节点(Node)上运行的 Pod 中来执行你的工作负载。** 节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。** 每个节点包含运行 Pod 所需的服务; 这些节点由控制面负责管理。
通常集群中会有若干个节点;而在一个学习所用或者资源受限的环境中,你的集群中也可能只有一个节点。
节点上的组件包括 kubelet容器运行时以及 kube-proxy

CRI(容器运行时接口)

CRI 是一个插件接口,它使 kubelet 能够使用各种容器运行时,无需重新编译集群组件。
你需要在集群中的每个节点上都有一个可以正常工作的容器运行时, 这样 kubelet 能启动 Pod 及其容器。
容器运行时接口(CRI)是 kubelet 和容器运行时之间通信的主要协议。
Kubernetes 容器运行时接口(Container Runtime Interface;CRI)定义了主要 gRPC 协议, 用于节点组件 kubelet 和**容器运行时**之间的通信。

节点与控制面之间的通信

本段列举控制面节点(确切地说是 API 服务器)和 Kubernetes 集群之间的通信路径。 目的是为了让用户能够自定义他们的安装,以实现对网络配置的加固, 使得集群能够在不可信的网络上(或者在一个云服务商完全公开的 IP 上)运行。

节点到控制面

Kubernetes 采用的是中心辐射型(Hub-and-Spoke)API 模式。 所有从节点(或运行于其上的 Pod)发出的 API 调用都终止于 API 服务器。 其它控制面组件都没有被设计为可暴露远程服务。 API 服务器被配置为在一个安全的 HTTPS 端口(通常为 443)上监听远程连接请求, 并启用一种或多种形式的客户端身份认证机制。 一种或多种客户端鉴权机制应该被启用, 特别是在允许使用匿名请求服务账户令牌的时候。
应该使用集群的公共根证书开通节点, 这样它们就能够基于有效的客户端凭据安全地连接 API 服务器。 一种好的方法是以客户端证书的形式将客户端凭据提供给 kubelet。 请查看 kubelet TLS 启动引导 以了解如何自动提供 kubelet 客户端证书。
想要连接到 API 服务器的 Pod 可以使用服务账号安全地进行连接。 当 Pod 被实例化时,Kubernetes 自动把公共根证书和一个有效的持有者令牌注入到 Pod 里。 kubernetes 服务(位于 default 名字空间中)配置了一个虚拟 IP 地址, 用于(通过 kube-proxy)转发请求到 API 服务器的 HTTPS 末端。
控制面组件也通过安全端口与集群的 API 服务器通信。
这样,从集群节点和节点上运行的 Pod 到控制面的连接的缺省操作模式即是安全的, 能够在不可信的网络或公网上运行。

控制面到节点

从控制面(API 服务器)到节点有两种主要的通信路径。 第一种是从 API 服务器到集群中每个节点上运行的 kubelet 进程。 第二种是从 API 服务器通过它的代理功能连接到任何节点、Pod 或者服务。

….

服务、负载均衡和联网

Kubernetes 网络模型

**集群中每一个 **Pod 都会获得自己的、 独一无二的 IP 地址, 这就意味着你不需要显式地在 Pod 之间创建链接,你几乎不需要处理容器端口到主机端口之间的映射。 这将形成一个干净的、向后兼容的模型;在这个模型里,从端口分配、命名、服务发现、 负载均衡、 应用配置和迁移的角度来看,Pod 可以被视作虚拟机或者物理主机。

Kubernetes强制要求所有网络设施都满足以下基本要求(从而排除了有意隔离网络的策略):

  • Pod 能够与所有其他节点上的 Pod 通信, 且不需要网络地址转译(NAT)
  • 节点上的代理(比如:系统守护进程、kubelet)可以和节点上的所有 Pod 通信

说明:对于支持在主机网络中运行 Pod 的平台(比如:Linux), 当 Pod 挂接到节点的宿主网络上时,它们仍可以不通过 NAT 和所有节点上的 Pod 通信。