k8s (Kubernetes) 架构与组件介绍 – wiki基地


深入解析 Kubernetes 架构与核心组件

引言

在当今瞬息万变的数字世界中,软件应用的部署、扩展和管理正变得日益复杂。容器技术的兴起为解决这些挑战提供了强大的基础,而 Kubernetes (常缩写为 K8s) 则站在了容器编排领域的巅峰。作为一个开源平台,Kubernetes 自动化了容器化应用的部署、扩展和管理过程,极大地提高了开发和运维效率。

要真正理解 Kubernetes 的强大之处并有效利用它,深入了解其底层架构和核心组件是至关重要的。Kubernetes 的设计哲学是分布式的、松耦合的,这使得它既强大又灵活,但也带来了架构上的复杂性。本文将详细剖析 Kubernetes 的整体架构,逐一介绍构成其核心的各个组件,并解释它们如何协同工作,共同构建一个健壮、可扩展的应用部署平台。

Kubernetes 整体架构概览

Kubernetes 采用了一种典型的控制平面(Control Plane,旧称 Master Node)与工作节点(Worker Node)的分布式架构模式。这种架构清晰地划分了职责:

  1. 控制平面 (Control Plane): 它是 Kubernetes 集群的大脑,负责管理整个集群的状态、调度应用程序、响应集群事件、维护集群的期望状态等。控制平面通常运行在专门的节点上,为了高可用性,生产环境中通常会部署多个控制平面节点。
  2. 工作节点 (Worker Node): 它们是集群中真正运行应用程序容器的地方。每个工作节点都运行着接收控制平面指令的必要服务,并管理在其上运行的 Pod(Kubernetes 中最小的可部署单元)。

想象一个乐队:控制平面就像是乐队的指挥,他知道乐谱(期望状态),协调各个乐器(工作节点),并在出现问题时进行调整。工作节点就像是乐队的乐手,他们负责实际演奏音乐(运行容器),并听从指挥的指示。

接下来,我们将分别深入探讨控制平面和工作节点的内部构成。

控制平面组件详解 (Control Plane Components)

控制平面是 Kubernetes 集群的核心智能所在。它由一系列协同工作的组件组成,这些组件负责集群的全局管理和协调。

1. API Server (kube-apiserver)

  • 作用: API Server 是 Kubernetes 控制平面的核心,也是整个集群的唯一入口。所有其他组件(包括控制平面内部组件、工作节点上的 Kubelet、命令行工具 kubectl 以及其他用户和外部服务)都通过 API Server 进行通信和交互。
  • 功能:
    • 接收并处理 RESTful API 请求: 它暴露了 Kubernetes API,所有操作(如创建 Pod、Service、Deployment 等)都是通过 API 请求完成的。
    • 数据校验: 对接收到的 API 请求进行严格的校验,确保数据的有效性和一致性。
    • 持久化数据: 将集群的状态数据(包括所有对象的信息、配置等)写入后台的持久化存储中 (etcd)。
    • 提供一致的数据视图: API Server 不直接存储数据,而是通过 etcd 读取和写入。它负责提供一个一致的、事务性的数据视图给所有客户端。
    • 认证、授权和准入控制 (Authentication, Authorization, Admission Control): API Server 是集群安全的第一道防线。它验证请求者的身份(认证)、确定请求者是否有权限执行操作(授权),并在请求被执行前进行额外的策略检查和修改(准入控制)。
    • Watch 机制: 支持客户端通过 Watch 机制监听特定资源的变化,这是 Kubernetes 控制循环(Control Loop)得以运行的基础。当 etcd 中的数据发生变化时,API Server 会通知监听它的客户端。
  • 重要性: API Server 的高可用性对于整个集群至关重要。如果 API Server 不可用,集群的控制平面将瘫痪,无法进行任何管理操作,尽管已经在运行的应用可能不会立即停止。其模块化的设计和强大的安全功能使其成为 Kubernetes 架构的基石。

