第二章:深入 Kubernetes(K8s) 的世界:核心概念与组件
在第一章中,我们了解了 K8s 的诞生背景、其核心价值以及声明式管理理念。现在,是时候揭开 K8s 这座“智能机器人”的内部构造了。
我们将从 K8s 的基本组成单位开始,逐步认识那些协同工作,共同支撑你的应用程序稳定运行的关键概念。
2.1 K8s 的“骨架”:集群 (Cluster)
K8s 并非单台机器就能运行,它是一个由多台服务器组成的集群 (Cluster)。
你可以将这个集群想象成一个大型的、统一的计算资源池,K8s 负责在这个池子里高效地管理你的应用程序。
一个典型的 K8s 集群包含两种主要类型的节点——主节点和工作节点。
2.1.1 主节点 (Master Node) / 控制平面 (Control Plane):集群的“大脑”
主节点是 K8s 集群的“大脑”和“指挥中心”。它负责管理整个集群,调度应用程序,响应用户请求。所有与 K8s 集群的交互,都是通过主节点进行的。
主节点默认不会运行用户应用程序(因为带有 NoSchedule
污点),但也可以通过去除调度限制,让其承担部分工作负载。
在 Kubernetes 架构中,主节点存在以下关键模块,用于协调和管理整个集群:
- API Server: 这是 K8s 集群的“门面”和“前端接口”。所有与 K8s 集群的通信(无论是来自用户、CLI 工具还是其他组件)都通过 API Server 进行。它验证请求、处理数据,并将集群状态信息持久化。
- etcd: K8s 集群的“记忆库”或“数据库”。它是一个高可用、强一致性的键值存储系统,用于保存 K8s 集群的所有配置数据、状态信息以及元数据。etcd 的稳定性对整个 K8s 集群至关重要。
- Scheduler (调度器): 负责将新创建的 Pod(我们稍后会介绍)调度到集群中合适的“工作节点”上。调度器会根据资源需求(CPU、内存)、可用性、策略约束等因素,选择最佳的运行节点。
- Controller Manager (控制器管理器): K8s 的“巡逻员”。它包含一系列控制器,持续监控集群的当前状态,并尝试将其驱动到用户期望的“声明式”状态。例如,如果某个应用程序副本数量不足,ReplicaSet Controller 就会启动一个新的 Pod。
通常我们会分别在三台以上机器上部署 控制平面节点 (Control Plane Node) 形成高可用的控制平面集群。如果所有控制平面节点都故障(宕机或不可访问),Worker Node 上现有运行着的 Pod 通常还会继续运行(只要 Worker Node 和 kubelet 本身正常),直到节点重启或容器异常。kubelet 也会尽力维持其节点上现有 Pod 的运行状态(例如重启崩溃的容器)。但是,整个集群将丧失核心管理能力: 无法创建新的 Pod(包括替换因节点故障丢失的 Pod)、无法进行任何调度(如扩容、新建 Deployment 等)、无法更新应用配置、也无法进行跨节点的故障自愈(如 Worker Node 宕机后在其他节点重建 Pod)。此外,服务发现和网络规则可能随着时间推移变得过时或不稳定。因此,控制平面的高可用性至关重要。
💡 提示: Kubernetes 采用的是声明式、控制循环架构,控制面组件主要负责将“用户想要的状态”不断与“实际运行状态”对比并调整。如果控制面崩溃了,这种调整机制将暂时停止,但已运行的容器并不会立刻终止。
2.1.2 工作节点 (Worker Node):集群的“四肢”
工作节点是 K8s 集群中真正运行应用程序(容器)的机器。它们是集群的“执行者”,接收来自主节点的指令,并负责容器的生命周期管理。每个工作节点上都运行着以下核心组件:
- Kubelet: 这是运行在每个工作节点上的“代理”,也是一位合格的程序“监察官”。它负责与 API Server 通信,接收主节点的指令,并确保节点上的容器按照 Pod 规范运行。Kubelet 会监控 Pod 的状态,并向 API Server 报告。
- Kube-proxy: K8s 的“网络代理”——节点网络的守门员。它负责为 K8s 中的 Service(服务)实现网络代理和负载均衡功能。它会根据 Service 的定义,在节点上配置网络规则,确保对服务的请求能够正确路由到后端 Pod。
- 容器运行时 (Container Runtime): 这是真正执行容器、管理容器生命周期的软件。例如,我们熟知的 Docker、containerd 或 CRI-O 都属于容器运行时。Kubelet 会通过容器运行时来启动、停止、删除容器以及管理容器的镜像。它是 Pod 中应用程序得以运行的基石。
2.2 K8s 的“居民”:Pod——应用程序的最小单位
如果说 K8s Node 是容器世界的管理者,那么 K8s Pod 就是容器世界的合法公民。
在 K8s 集群中,你的应用程序(容器)并非直接运行在工作节点上,而是被封装在一个名为 Pod 的抽象层中。
Pod 是 K8s 中最小的可部署和可调度的计算单元。
- 容器的“家”:一个 Pod 最常见的是包含一个应用程序容器。但在一些特定的、需要紧密协作的场景下,一个 Pod 也可以包含多个容器。这些容器必须紧密耦合,并需要共享某些资源(最典型的是网络命名空间 - 共享 IP 和端口,以及存储卷 - 允许容器间共享文件)。
- 共享资源: 同一个 Pod 内的所有容器共享相同的网络命名空间(即它们共享一个 IP 地址和端口空间)和存储卷。它们可以像在同一台机器上一样通过
localhost
互相通信。 - 短暂性: Pod 被设计为相对短暂的。如果一个 Pod 崩溃或其所在的节点出现故障,K8s 会自动创建并启动一个新的 Pod 来替代它,而不会尝试“修复”旧的 Pod。这意味着 Pod 是可替换的,不应存储持久性数据。
2.3 K8s 的“自动化管家”:Deployment——管理 Pod 的“生产线”
哎~,说到底现在还是只能手动管理 Pod 的创建与运行,说好的自动化管理呢?
咱们继续往下看——这不就来了?
手动管理大量的 Pod 显然是不现实的。为了实现 Pod 的自动化部署、扩展和更新,K8s 引入了 Deployment 这个概念。
- 管理一组 Pods: Deployment 负责管理一组相同 Pod 的‘副本’。你只需声明你希望运行多少个 Pod 副本,Deployment 通过创建和管理 ReplicaSet 对象,就会确保集群中始终有这么多数量的 Pod 在运行。
- 弹性伸缩: 当应用程序负载变化时,你可以轻松修改 Deployment 中的 Pod 副本数量,K8s 会自动进行扩容(增加 Pod)或缩容(减少 Pod)。
- 无缝更新与回滚: Deployment 提供了强大的更新策略,最常用的是滚动更新 (Rolling Update)。这意味着当你发布新版本的应用程序时,K8s 会逐步替换旧版本的 Pod,确保服务在更新过程中不中断。如果新版本出现问题,Deployment 也支持快速回滚到上一个稳定版本。
- 自愈能力: 如果 Deployment 管理的 Pod 发生故障,它会自动替换掉故障 Pod,维持所需的副本数量。
2.4 K8s 的“联系方式”:Service——应用程序的稳定入口
Pod 的 IP 地址是动态的,当 Pod 被 K8s 重启、替换或重新调度时,它们的 IP 地址会发生变化。这使得外部用户或集群内的其他应用程序难以稳定地访问到这些 Pod。这时,Service 就发挥了作用。
- 稳定的网络入口: Service 为一组 Pod 提供了一个固定且稳定的网络入口(通常是一个固定的 IP 地址和端口)。无论其背后 Pod 的 IP 地址如何变化,Service 的地址都不会变。
- 负载均衡: 当一个 Service 关联了多个后端 Pod 时,它会自动将进入的请求均匀地分发到这些 Pod 上,实现负载均衡。这确保了单个 Pod 不会被请求压垮,提高了应用程序的可用性。
- 服务发现: K8s 内部的服务发现机制允许其他 Pod 通过 Service 的名称来访问它,而无需知道具体的 IP 地址。这使得应用程序间的通信更加灵活和解耦。
- 多种类型: Service 有多种类型,以适应不同的访问需求。
- ClusterIP: 默认类型,Service 只能在 K8s 集群内部被访问。
- NodePort: 通过每个工作节点上的特定端口,将 Service 暴露给集群外部。
- LoadBalancer: 在支持 Kubernetes 服务集成的云环境中,使用此类型会由云供应商自动创建并配置一个外部负载均衡器,并将流量路由到 Service,从而提供公网或 VPC 内的访问能力。在非云环境或缺乏集成时,此类型可能无法自动生效或需要额外解决方案。