Kubernetes采用主从架构设计。Kubernetes 集群由一个控制平面(相当于管理主机)和一组用于运行容器化应用的工作机器(相当于工作从机)组成, 这些工作机器称作节点(Node)。每个集群至少需要一个工作节点来运行 Pod。
工作节点托管着组成应用负载的 Pod。控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行,而一个集群通常运行多个节点,以提供容错和高可用。
一个完整且可运行的 Kubernetes 集群所需的组件如下图。
控制平面组件
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足 Deployment 的 replicas
字段时,要启动新的 Pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,安装脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。
kube-apiserver
API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver
设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver
的多个实例,并在这些实例之间平衡流量。
etcd
一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。
如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。
kube-scheduler
kube-scheduler
是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
kube-controller-manager
kube-controller-manager 是控制平面的组件, 负责运行控制器进程。
从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
控制器有许多不同类型。以下是一些例子:
- Node 控制器:负责在节点出现故障时进行通知和响应
- Job 控制器:监测代表一次性任务的 Job 对象,然后创建 Pod 来运行这些任务直至完成。
- EndpointSlice 控制器:填充 EndpointSlice 对象(以提供 Service 和 Pod 之间的链接)。
- ServiceAccount 控制器:为新的命名空间创建默认的 ServiceAccount。
cloud-controller-manager
一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。cloud-controller-manager
仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不包含云控制器管理器。
与 kube-controller-manager
类似,cloud-controller-manager
将若干逻辑上独立的控制回路组合到同一个可执行文件中,以同一进程的方式供你运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。
下面的控制器都包含对云平台驱动的依赖:
- Node 控制器:用于在节点终止响应后检查云平台以确定节点是否已被删除
- Route 控制器:用于在底层云基础架构中设置路由
- Service 控制器:用于创建、更新和删除云平台上的负载均衡器
节点组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行时环境。
kubelet
kubelet
会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpec,确保这些 PodSpec 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
kube-proxy(可选)
kube-proxy 是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
如果你使用网络插件为 Service 实现本身的数据包转发, 并提供与 kube-proxy 等效的行为,那么你不需要在集群中的节点上运行 kube-proxy。
容器运行时
这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
插件(Addons)
Addons的翻译是附加组件、插件或扩展程序。
插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system
命名空间。
下面描述众多插件中的几种。有关可用插件的完整列表, 请参见插件(Addons)。
DNS
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
Web 界面(仪表盘)
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身,并进行故障排除。
容器资源监控
容器资源监控 将关于容器的一些常见的时序度量值保存到一个集中的数据库中,并提供浏览这些数据的界面。
集群层面日志
集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
网络插件
网络插件 是实现容器网络接口(CNI)规范的软件组件。它们负责为 Pod 分配 IP 地址,并使这些 Pod 能在集群内部相互通信。
架构变种
虽然 Kubernetes 的核心组件保持一致,但它们的部署和管理方式可能有所不同。 了解这些变化对于设计和维护满足特定运营需求的 Kubernetes 集群至关重要。
控制平面部署选项
控制平面组件可以通过以下几种方式部署:
传统部署
控制平面组件直接在专用机器或虚拟机上运行,通常作为 systemd 服务进行管理。
静态 Pod
控制平面组件作为静态 Pod 部署,由特定节点上的 kubelet 管理。 这是像 kubeadm 这样的工具常用的方法。
自托管
控制平面在 Kubernetes 集群本身内部作为 Pod 运行, 由 Deployments、StatefulSets 或其他 Kubernetes 原语管理。
托管 Kubernetes 服务
云平台通常将控制平面抽象出来,将其组件作为其服务的一部分进行管理。
工作负载调度说明
含控制平面组件在内的工作负载的调度可能因集群大小、性能要求和操作策略而有所不同:
- 在较小或开发集群中,控制平面组件和用户工作负载可能在同一节点上运行。
- 较大的生产集群通常将特定节点专用于控制平面组件,将其与用户工作负载隔离。
- 一些组织在控制平面节点上运行关键组件或监控工具。
集群管理工具
像 kubeadm、kops 和 Kubespray 这样的工具提供了不同的集群部署和管理方法, 每种方法都有自己的组件布局和管理方式。
Kubernetes 架构的灵活性使各组织能够根据特定需求调整其集群,平衡操作复杂性、性能和管理开销等因素。
定制和可扩展性
Kubernetes 架构允许大幅度的定制:
- 你可以部署自定义的调度器与默认的 Kubernetes 调度器协同工作,也可以完全替换掉默认的调度器。
- API 服务器可以通过 CustomResourceDefinition 和 API 聚合进行扩展。
- 云平台可以使用 cloud-controller-manager 与 Kubernetes 深度集成。
Kubernetes 架构的灵活性使各组织能够根据特定需求调整其集群,平衡操作复杂性、性能和管理开销等因素。
参考:Kubernetes中文文档