1. k8s基础架构
上图是k8s的基本架构,可以看到,其基本包括两个大的方面:
- 控制平面(control-plane)组件;
- Node组件;
2. 控制平面(control-plane)组件
控制平面组件会为集群做出全局决策,比如资源的调度、检测以及响应集群事件等。控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。
2.1 kube-apiserver
API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。
2.2 etcd
一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。
2.3 kube-scheduler
kube-scheduler
是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
2.4 kube-controller-manager
kube-controller-manager 是控制平面的组件, 负责运行控制器进程。
从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
有许多不同类型的控制器。以下是一些例子(并非全部):
- 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
- 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
- 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
2.5 cloud-conroller-manager
可详见云控制器管理器(Cloud Controller Manager)。
3. Node组件
Node(节点)可以理解为机器节点,可以是虚拟机或者一台真实的物理机器。通常一个集群中会有若干节点,如果是资源受限的环境中,集群也可能只有一个节点。节点上的组件包括 kubelet、 容器运行时以及 kube-proxy。
Node组件会在每个节点上运行,负责维护运行的Pod并提供k8s运行环境。
3.1 kubelet
kubelet
会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpec,确保这些 PodSpec 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
有关kubeadm
、kubectl
和kubelet的区别,可参考Kubernetes kubeadm kubectl kubelet 区别。
3.2 kube-proxy
kube-proxy 是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
3.3 容器运行时
这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
4. Pod
Pod 是可以在k8s中创建和管理的、最小的可部署的计算单元,一个 Node 可以有一个或者多个 Pod。其英文大意是豆荚,如果把容器比作豌豆,那么Pod就是豌豆荚,即Pod是由一组容器(一个或者多个)组成,这些容器共享存储、网络、以及怎样运行这些容器的声明。Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。
和一个个独立的容器一样,Pod 也被认为是相对临时性的实体,其会被创建、赋予唯一的ID(UID),并被调度到节点,并在终止或者删除之前一直运行在该节点。如果一个节点死掉了,调度到该节点的 Pod 也被计划在给定超时期限结束后删除。Pod 本身没有自愈能力,k8s使用一种高级抽象来管理这些相对而言可随时丢弃的 Pod 实例, 称作控制器。
4.1 Workloads
上面说过,最终应用都是以容器的形式在 Pods 中运行,但是直接管理单个 Pod 的工作量会很大,我们可以使用 Kubernetes API 创建工作负载(Workloads)对象, 这些对象所表达的是比 Pod 更高级别的抽象概念,Kubernetes 控制平面根据你定义的工作负载对象规约自动管理 Pod 对象。
常见的工作负载包括:
-
Deployment (也间接包括 ReplicaSet),表示无状态的、可互换的服务;(Deployment 替代原来的 ReplicationController API)。
-
StatefulSet 允许你管理一个或多个运行相同应用代码、但具有不同身份标识的 Pod。 StatefulSet 与 Deployment 不同。Deployment 中的 Pod 预期是可互换的。 StatefulSet 最常见的用途是能够建立其 Pod 与其持久化存储之间的关联。 例如,你可以运行一个将每个 Pod 关联到 PersistentVolume 的 StatefulSet。如果该 StatefulSet 中的一个 Pod 失败了,Kubernetes 将创建一个新的 Pod, 并连接到相同的 PersistentVolume。
-
DaemonSet 定义了在特定节点上提供本地设施的 Pod, 例如允许该节点上的容器访问存储系统的驱动。当必须在合适的节点上运行某种驱动或其他节点级别的服务时, 你可以使用 DaemonSet。DaemonSet 中的每个 Pod 执行类似于经典 Unix / POSIX 服务器上的系统守护进程的角色。DaemonSet 可能对集群的操作至关重要, 例如作为插件让该节点访问集群网络, 也可能帮助你管理节点,或者提供增强正在运行的容器平台所需的、不太重要的设施。 你可以在集群的每个节点上运行 DaemonSets(及其 Pod),或者仅在某个子集上运行 (例如,只在安装了 GPU 的节点上安装 GPU 加速驱动)。
-
你可以使用 Job 和/或 CronJob 定义一次性任务和定时任务。 Job 表示一次性任务,而每个 CronJob 可以根据排期表重复执行。
5. 容器
容器是服务运行的载体,其将应用程序从底层的主机设施中解耦。 这使得在不同的云或 OS 环境中部署更加容易。k8s支持许多容器运行环境,例如 docker 、containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。