2. etcd

  • 作用: etcd 是一个高可用、强一致性的分布式键值存储系统,它是 Kubernetes 集群的后端存储。集群的所有状态数据(例如 Pod、Service、Deployment 的定义、节点状态、配置信息等)都存储在 etcd 中。
  • 功能:
    • 持久化存储: 存储集群的配置数据和状态数据。
    • 分布式和高可用: etcd 是一个分布式系统,通常以集群模式部署,以确保存储的高可用性。即使部分 etcd 节点故障,系统仍然可以正常工作。
    • 强一致性: 使用 Raft 一致性算法,确保所有 etcd 节点上的数据保持一致。这对于维护集群状态的单一事实来源至关重要。
    • Watch 机制: 支持客户端监听特定键的变化,并发送通知。API Server 利用这一机制来监测 etcd 中数据的变化,进而通知其他组件。
  • 重要性: etcd 存储着整个 Kubernetes 集群的“真相”或“期望状态”。如果 etcd 丢失数据或发生故障且无法恢复,那么整个集群的状态将无法恢复,后果非常严重。因此,确保 etcd 的数据安全、备份和高可用性是运维 Kubernetes 集群的关键任务。

3. Scheduler (kube-scheduler)

  • 作用: Scheduler 负责监控新创建但尚未分配到任何节点的 Pod。它根据一系列预设的策略(如资源需求、节点亲和性/反亲和性、污点/容忍度、节点上的负载等)为 Pod 选择一个最合适的节点来运行。
  • 功能:
    • 过滤 (Filtering): 根据 Pod 的要求和节点的条件,排除掉不符合条件的节点。
    • 打分 (Scoring): 对剩余的符合条件的节点进行打分,分数高的表示更适合运行该 Pod。打分考虑多种因素,例如资源的有效利用率、跨可用区的分布、节点亲和性等。
    • 绑定 (Binding): 将 Pod 绑定到选定的最优节点上。这个绑定操作是通过调用 API Server 来更新 Pod 的定义信息,标记它将被哪个节点执行。
  • 工作流程: Scheduler 通过 API Server 的 Watch 机制监听新创建的 Pod。一旦发现没有分配节点的 Pod,就会启动调度流程,为其选择节点,并通过 API Server 更新 Pod 的 nodeName 字段,完成绑定。实际运行 Pod 的任务则由目标节点上的 Kubelet 完成。
  • 重要性: Scheduler 的效率和策略直接影响到集群资源的利用率、应用的可用性和性能。一个好的调度器能够确保工作负载均匀分布,避免单点故障,并满足应用的特定部署需求。

4. Controller Manager (kube-controller-manager)

  • 作用: Controller Manager 运行着许多不同的控制器(Controller)。每个控制器都是一个独立的控制回路(Control Loop),它通过 API Server 持续监控集群的当前状态,并尝试驱动当前状态向期望状态靠拢。
  • 功能: 运行核心控制器,例如:
    • Node Controller (节点控制器): 负责监控节点的状态(如节点是否宕机)。如果节点长时间不可达,它会标记节点为 Unreachable,并在一定延迟后,将运行在该节点上的 Pod 驱逐(删除)。
    • Replication Controller (副本控制器): 负责维护特定数量的 Pod 副本,例如 ReplicationController, ReplicaSet。它监控由其管理的 Pod 数量,如果数量少于期望值,它会创建新的 Pod;如果数量多于期望值,它会终止多余的 Pod。
    • Endpoints Controller (端点控制器): 负责填充 Services 对象的 Endpoints。Endpoints 是 Service 背后 Pod 的 IP 地址和端口列表。当 Pod 发生变化(创建、删除、IP 变化)时,Endpoints Controller 会更新对应的 Endpoints 对象,使得 Service 能够找到正确的 Pod。
    • Service Account Controller (服务账户控制器): 为命名空间创建默认的 ServiceAccount,并确保 ServiceAccounts 的 Secret 在 API Server 中存在。
    • Job Controller (任务控制器): 负责管理 Job 对象,确保批处理任务(一次性运行完成并终止的任务)能够按计划执行。
    • CronJob Controller (定时任务控制器): 负责管理 CronJob 对象,根据计划创建 Job。
  • 工作流程: 每个控制器通常通过 API Server 的 Watch 机制监听其关注的资源对象的变化。当变化发生时,控制器会被触发,读取当前状态,与存储在 etcd 中的期望状态进行比较,然后调用 API Server 执行必要的操作(如创建/删除 Pod、更新对象状态等)来达到期望状态。这个持续比较和调整的过程就是 Kubernetes 的核心控制循环理念。
  • 重要性: Controller Manager 是 Kubernetes 实现自动化管理和自我修复的关键。通过不同的控制器,Kubernetes 能够确保应用的副本数量、服务的可访问性等始终符合用户的期望。

