当部署完 Kubernetes,便拥有了一个完整的集群。
集群是由一组被称作节点(node) 的机器组成, 这些节点上会运行由 Kubernetes 所管理的容器化应用。 且每个集群至少有一个工作节点。
工作节点会托管所谓的 Pods,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pods。 为集群提供故障转移和高可用性, 这些控制平面一般跨多主机运行,而集群也会跨多个节点运行。
控制面组件会为集群做出全局决策,(比如资源的调度)。 以及检测和响应集群事件,(例如当不满足部署的 replicas
字段时, 要启动新的 pod )。
控制面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。
etcd
是兼顾一致性与高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。Kubernetes 集群的 etcd
数据库通常需要有个备份计划。
如果想要更深入的了解 etcd
,请参考 etcd 文档 。
组件负责公开 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制面的前端。
Kubernetes API 服务器的主要实现是 [kube-apiserver](https://cuizb.top/myblog/article/1663080971#kube-apiserver(API 服务器))。 kube-apiserver
设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver
的多个实例,并在这些实例之间平衡流量。
负责监视新创建的、未指定运行节点(node) 的 Pods , 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
Kubernetes 控制器管理器是一个守护进程,内嵌随 Kubernetes 一起发布的核心控制回路。 在机器人和自动化的应用中,控制回路是一个永不休止的循环,用于调节系统状态。 在 Kubernetes 中,每个控制器是一个控制回路,通过 API 服务器监视集群的共享状态, 并尝试进行更改以将当前状态转为期望状态。
负责运行控制器 进程。从逻辑上讲, 每个控制器 都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
目前,Kubernetes 自带的控制器例子包括副本控制器、节点控制器、命名空间控制器和服务账号控制器等。
这些控制器包括:
云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。嵌入了特定于云平台的控制逻辑。
cloud-controller-manager
仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。
与 kube-controller-manager
类似,cloud-controller-manager
将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。
下面的控制器都包含对云平台驱动的依赖:
Kubernetes 通过将容器放入 Pod 以在节点上运行来运行您的工作负载。节点可能是虚拟机或物理机,具体取决于集群。每个节点都由控制平面管理,并包含运行 Pod 所需的服务。
通常,集群中有多个节点;
节点上的组件包括 kubelet、容器运行时和 kube-proxy。节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet
向控制面执行自注册;例如使用json创建Node对象:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes 会在内部创建一个 Node 对象作为节点的表示。Kubernetes 检查 kubelet
向 API 服务器注册节点时使用的 metadata.name
字段是否匹配。 如果节点是健康的(即所有必要的服务都在运行中),则该节点可以用来运行 Pod。 否则,直到该节点变为健康之前,所有的集群活动都会忽略该节点。
说明: Kubernetes 会一直保存着非法节点对应的对象,并持续检查该节点是否已经变得健康。 你,或者某个控制器 必须显式地删除该 Node 对象以停止健康检查操作。
Node 对象的名称必须是合法的 DNS 子域名。
节点的名称用来标识 Node 对象。 没有两个 Node 可以同时使用相同的名称。 Kubernetes 还假定名字相同的资源是同一个对象。 就 Node 而言,隐式假定使用相同名称的实例会具有相同的状态(例如网络配置、根磁盘内容) 和类似节点标签这类属性。这可能在节点被更改但其名称未变时导致系统状态不一致。 如果某个 Node 需要被替换或者大量变更,需要从 API 服务器移除现有的 Node 对象, 之后再在更新之后重新将其加入。
一个节点的状态包含以下信息:
-hostname-override
参数覆盖。conditions
字段描述了所有 Running
节点的状况。capacity
块中的字段标示节点拥有的资源量。 allocatable
块指示节点上可供普通 Pod 消耗的资源量。kubelet
和 kube-proxy
版本)、 容器运行时详细信息,以及节点使用的操作系统。 kubelet
从节点收集这些信息并将其发布到 Kubernetes API。可以使用 kubectl
来查看节点状态和其他细节信息:
kubectl describe node <节点名称>
Kubernetes 节点发送的心跳帮助你的集群确定每个节点的可用性,并在检测到故障时采取行动。
对于节点,有两种形式的心跳:
.status
kube-node-lease
名字空间 中的 Lease(租约)对象。 每个节点都有一个关联的 Lease 对象。与 Node 的 .status
更新相比,Lease 是一种轻量级资源。 使用 Lease 来表达心跳在大型集群中可以减少这些更新对性能的影响。
kubelet 负责创建和更新节点的 .status
,以及更新它们对应的 Lease。
.status
。 .status
更新的默认间隔为 5 分钟(比节点不可达事件的 40 秒默认超时时间长很多)。
kubelet
会创建并每 10 秒(默认更新间隔时间)更新 Lease 对象。 Lease 的更新独立于 Node 的 .status
更新而发生。 如果 Lease 的更新操作失败,kubelet 会采用指数回退机制,从 200 毫秒开始重试, 最长重试间隔为 7 秒钟。
kubelet
会在集群中每个节点(node) 上运行。 它保证容器(containers) 都运行在 Pod 中。kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system
命名空间。