【AI 总结】What is Kubernetes?
What is Kubernetes? | AI 总结
一、Kubernetes 核心概念与价值
- 定义:开源容器编排系统,最初由 Google 开发,现由 Cloud Native Computing Foundation(CNCF)支持,用于在集群环境中管理容器化应用。
- 核心目标:提供可预测性、可扩展性和高可用性,全生命周期管理容器化应用与服务,支持应用扩缩容、滚动更新、版本切换(测试 / 回滚)等操作。
- 用户价值:用户可定义应用运行规则与交互方式,通过灵活的接口和平台原语,实现对应用的可靠管理,无需直接处理底层容器调度细节。
二、Kubernetes 架构
Kubernetes 采用分层架构,核心是 “集群”,由两类角色的服务器组成,各角色分工明确:
| 服务器类型 | 功能定位 | 核心职责 |
|---|---|---|
| Master Server(主服务器) | 集群 “大脑与网关” | 1. 暴露 Kubernetes API 供用户 / 客户端交互; 2. 监控节点健康状态; 3. 调度工作负载(分配任务); 4. 协调组件间通信(容器编排) |
| Node Server(节点服务器) | 集群 “工作节点” | 1. 接收主服务器的工作指令; 2. 运行容器化应用(需安装容器运行时,如 Docker、rkt); 3. 调整网络规则,实现流量路由与转发 |
- 底层基础:集群由物理 / 虚拟机通过共享网络组成,应用以容器形式运行在节点上,主服务器确保 “应用期望状态” 与 “集群实际状态” 一致。
- 用户交互方式:通过 Kubernetes API 服务器(直接或借助客户端如 kubectl)提交 JSON/YAML 格式的 “声明式计划”,主服务器解析计划并在基础设施上执行。
1. 节点服务器(Node Server):可以有多个
- 核心作用:它们是集群的 “体力劳动者”,负责运行实际的容器化应用(Pod)。
- 扩展性:Kubernetes 的强大之处就在于它可以管理成百上千个节点服务器。当你的业务量增加时,你可以通过增加 Node 节点来横向扩展集群的计算能力。
2. 主服务器(Master Server):可以是一个,也可以是多个
虽然在基础教程或小型测试集群(如 Minikube)中通常只有一个 Master,但在生产环境中:
- 单个 Master:存在 “单点故障” 风险。如果这台服务器宕机,整个集群的 “大脑” 就瘫痪了,虽然现有的应用(Node 上的容器)可能还会运行,但你无法进行任何调度、更新或管理操作。
- 多个 Master(高可用架构):在生产环境中,通常会部署 3 个或 5 个 Master 服务器组成高可用(High Availability, HA)集群。它们通过算法(如 Etcd 的 Raft 协议)选举出领导者,确保即使其中一台挂了,集群依然能正常运行。
注: 在生产环境中,为了保证高可用性,通常会部署多个 Master Server(形成集群);而 Node Server 的数量则根据业务负载需求动态增减。
三、Master Server 核心组件
主服务器作为控制平面,由 5 个关键组件协同工作,负责集群全局管理:
| 组件名称 | 形象比喻 | 核心职责与功能描述 (技术细节) | 为什么这样拆分? (设计哲学) |
|---|---|---|---|
| etcd | 核心账本 | 轻量级分布式键值存储(CoreOS 开发)。存储集群配置数据、服务发现、集群状态(如 leader 选举、分布式锁)。提供 HTTP/JSON API,支持单节点或生产推荐的多节点分布式部署。 | 状态一致性:将 “数据” 与 “逻辑” 分离。它是集群唯一的 “真实来源”,独立部署确保了即便管理组件重启,集群状态也不会丢失。 |
| kube-apiserver | 行政前台 / 总机 | 集群管理核心入口。实现 RESTful 接口,是组件间通信的桥梁。负责同步 etcd 存储与容器服务信息,执行身份验证、授权及访问控制,维护集群健康。 | 安全与统一:它是唯一直接操作 etcd 的组件。通过这种 “单点访问” 设计,隐藏了底层数据库细节,并强制执行统一的安全准则。 |
| kube-controller-manager | 大堂经理(巡检员) | 控制器管理器。运行各类 “控制器” 以维护工作负载生命周期。例如 “复制控制器” 确保 Pod 副本数与配置一致。它通过 API 服务器监听变更并执行流程以达成 “期望状态”。 | 声明式自动化:它是 K8s 的 “大脑执行器”。拆分出来是为了让系统能自动巡检并修复故障(如:挂了就补、少了就加),无需人工干预。 |
| kube-scheduler | 调度专家 | 工作负载调度器。负责分析工作负载的资源要求(如 CPU / 内存)与节点的当前可用资源,将待处理的任务分配到最合适的节点,避免资源超额分配。 | 决策解耦:调度逻辑往往非常复杂(需考虑亲和性、策略、成本等)。独立拆分允许用户在不影响集群运行的情况下,定制或更换调度算法。 |
| cloud-controller-manager | 外贸专员 | 云服务适配组件。作为 K8s 与云服务商(如阿里云、AWS)的 “胶水”。负责将通用资源(存储、负载均衡)映射到云商实际资源,并同步云端状态到集群。 | 平台中立性:让 K8s 核心代码与特定的云厂商代码解耦。这样 K8s 就能在任何云环境下以同样的方式运行,厂商只需提供适配器。 |
核心对比:kube-controller-manager vs kube-scheduler
| 特性 | kube-controller-manager (大堂经理) | kube-scheduler (调度专家) |
|---|---|---|
| 核心职责 | 管理状态 What:确保集群的 “实际状态” 符合 “期望状态”。 | 分配位置 Where:为待处理的 Pod 选择最合适的 Node(节点)。 |
| 关注对象 | 关注资源副本数、节点健康、服务账户等。 | 关注未调度的 Pod 和各节点的资源余量。 |
| 主要逻辑 | “如果少了,就补上”(控制循环)。 | “这个 Pod 放哪最合适?”(过滤与打分)。 |
| 动作产出 | 创建或删除 Pod 的定义,维护资源对象。 | 将 Pod 的 nodeName 属性更新为选中的节点名。 |
为什么要把它们拆开?(拆分的意义)
1. 复杂度解耦(最核心原因)
- 控制器的逻辑相对简单直接:对比状态 -> 补齐差异。
- 调度器的逻辑极其复杂:需要计算 CPU / 内存、亲和性、污点、容忍度、拓扑分布等。将 “决定做什么” 和 “决定在哪做” 拆分,可以防止单个组件逻辑过于臃肿。
2. 独立扩展与定制化
- Kubernetes 支持多调度器。如果你有特殊需求(如 AI 训练需要特殊的 GPU 调度算法),你可以运行一个自定义调度器,而不需要改动核心的控制器逻辑。
3. 故障隔离与自愈流程
- 流程解耦:当 Controller Manager 补齐一个 Pod 后,这个 Pod 处于
Pending状态。即便此时调度器短时间挂掉,Pod 的记录已经存在于集群中了。 - 职责清晰:控制器负责 “招人”(创建 Pod),调度器负责 “分座位”(分配节点)。如果招了人没座位(Pending),你能立刻锁定是调度环节出了问题。
K8s 核心组件的协作流程(如何联系在一起)
如果把 K8s 集群比作一个自动化工厂,它们的关系如下:
- kube-apiserver 唯一窗口:工厂的 “前台” 和 “公告板”。所有指令、状态更新都必须经过它,并持久化到 etcd 数据库中。
- kube-controller-manager 意图实现者:工厂的 “管理部门”。
- 联系:它监听公告板,发现 “实际状态” 与 “用户期望” 不符时,负责发起改变。
- 任务:比如用户想要 3 个副本,它就负责在公告板上登记 3 个 Pod 的需求。
- kube-scheduler 位置决策者:工厂的 “空间规划师”。
- 联系:它监听公告板上 “待分配” 的 Pod。
- 任务:根据工厂(集群)的剩余空间,在公告板上给 Pod 标好 “建议存放的房间号(Node)”。
- kubelet 一线执行者:工厂每个房间的 “领班”。
- 联系:它只盯着公告板上关于 “自己房间” 的任务。
- 任务:看到有分配给自己的 Pod,就立刻去启动真实的容器。
总结关系图
sequenceDiagram
autonumber
participant User as 用户
participant API as API Server
participant CM as Controller Manager
participant SCH as Scheduler
participant KLT as Kubelet
User->>API: 提交请求 (Create Pod)
Note over API, CM: 监听变更
API->>CM: 逻辑补齐
CM-->>API: 更新状态 (创建 Pod 记录)
Note over API, SCH: 监听变更
API->>SCH: 位置决策
SCH-->>API: 绑定节点 (更新 nodeName)
Note over API, KLT: 监听变更
API->>KLT: 执行落地
KLT-->>API: 更新运行状态
深度理解:平等的协作架构
在 Kubernetes 中,组件之间并不是 “上级下达指令给下级” 的命令式架构,而是围绕 kube-apiserver 展开的声明式协作
1. 核心特征:平等与解耦
- 无直接通信:
kube-controller-manager与kube-scheduler互不隶属,互不通话。 - 中心辐射:所有组件都只与
kube-apiserver通信。它们都是 API Server 的客户端。 - 数据驱动:组件通过 Watch(监听) API Server 的数据变化来决定自己该干什么。
2. 协作模型:黑板模式
- API Server 是 “黑板”:负责记录状态,不处理业务逻辑。
- Controller Manager:负责 “发现差异并填补”。
- 动作:发现副本不够 -> 在黑板上增加 Pod 记录。
- Scheduler:负责 “空间决策”。
- 动作:发现 Pod 没有 Node 信息 -> 在黑板上补全 Node 信息。
3. 这种设计的意义
这种非线性、去中心化的协作方式,使得 K8s 具有极强的可扩展性。你可以运行多个调度器,或者自定义各种控制器,只要它们都遵循 API Server 的规范,就能无缝集成到集群中,而不会破坏现有组件的稳定性。
四、Node Server 核心组件
Node 是 Kubernetes 集群中的 “工作负载机器”,它可以是物理机,也可以是虚拟机(如云服务器)。如果说 Master Server 是集群的 “大脑(指挥中心)”,那么 Node 就是集群的 “四肢(前线工厂)”—— 它们是真正承载并运行 Pod(内部封装了一个或多个容器)的地方。
1. Pod 是 “容器的容器” (封装关系)
- Docker 容器:是一个独立的进程隔离环境,通常一个容器只运行一个应用(如 Nginx)。
- Kubernetes Pod:是 K8s 中最小的调度单元。它更像是一个 “逻辑主机”(Logical Host)。
- 一个 Pod 内部可以包含一个或多个 Docker 容器。
- 这些容器在 Pod 内部共享相同的网络命名空间(IP 和端口)和存储卷(Volumes)。
2. 为什么需要 Pod 而不是直接管理容器?
如果你直接管理 Docker 容器,当两个容器需要极其紧密地协作(比如一个主 Web 容器,一个专门负责收集日志的辅助容器 Sidecar)时,你会发现很难保证它们总是被调度在同一台物理机上,也很难让它们共享网络和磁盘。
Pod 解决了这个问题:
- 共享网络:Pod 里的所有容器都通过 localhost 互相通信,就像在同一台电脑上一样。
- 共同生死:Pod 里的容器会被作为一个整体进行调度和重启。
3. 这里的 “平实” 说法是否准确?
- 对于初学者:可以把 Pod 理解为 “K8s 版本的容器”。
- 对于进阶者:必须意识到 Pod $\neq$ Container。Node 实际上运行的是 Pod,而 Pod 内部由 Container Runtime(如 Docker 或 containerd)启动具体的容器。
节点服务器需安装 3 类组件,确保与主服务器通信、运行容器并管理网络:
| 组件名称 | 核心定位 | 主要职责 | 关键功能 / 示例 |
|---|---|---|---|
| container runtime | 底层引擎 | 负责容器的启动、停止和管理 | Docker, rkt, runc |
| kubelet | 节点 “管家” | 节点与控制平面的通信纽带;管理 Pod 及其容器的生命周期 | 接收清单 (Manifests)、维护工作负载状态、与 etcd 交互 |
| kube-proxy | 网络代理 | 维护节点网络规则;实现服务发现和负载均衡 | 转发请求到正确容器、管理子网、确保网络隔离与访问 |
它们之间的联系:
- 协作关系:
kubelet接收到指令后,会调用 容器运行时 来具体执行容器的创建或销毁;而kube-proxy则在外部请求到达时,确保流量能正确导向由kubelet管理的这些容器中。 - 共同目标:三者共同驻留在每个 Node 节点上,确保容器化应用能被正确调度、运行并实现网络互通。
这里的 “外部请求” 在 Kubernetes 的语境下通常包含两个层面,主要取决于你是站在哪个视角看的:
1. 集群外部的请求 (真正的 “外部”)
这是指来自集群之外的流量,比如:
- 最终用户:用户通过浏览器访问你的网站(流量经过 LoadBalancer 或 NodePort 进入集群)。
- 外部系统:集群外的数据库或第三方 API 回调。
- 入口流量:流量到达 Node 节点的某个端口后,kube-proxy 负责根据转发规则,把这个请求准确地扔给对应的 Pod。
2. Pod 外部的请求 (集群内部的 “横向流量”)
即使是集群内部的通信,对某个具体的 Pod 来说,只要流量跨越了自身的网络命名空间,都可以视为 “外部” 请求。这种流量分发主要由 kube-proxy 在幕后调度:
- 跨 Node 请求:运行在 Node A 上的 Pod 想要访问某个 Service。Node A 上的
kube-proxy会拦截该请求,并根据 Service 定义的规则,将其转发到运行在 Node B(或其他节点)上的后端 Pod。 - Service 抽象层:集群里的服务 A 调用服务 B 时,流量通过 Service 的虚拟 IP(Cluster IP)进行中转。
kube-proxy负责维护各节点上的转发规则(如 iptables 或 IPVS),确保流量能准确命中健康的 Pod 实例。
五、Kubernetes 对象与工作负载
Kubernetes 通过 “对象” 抽象管理容器,避免直接操作容器,核心对象分为 6 类,各有特定用途:
| 对象类型 | 定义与功能 | 适用场景 |
|---|---|---|
| Pods(Pod) | 最小管理单元,封装 1 个或多个 “紧耦合” 容器: - 共享环境、存储、IP 空间,生命周期一致,需调度到同一节点; - 通常包含 “主容器”(核心应用)+“辅助容器”(如文件同步、日志收集)。 |
管理紧密关联的容器组(如 Web 服务 + 日志收集器),不直接用于水平扩缩容(需依赖更高层对象)。 |
| Replication Controllers(复制控制器) | 基于 Pod 模板,管理 “相同副本 Pod” 的水平扩缩容: - 确保 Pod 副本数与配置一致(故障时自动重建); - 支持滚动更新(逐版替换 Pod,减少 downtime)。 |
早期用于实现 Pod 高可用与负载分发,现逐渐被 Replication Sets 与 Deployments 替代。 |
| Replication Sets(复制集) | 复制控制器的升级版本,增强 “Pod 选择灵活性”(支持更复杂的 Pod 匹配规则),但不支持滚动更新,需配合更高层对象使用。 | 作为 Deployments 的底层组件,不建议用户直接管理。 |
| Deployments(部署) | 最常用的高层工作负载对象,基于 Replication Sets 构建: - 支持灵活的生命周期管理(修改配置后自动调整副本集); - 自动维护更新历史、支持故障回滚; - 简化滚动更新操作(无需手动创建新复制控制器)。 |
绝大多数场景下的首选对象,用于管理长期运行的服务类应用(如 Web 服务、API 服务)。 |
| Stateful Sets(有状态集) | 针对 “有状态应用” 的专用控制器,提供 “顺序性与唯一性保障”: - 为每个 Pod 分配固定编号名称(跨节点调度后保持不变); - 支持持久化存储卷(Pod 删除后卷保留,避免数据丢失); - 部署 / 扩缩容按 Pod 编号顺序执行,确保操作可预测。 |
数据库、分布式存储等需稳定标识与持久数据的应用(如 MySQL 集群、Elasticsearch)。 |
| Daemon Sets(守护集) | 在集群所有节点(或指定子集)上运行 1 个 Pod 副本: - 通常用于节点级维护服务,可绕过普通 Pod 调度限制(如在主服务器上运行); - 节点新增时自动部署 Pod,节点删除时自动清理。 |
日志收集(如 Fluentd)、监控数据采集(如 Prometheus Node Exporter)、节点网络插件等。 |
| Jobs & Cron Jobs(任务与定时任务) | - Jobs:管理 “一次性任务”,容器执行成功后退出(非长期运行),支持重试失败任务; - Cron Jobs:基于 Jobs 扩展,按 Linux Cron 调度规则(如每天凌晨 2 点)运行任务,支持未来 / 周期性执行。 |
Jobs:批量数据处理、一次性脚本执行; Cron Jobs:定时备份、周期性报表生成。 |
为了让你更直观地理解这些 Kubernetes(K8s)对象,我们可以把 K8s 集群类比为一个大型连锁超市的管理系统。
1. Pod(容器组):超市里的 “货架标准单元”
- 类比:一个最小的摆放单元(比如一个带冷藏功能的货架)。
- 说明:超市里最小的单位不是一个苹果,而是一个货架。货架里可以只放苹果(主容器),也可以在旁边配一个除味剂(辅助容器 / Sidecar)。它们共享这个货架的空间和电源(网络和存储)。你不会单独搬走一个苹果,要搬就搬整个货架。
2. Replication Controllers (RC) / Replication Sets (RS):超市的 “值班经理”
- 类比:负责点名的人事主管。
- 说明:他的任务很简单:老板说 “生鲜区必须有 3 个货架在工作”,如果其中一个货架坏了,他立刻去仓库调一个新的补上。RS 比 RC 更聪明一点,他不仅能认出 “生鲜货架”,还能通过标签认出 “贴了红标签的生鲜货架”。
3. Deployments(部署):超市的 “运营总部”
- 类比:超市的连锁总部方案。
- 说明:这是你平时用得最多的。总部下达指令:“把所有旧款货架升级成新款”。Deployment 会指挥 “值班经理”(RS)先撤下一个旧货架,换上一个新货架(滚动更新)。如果新货架漏电,总部还能一键下令:“全部换回旧款”(回滚)。
4. Stateful Sets(有状态集):超市里的 “存包柜” 或 “专属办公室”
- 类比:带编号的员工储物柜。
- 说明:普通的货架(Pod)坏了换个新的就行,不分彼此。但有些员工(如会计)需要固定的办公室和保险柜(数据持久化)。StatefulSet 保证会计 1 号永远用 1 号办公室,即使 1 号办公室装修(漂移到其他节点),会计 1 号回来时,他的保险柜和钥匙(数据和标识)依然在那里。
5. Daemon Sets(守护集):超市里的 “安保 / 清洁系统”
- 类比:每层楼必须配备的烟雾报警器或保安。
- 说明:不需要总部算一共要多少个,规则很简单:只要超市开了一层新楼(新增一个节点),这层楼就必须自动装上一个报警器。如果这层楼关了,报警器也跟着撤走。常用于日志收集和监控。
6. Jobs(任务):超市的 “年度大扫除”
- 类比:一次性的装修队。
- 说明:他们进场不是为了长期值班,而是为了干完一件具体的活(比如 “刷墙”)。墙刷好了(程序运行成功),他们就解散领工资,不会一直占着位置。
7. Cron Jobs(定时任务):超市的 “凌晨补货”
- 类比:每天凌晨两点的自动洒水系统。
- 说明:它基于 Job 扩展。它不需要一直运行,而是定好闹钟(比如每天凌晨 2 点),闹钟一响就派出一个 “装修队”(Job)去干活(比如备份数据库、清理垃圾),干完就走。
它们之间的 “组织架构” 联系:
垂直指挥链(最常用的组合):
- 运营总部 (Deployment) 不直接去搬货架,它负责制定 “方案”。
- 总部把方案交给 值班经理 (ReplicaSet) 。
- 值班经理盯着 货架 (Pod) 的数量,坏了就补,多了就撤。
- 如果你要升级,总部会再派一个 “新经理” 带新货架进场,等新经理交接完,旧经理就带着旧货架撤退。
定时触发链:
- 自动洒水 (CronJob) 就像个闹钟,时间一到就给 装修队 (Job) 派发任务单。
- 装修队接到单子,立刻进场摆好 临时货架 (Pod) 开始干活,活干完(程序运行结束)就带着货架撤场。
特殊职能部门:
- 专属办公室 (StatefulSet) 和 每层保安 (DaemonSet) 是独立于普通货架管理的特殊部门,分别解决 “东西不能丢(身份持久化)” 和 “每层楼必须有(节点覆盖)” 的特定需求。
| 对象类型 | 生活类比 | 核心关注点 |
|---|---|---|
| Pod | 货架单元 | 最小的活儿怎么干(装载容器) |
| RS / RC | 值班经理 | 人 / 货够不够(维持副本数) |
| Deployments | 运营总部 | 怎么升级、怎么撤退(版本控制) |
| Stateful Sets | 专属办公室 / 储物柜 | 名字不能变、东西不能丢(身份与持久化) |
| Daemon Sets | 每层保安 / 报警器 | 见楼就上,一个不漏(全覆盖部署) |
| Jobs | 装修队 | 干完就走(一次性任务) |
| Cron Jobs | 自动洒水 | 准时干活(周期性任务) |
在 Kubernetes 中,Replication Controller (RC) 和 ReplicaSet (RS) 都是为了确保在任何时候都有指定数量的 Pod 副本在运行。虽然它们的功能非常相似,但 RS 是 RC 的下一代版本。
以下是它们更具体的区别与联系:
1. 核心区别:选择器(Selector)的灵活性
这是两者最本质的区别。
- Replication Controller (RC):仅支持基于相等(Equality-based)的选择器。
- 它只能匹配包含特定标签的 Pod。例如:env = dev 或 tier = frontend。
如果需要同时匹配多个条件,只能通过逻辑 “与” 完成。
- 它只能匹配包含特定标签的 Pod。例如:env = dev 或 tier = frontend。
- ReplicaSet (RS):支持基于集合(Set-based)的选择器。
- 这使得它比 RC 强大得多。它支持 In、NotIn、Exists 等操作。
- 示例:它可以选择标签 env 为 production 或 qa 的 Pod(env in (production, qa)),或者选择具有某个标签但不关心其值的 Pod。
- 这种灵活性在处理复杂的部署策略或多版本共存时非常有用。
2. 滚动更新(Rolling Updates)
- Replication Controller (RC):在早期的 K8s 中,RC 确实支持通过 kubectl rolling-update 命令进行滚动更新。但这是一个客户端操作,意味着如果你的终端断开了,更新可能会卡在中间状态。
- ReplicaSet (RS):RS 本身不支持滚动更新命令。它的设计初衷是作为一个纯粹的 “副本维持器”。滚动更新的功能被移交给了更高层级的对象 ——Deployment。Deployment 通过管理多个 RS(一个旧版本 RS,一个新版本 RS)来实现平滑的滚动更新,这是服务端操作,更加健壮和自动化。
3. 历史地位与现状
- 联系:ReplicaSet 是 Replication Controller 的直接继承者。它们的核心逻辑(维持副本数、监控 Pod 状态、故障自愈)是完全一致的。
- 区别:
- RC 现在被认为是遗留技术。除非是为了兼容非常老的集群,否则在新创建的资源中几乎不再使用 RC。
- RS 虽然比 RC 先进,但 Kubernetes 官方强烈建议不要直接管理 RS。
4. 总结:它们与 Deployment 的关系
在现代 Kubernetes 实践中,关系链如下:
- Deployment(高层抽象):负责定义更新策略(滚动更新、回滚)。
- ReplicaSet(中间层):负责确保 Pod 的副本数量符合预期,并利用 “集合选择器” 精确筛选 Pod。
- Pod(最小单元):实际运行的容器。
一句话总结:RC 是旧时代的产物,RS 是具备更强筛选能力的升级版;但在实际工作中,我们通过 Deployment 来间接使用 RS,而完全弃用 RC。
是的,你的理解完全正确。简单来说:
- RS 是 RC 的升级版:它们的核心职责完全一样(都是保证 Pod 副本数量),但 RS 引入了更强大的 标签选择器(Label Selector),支持集合运算(如 In, NotIn),而 RC 只能做相等的简单匹配。
- RC 是为了兼容性:在 Kubernetes 的演进过程中,为了不破坏那些还在运行老版本配置的集群,RC 被保留了下来。但在新的项目和现代的 K8s 教程中,RC 已经很少被提及了。
- 实际使用中的微妙之处:
- 虽然 RS 取代了 RC,但在日常操作中,我们几乎从不直接手动创建和管理 RS。
- 我们一般会直接定义 Deployment。当你创建一个 Deployment 时,它会自动为你创建一个 RS。
- Deployment 负责更高层的逻辑(如回滚、暂停更新),而生成的 RS 负责底层具体的副本维护。
总结一下:如果你在写新的 YAML 配置文件,永远不要使用 RC。虽然 RS 是它的升级版,但你应该直接使用 Deployment,让 Deployment 去帮你管理 RS。
六、其他关键 Kubernetes 组件
除工作负载外,Kubernetes 提供 3 类核心抽象,解决网络、存储与对象组织问题:
1. Kubernetes Services(服务)
- 定义:内部负载均衡器与 Pod “大使”,将执行同一功能的 Pod 逻辑分组,对外暴露稳定端点。
- 核心价值:
- 内部消费者只需访问 Service 的固定 IP,无需关注后端 Pod 的动态变化(如扩缩容、替换);
- 支持 Pod 发现与基础负载均衡,简化容器间通信设计。
- 外部访问方式:
- NodePort:在每个节点的外部网络接口开放静态端口,外部流量通过该端口路由到内部 Service;
- LoadBalancer:借助云服务商集成,创建外部负载均衡器(由 cloud-controller-manager 配置),直接路由到内部 Service。
1. 核心定义
- Pod:最小的运行单元。它像是一个容器的 “豌豆荚”,里面运行着一个或多个容器(通常是一个应用容器)。Pod 是短暂的,重启或销毁后 IP 会变。
- Deployment:管理者(控制器)。你通常不直接创建 Pod,而是创建一个 Deployment。它负责定义 Pod 的副本数量、镜像版本,并确保 Pod 始终按预期运行(例如:Pod 挂了,Deployment 会自动起一个新的)。
- Service:访问入口(大使)。由于 Pod 的 IP 经常变动,Service 提供了一个固定的虚拟 IP。它通过 “标签选择器(Label Selector)” 找到一组 Pod,并将流量负载均衡地分发给它们。
2. 三者之间的逻辑关系
可以用以下公式概括:Deployment 管理 Pod,Service 暴露 Pod。
第一层:Deployment -> Pod(隶属与管理关系)
- 如何关联:Deployment 在配置中定义了 template(Pod 模板)和 replicas(副本数)。
- 作用:Deployment 保证了 Pod 的高可用和版本回滚。如果你更新了 Deployment 的镜像,它会逐步销毁旧 Pod 并创建新 Pod。
第二层:Service -> Pod(发现与负载均衡关系)
- 如何关联:Service 使用 selector 匹配 Pod 的 labels。
- 作用:Service 解决了 “如何找到 Pod” 的问题。无论 Deployment 如何调度、重启或增减 Pod,Service 的 IP 始终不变。它是 Pod 的 “大使”,负责把外部或内部的请求转发到后端健康的 Pod 上。
在 Kubernetes 中,NodePort 和 LoadBalancer 是将服务暴露给集群外部流量的两种主要方式。
1. 工作原理对比
- NodePort (节点端口)
- 原理:在集群的每个节点(Node)上开启一个相同的静态端口(通常在 30000-32767 之间)。外部流量通过访问
任意节点IP:NodePort即可进入集群。 - 特点:它是最基础的外部访问方式,不依赖云厂商。但客户端需要管理节点 IP,且端口管理较为繁琐。
- 原理:在集群的每个节点(Node)上开启一个相同的静态端口(通常在 30000-32767 之间)。外部流量通过访问
- LoadBalancer (负载均衡器)
- 原理:在
NodePort的基础上,配合云服务商(如 AWS、阿里云等)创建一个外部负载均衡器。负载均衡器拥有独立的公网 IP。 - 特点:外部流量访问负载均衡器的 IP,由它自动将请求分发到各个节点的 NodePort。它是生产环境的首选,提供了单一入口和更高的可用性。
- 原理:在
2. 核心区别
| 特性 | NodePort | LoadBalancer |
|---|---|---|
| 访问入口 | 节点 IP + 静态端口 | 独立的公网 IP |
| 云平台依赖 | 无需,通用 | 需要云服务商支持 |
| 管理复杂度 | 需手动管理节点 IP 分发 | 自动管理,对客户端透明 |
| 安全性 | 暴露节点 IP,风险相对较高 | 隐藏节点细节,更安全 |
| 成本 | 免费(消耗集群资源) | 需支付云商负载均衡器费用 |
3. 适用场景建议
- NodePort:适用于本地开发测试、私有云环境,或在资金受限、不需要固定公网入口的场景。
- LoadBalancer:适用于公有云上的生产环境,需要稳定公网 IP 和自动化流量分配的场景。
2. Volumes & Persistent Volumes(存储卷)
| 存储类型 | 定义与生命周期 | 适用场景 |
|---|---|---|
| Volumes(普通存储卷) | 与 Pod 生命周期绑定,Pod 内所有容器共享数据,Pod 删除后卷销毁;解决 Pod 内容器间数据共享问题。 | Pod 内多容器数据交换(如主容器生成日志,辅助容器收集日志)。 |
| Persistent Volumes(持久化存储卷) | 与 Pod 生命周期解耦,由管理员提前配置集群级存储资源,用户通过 “Persistent Volume Claims(PVC)” 申请使用;支持 “回收策略”(手动删除 / 自动清理)。 | 需跨 Pod 生命周期保留数据的场景(如数据库数据、用户上传文件),避免节点故障导致数据丢失。 |
这是一个非常经典且关键的 Kubernetes (K8s) 基础概念问题。简单来说:Pod 不等于容器,Pod 是容器的 “容器”(或者说载体)。
1. Pod vs 容器 的关系
在 Kubernetes 中,Pod 是最小的可部署单元,而不是容器。
- 你可以把 Pod 想象成一个 “房间”:这个房间里可以只住一个人(一个容器),也可以住多个人(多个容器)。
- 容器(Container):是运行在 Pod 里面的具体进程。
2. 什么叫 “Pod 内容器共享数据”?
当一个 Pod 内部运行了多个容器时,它们之间有着非常亲密的关系:
- 网络共享:它们共享同一个 IP 地址和端口空间。容器 A 可以通过 localhost:port 直接访问容器 B。
- 存储共享(Volumes):这就是你看到的文档提到的内容。Pod 可以定义一个 “存储卷(Volume)”,然后同时挂载到这个 Pod 里的多个容器中。
举个例子(Sidecar 模式),假设你有一个应用:
- 主容器(Main Container):运行你的业务代码,它会把日志写到 /var/log/app.log。
- 辅助容器(Logging Sidecar):专门负责收集日志。
如果你给 Pod 配置了一个 Volume(比如叫 log-data),你可以让:
- 主容器把 log-data 挂载到它的 /var/log。
- 辅助容器也把 log-data 挂载到它的 /data/logs。
结果:主容器写下的日志,辅助容器立刻就能在自己的目录里读到。这就是所谓的 “Pod 内容器共享数据”。
3. 为什么不直接把所有东西写在一个容器里?
虽然可以这么做,但 K8s 提倡 “一个容器只做一件事”:
- 解耦:业务逻辑和日志收集逻辑分开,方便维护和复用。
- 资源隔离:可以单独限制每个容器的 CPU 和内存。
- 重启策略:如果日志收集器挂了,K8s 可以只重启它,而不影响主业务。
总结:你看到的文档里提到的 Volumes 解决的就是:当一个 Pod 里有多个 “小伙伴”(容器)时,大家如何通过同一个 “抽屉”(存储卷)来交换文件。如果你的 Pod 里永远只有一个容器,那么这种 “共享” 确实体现不出来,但 K8s 的设计允许并鼓励在复杂场景下使用多容器协作。
3. Labels & Annotations(标签与注解)
- Labels(标签):
- 键值对形式的 “语义标签”,用于给对象分组,支持筛选与匹配(如控制器通过标签识别管理的 Pod,Service 通过标签路由到后端 Pod);
- 规则:每个对象可多个标签,但同一键只能有一个值,常见标签如 “name(名称)”“env(环境:dev/prod)”“version(版本)”。
- Annotations(注解):
- 键值对形式的 “元数据”,存储非筛选用途的信息(如构建版本、运维联系方式、工具配置);
- 区别于标签:不用于对象选择,仅用于补充描述,数据格式更灵活(可包含结构化 / 非结构化信息)。
Labels(标签) 和 Annotations(注解) 虽都是键值对形式的元数据,但其核心用途不同:
Labels(标签):标识、分组与筛选
- 核心作用:用于标识资源的特征,是 Kubernetes 资源管理(如选择器 Selector)的基础。
- 使用场景:
- 控制器关联:
Deployment或ReplicaSet通过标签识别并管理属于它们的Pod。 - 服务发现:
Service通过标签选择器(Selector)定位后端Pod集群,实现负载均衡。 - 多维度组织:
- 环境区分:
env: dev,env: prod。 - 架构分层:
tier: frontend,tier: backend。 - 版本控制:
release: stable,release: canary。
- 环境区分:
- 调度策略:通过
nodeSelector或亲和性配置,让 Pod 运行在特定标签的节点(如disktype: ssd)。
- 控制器关联:
Annotations(注解):元数据记录与工具配置
- 核心作用:存储非标识性的辅助信息,供外部工具、控制器或运维人员阅读,不支持筛选。
- 使用场景:
- 外部工具配置:如 Ingress 配置路由规则(
nginx.ingress.kubernetes.io/rewrite-target),或 Prometheus 抓取指标配置。 - 审计与溯源:记录镜像构建时间、Git Commit ID、发布人联系方式等。
- 复杂数据存储:由于注解值没有严格长度限制,可存储结构化数据(如 JSON 配置)。
- 外部工具配置:如 Ingress 配置路由规则(
对比总结
| 特性 | Labels(标签) | Annotations(注解) |
|---|---|---|
| 主要目的 | 标识和筛选对象 | 存储辅助 / 非筛选信息 |
| 筛选支持 | 支持(Selector) | 不支持 |
| 字符限制 | 严格限制(通常 63 字符内) | 较少限制,可存储大文本 |
| 典型用户 | K8s 核心组件(调度、控制器) | 外部工具、插件、运维人员 |
七、结论
Kubernetes 通过分层架构、组件化设计,解决了容器化应用的大规模管理难题,提供灵活、可靠的容器编排能力,是云原生开发的核心工具。尽管其架构与组件初期学习成本较高,但凭借开源生态与强大功能,成为企业级容器管理的首选方案。用户可结合 DigitalOcean 的托管服务与教程,快速上手 Kubernetes 并部署云原生应用。
graph TD
%% 用户交互
User[用户 / kubectl] --> APIServer[kube-apiserver <br/>统一入口]
%% Master 控制平面
subgraph Master [Master Server - 控制平面]
APIServer --- Etcd[etcd <br/>核心账本]
APIServer --- CM[kube-controller-manager <br/>控制器管理器]
APIServer --- SCH[kube-scheduler <br/>调度专家]
end
%% 工作负载逻辑
subgraph Objects [工作负载对象]
Deploy[Deployment <br/>运营总部] --> RS[ReplicaSet <br/>副本管理]
RS --> Pod[Pod <br/>最小单元]
SS[StatefulSet <br/>有状态应用] --> Pod
DS[DaemonSet <br/>守护进程] --> Pod
Job[Job/CronJob <br/>任务] --> Pod
end
%% 节点运行
subgraph Node [Node Server - 工作节点]
KLT[kubelet <br/>节点管家]
CR[Container Runtime <br/>容器引擎]
KP[kube-proxy <br/>网络代理]
KLT --> CR
CR --> Container[容器]
end
%% 核心关系连接
APIServer -- 指令 --> KLT
CM -- 监控状态 --> APIServer
SCH -- 分配节点 --> APIServer
Pod --- Container
%% 网络与存储
Service[Service <br/>服务/负载均衡] -- 筛选标签 --> Pod
Pod --- Vol[Volumes <br/>存储卷]
%% 元数据
Label[Labels 标签] -.-> Service
Label -.-> RS
Label -.-> SCH
%% 样式
style Master fill:#f9f9f9,stroke:#f66
style Node fill:#f0f7ff,stroke:#007bff
style Pod fill:#fff,stroke:#28a745