5. Cloud Controller Manager (cloud-controller-manager) – 可选

  • 作用: 如果你在云环境中运行 Kubernetes(例如 AWS、GCE、Azure 等),Cloud Controller Manager 负责与云提供商的 API 进行交互。它将云平台特定的功能集成到 Kubernetes 中。
  • 功能: 运行与底层云平台集成的控制器,例如:
    • Node Controller: 检查云提供商的 API,确定节点在云平台中是否已被删除。
    • Route Controller: 在云平台中配置路由,使得不同节点上的 Pod 之间可以相互通信。
    • Service Controller: 与云提供商的负载均衡服务集成,创建外部负载均衡器来暴露 Service。
    • Volume Controller: 与云提供商的块存储服务集成,创建、附加和卸载卷。
  • 重要性: Cloud Controller Manager 的引入使得 Kubernetes 的核心代码更加通用,与具体的云平台解耦。云提供商可以开发自己的 Cloud Controller Manager 实现来与 Kubernetes 对接,而无需修改 Kubernetes 的核心代码。这增强了 Kubernetes 的可移植性和 extensibility。在裸金属环境或本地部署的集群中,通常不需要 Cloud Controller Manager。

工作节点组件详解 (Worker Node Components)

工作节点是 Kubernetes 集群中实际运行用户应用(以 Pod 的形式)的地方。每个工作节点都包含运行容器和与控制平面通信所需的关键组件。

1. Kubelet

  • 作用: Kubelet 是运行在每个工作节点上的主要代理程序。它负责与控制平面通信,接收并执行控制平面下发的指令(特别是关于 Pod 的创建、启动、停止和删除),并向控制平面报告节点和 Pod 的状态。
  • 功能:
    • 注册节点: 向 API Server 注册自身,成为集群的一部分。
    • 监视 Pod 规约 (Pod Specs): 通过 API Server 的 Watch 机制持续监听分配给该节点的 Pod 的定义(Pod Spec)。
    • 管理 Pod 生命周期: 根据收到的 Pod Spec,Kubelet 负责管理该 Pod 的生命周期。这包括:
      • 调用容器运行时拉取容器镜像。
      • 创建并启动容器(通过 CRI 接口)。
      • 停止和删除容器。
      • 处理 Pod 的各种状态(Running, Pending, Succeeded, Failed)。
    • 报告状态: 向 API Server 报告节点的状态(如 CPU/内存/存储资源、网络配置、Conditions 等)以及在该节点上运行的 Pods 的状态。
    • 执行容器命令: 可以通过 API Server 和 Kubelet 执行进入容器(kubectl exec)或查看容器日志(kubectl logs)等操作。
  • 重要性: Kubelet 是连接控制平面和工作节点的桥梁。它是节点上实际执行容器操作的“手和脚”。没有 Kubelet,工作节点就无法被控制平面管理,也无法运行任何应用。

2. Kube-proxy

  • 作用: Kube-proxy 是运行在每个工作节点上的网络代理,负责实现 Kubernetes Service 的网络功能。它维护节点上的网络规则,使得 Service 能够将请求正确地路由到其背后的 Pods。
  • 功能:
    • 监听 Service 和 Endpoints 的变化: 通过 API Server 的 Watch 机制监听 Service 和 Endpoints 对象的变化。
    • 维护网络规则: 根据 Service 和 Endpoints 信息,Kube-proxy 在节点上配置网络转发规则。这些规则可以是 iptables 规则、IPVS 规则或用户空间代理。
    • 实现 Service 的负载均衡: 当有流量到达 Service 的 ClusterIP 或 NodePort 时,Kube-proxy 配置的规则会将请求负载均衡地转发到 Service 对应的某个健康 Pod 上。
    • 处理不同模式: Kube-proxy 可以运行在不同的模式下,主要有:
      • iptables: 使用 Linux 内核的 iptables 规则实现 Service 转发。这是默认模式,效率较高。
      • ipvs: 使用 Linux 内核的 IPVS (IP Virtual Server) 实现 Service 转发。在大规模集群中性能通常优于 iptables,支持更多负载均衡算法。
      • userspace: 最早的模式,现在已不常用,性能较差。
  • 重要性: Kube-proxy 是 Kubernetes Service 网络的核心。它确保了 Service 这种抽象能够有效地将请求代理到动态变化的 Pod 集合上,为应用提供了稳定的访问入口和基本的负载均衡能力。

3. Container Runtime

  • 作用: Container Runtime 是负责实际运行容器的软件。它是每个工作节点上必不可少的组件。
  • 功能:
    • 拉取镜像: 从容器仓库(如 Docker Hub, Quay.io 等)拉取容器镜像。
    • 启动容器: 根据容器镜像和 Pod Spec 中定义的配置,创建并启动容器。
    • 停止容器: 接收 Kubelet 指令,停止正在运行的容器。
    • 删除容器: 删除不再需要的容器。
    • 管理容器的生命周期: 负责容器的创建、运行、监控和销毁。
    • 实现 CRI 接口: Kubernetes 定义了容器运行时接口 (Container Runtime Interface, CRI)。Kubelet 通过 CRI 与具体的容器运行时进行交互,这使得 Kubernetes 可以支持多种不同的容器运行时,而无需修改 Kubelet 的代码。
  • 常见实现: Docker (通过 dockershim 兼容层或新的 cri-dockerd), containerd, CRI-O, rkt 等。
  • 重要性: 容器运行时是 Kubernetes 能够运行容器化应用的基础。CRI 接口的引入是 Kubernetes 走向开放和支持多样化容器技术的关键一步。

核心概念与对象 (Core Concepts and Objects)

虽然不是独立的进程组件,但理解 Kubernetes 的核心概念和对象对于理解其架构至关重要,因为这些对象是各个组件操作和管理的目标。

  • Pod: Kubernetes 中最小的可部署计算单元。一个 Pod 包含一个或多个紧密关联、共享网络命名空间和存储卷的容器。Pod 是原子性的,一起创建、一起调度、一起终止。Kubelet 直接管理 Pod。
  • Service: 一个抽象层,定义了一组 Pods 的逻辑集合以及访问它们的策略。Service 为 Pods 提供了一个稳定的 IP 地址和 DNS 名称,即使 Pods 的生命周期短暂、数量动态变化。Kube-proxy 在节点上实现 Service 的网络功能,Endpoints Controller 维护 Service 背后的 Pod 列表。
  • Volume: 为 Pod 中的容器提供可持久化存储或共享存储的方式。解耦了存储的生命周期与 Pod 的生命周期。Kubelet 与容器运行时协作挂载卷。
  • Namespace: 提供一种机制,将集群资源(如 Pods、Services、Deployments 等)划分为相互隔离的逻辑组。有助于多团队或多项目在同一个集群中共享资源。
  • Deployment: 一种更高层次的控制器,用于声明式地管理 Pods 和 ReplicaSets。通常用于无状态应用的部署。Deployment Controller 负责创建和更新 ReplicaSets,而 ReplicaSet Controller 则负责维护期望数量的 Pod 副本。通过 Deployment 可以方便地进行应用的版本更新(滚动升级、回滚)和扩缩容。
  • StatefulSet: 用于管理有状态应用的控制器。与 Deployment 类似,但为每个 Pod 提供稳定的、唯一的网络标识和持久存储。适用于数据库、消息队列等需要稳定身份和持久状态的应用。
  • DaemonSet: 确保在集群中的 每一个(或特定)工作节点上运行一个 Pod 的副本。常用于运行集群存储守护进程、日志收集代理 (如 Fluentd)、节点监控代理 (如 Prometheus Node Exporter) 等需要在每个节点上运行的服务。
  • ConfigMap & Secret: 用于存储配置数据 (ConfigMap) 和敏感信息 (Secret)。它们可以将配置信息与应用镜像解耦,提高应用的灵活性和安全性。Kubelet 可以将 ConfigMap 和 Secret 作为文件或环境变量注入到 Pod 中。

组件协同工作流程示例

让我们通过一个简单的例子来看看这些组件是如何协同工作的:用户部署一个 Nginx 应用。

  1. 用户操作: 用户使用 kubectl apply -f nginx-deployment.yaml 命令提交一个 Deployment 定义文件。
  2. API Server 接收: kubectl 将 Deployment 定义文件发送给 API Server (通过 REST API 调用)。
  3. API Server 校验与存储: API Server 接收并校验请求,确认用户有权限,然后将 Deployment 对象存储到 etcd 中。
  4. Controller Manager 响应: Deployment Controller 通过 Watch 机制监听 etcd 中 Deployment 对象的变化。当它看到新的 Deployment 对象时,会读取其定义(例如,期望的副本数、Pod 模板)。
  5. Deployment Controller 创建 ReplicaSet: Deployment Controller 根据 Deployment 的定义,创建或更新一个 ReplicaSet 对象,同样将其存储到 etcd 中。ReplicaSet Controller 会被这个变化触发。
  6. ReplicaSet Controller 创建 Pods: ReplicaSet Controller 监听到新的 ReplicaSet 对象,发现当前集群中没有对应数量的 Pods,于是根据 ReplicaSet 中包含的 Pod 模板,创建指定数量的 Pod 对象,并将其存储到 etcd 中。这些新创建的 Pods 此时处于 Pending 状态,并且还没有被分配到任何节点。
  7. Scheduler 调度 Pods: Scheduler 通过 Watch 机制监听 API Server,发现新的 Pending 状态的 Pods。对于每一个 Pending Pod,Scheduler 启动调度流程,根据其资源需求、亲和性规则、节点负载等因素,选择一个最合适的节点。
  8. Scheduler 绑定 Pod 到节点: Scheduler 通过调用 API Server,更新选定 Pod 对象的定义,将其 nodeName 字段设置为选定的节点名称。API Server 将此更新写入 etcd。
  9. Kubelet 启动 Pod: 目标工作节点上的 Kubelet 通过 Watch 机制监听 API Server,发现有一个 Pod 被分配给了自己(nodeName 匹配该节点)。Kubelet 读取 Pod 的详细定义。
  10. Kubelet 与 Container Runtime 交互: Kubelet 指示该节点上的 Container Runtime (例如 containerd):
    • 拉取 Nginx 容器镜像(如果本地没有)。
    • 根据 Pod 定义创建并启动容器。
    • 配置 Pod 的网络和存储卷。
  11. Kubelet 报告状态: Kubelet 监控 Pod 中容器的运行状态,并通过 API Server 持续更新 Pod 的状态(例如从 Pending 变为 Running)和节点的状态。API Server 将这些状态写入 etcd。
  12. Endpoints Controller 更新 Endpoints: 如果用户同时创建了 Service 来暴露 Nginx 应用,Endpoints Controller 会监听到新的 Running 状态的 Nginx Pods,并获取它们的 IP 地址和端口。它会更新与 Service 关联的 Endpoints 对象,将这些 Pod 的地址添加到列表中。
  13. Kube-proxy 更新网络规则: 工作节点上的 Kube-proxy 监听到 Endpoints 对象的变化。它会在本节点的网络中配置相应的转发规则 (iptables 或 IPVS),使得访问该 Service 的流量能够被正确地路由到这些 Nginx Pods 上。

至此,Nginx Pod 成功启动并在工作节点上运行,并且可以通过 Service 访问。如果某个 Nginx Pod 意外终止,ReplicaSet Controller 会监测到 Pod 数量减少,并重复上述步骤 6-11 来启动一个新的 Pod,从而维持期望的副本数。这就是 Kubernetes 的自动化和自我修复能力的体现。

其他重要组成部分 (Add-ons)

虽然不属于核心控制平面或工作节点组件,但在生产级的 Kubernetes 集群中,以下组件或概念也是不可或缺的,它们通常作为 Add-ons 部署:

  • DNS (如 CoreDNS): 为集群内部 Service 提供 DNS 服务发现能力,使得应用可以通过 Service 名称相互访问。
  • 容器网络接口 (Container Network Interface, CNI): 一个规范,定义了容器运行时如何调用网络插件来配置容器的网络。CNI 插件负责实现跨节点 Pod 之间的网络连通性(提供 Pod IP 地址、路由等)。常见的 CNI 实现包括 Flannel, Calico, Cilium, Weave Net 等。Kubelet 在启动 Pod 时会调用 CNI 插件。
  • 容器存储接口 (Container Storage Interface, CSI): 一个规范,定义了容器编排系统(如 Kubernetes)如何调用存储插件来提供块存储或文件存储给容器。CSI 插件负责存储卷的创建、删除、挂载、卸载等操作。
  • 指标收集与监控 (Metrics Server, Prometheus, Grafana): 用于收集节点和 Pod 的资源使用指标,为 HPA (Horizontal Pod Autoscaler) 和 VPA (Vertical Pod Autoscaler) 提供数据源,也用于集群的监控和故障排查。
  • 日志收集 (EFK Stack – Elasticsearch, Fluentd, Kibana 或 Loki, Promtail, Grafana): 用于收集集群中所有 Pod 和节点产生的日志,并将其集中存储和分析。
  • Dashboard: Kubernetes 官方提供的 Web UI,方便用户查看集群资源、管理应用等。
  • Ingress Controller: 负责管理集群外部对 Service 的访问,通常作为反向代理和负载均衡器。

这些 Add-ons 极大地扩展了 Kubernetes 的功能,使其成为一个完整的云原生应用平台。

Kubernetes 架构的设计原则与优势

Kubernetes 架构的设计遵循了几个重要的原则,这些原则赋予了它强大的能力:

  1. 松耦合与模块化: 各个组件相对独立,通过 API Server 进行通信。这使得组件可以独立开发、升级和替换,提高了系统的灵活性和可维护性。
  2. 声明式 API: 用户通过 YAML/JSON 文件描述期望的集群状态(例如,“我想要运行 3 个 Nginx Pods”),而不是一步步的操作指令。控制平面通过控制循环持续地将当前状态调整到期望状态。这简化了管理,并使得系统具有自我修复能力。
  3. 分布式与高可用: 核心组件(如 API Server, etcd, Controller Manager, Scheduler)都可以以分布式的方式运行,以实现高可用性,避免单点故障。
  4. 可扩展性: Kubernetes 提供了丰富的扩展点,例如 CRI, CNI, CSI 接口,自定义资源定义 (Custom Resource Definitions, CRD) 等,允许用户或第三方集成自己的实现或扩展 Kubernetes 的功能。
  5. 自动化与自我修复: 通过各种控制器和控制循环,Kubernetes 能够自动处理许多常见的运维任务,如故障 Pod 的重启、节点故障时的 Pod 迁移、扩缩容等。

这些设计原则共同构成了 Kubernetes 强大、可靠且灵活的基石,使其成为容器编排领域的领导者。

结论

Kubernetes 的架构是一个精心设计的分布式系统,由控制平面和工作节点上的众多协同组件组成。API Server 作为核心枢纽,etcd 作为单一事实来源,Scheduler 负责智能调度,Controller Manager 通过控制循环维护期望状态,而工作节点上的 Kubelet、Kube-proxy 和 Container Runtime 则负责执行具体的应用运行和网络功能。

理解这些核心组件的角色、功能以及它们之间如何通过声明式 API 和 Watch 机制协同工作,是掌握 Kubernetes 的关键。尽管其内部机制可能显得复杂,但正是这种复杂性带来了强大的自动化、弹性、可扩展性和自我修复能力。通过这些组件的有机结合,Kubernetes 成功地解决了大规模容器化应用的部署和管理挑战,为构建现代化的、弹性的微服务架构提供了坚实的基础。希望本文能帮助您更深入地理解 Kubernetes 的内部工作原理,更好地利用这一强大的平台。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部