生产集群运维——升级、备份、故障排查与容量规划
把 Kubernetes 集群跑起来是第一步,让它在生产环境中长期稳定运行才是真正的挑战。版本升级、etcd 备份恢复、节点维护、故障排查、容量规划——这些 Day-2 运维场景,每一个都有足以让集群中断服务的操作风险。Kubernetes 为这些场景提供了明确的工具和流程约定,但操作顺序和细节上的失误仍然是生产事故的主要来源。 版本升级是最高风险的操作之一。Kubernetes 的 API 在版本间存在兼容性约束(skew policy),错误的升级顺序——例如先升级 kubelet 而非先升级 control plane——会导致集群进入不一致状态,轻则调度异常,重则 API Server 无法与节点通信。etcd 备份看似简单,但备份时机(必须在升级前)、恢复流程(必须停止 API Server 再恢复)、验证方式(恢复后检查关键对象)如果有任何一步出错,都可能导致数据丢失或集群无法启动。 节点维护(drain + upgrade + uncordon)有 PodDisruptionBudget(PDB)这道安全网,但前提是 PDB 本身配置正确。容量规划需要理解"...
可观测性——Metrics、Logging、Tracing 的集群实践
一个运行在 Kubernetes 上的分布式系统,出问题时最难回答的问题是"发生了什么"。单机时代,登录服务器查看进程状态和日志文件,基本能还原现场。容器化之后,Pod 随时可能被调度到不同节点,崩溃后立即重启,原始日志消失,这套方法彻底失效。可观测性(Observability)是对这个问题的系统性回答:通过在系统内部埋点、采集、存储和展示三类信号——Metrics(指标)、Logging(日志)、Tracing(链路追踪)——让工程师在不登录服务器的情况下理解系统行为。 Kubernetes 本身对可观测性有明确的架构分工。采集点(kubelet 内嵌的 cAdvisor、node-exporter DaemonSet、应用 SDK)由各组件负责暴露,聚合层(Prometheus、metrics-server)负责拉取和存储,展示层(Grafana、Jaeger UI)负责查询和可视化。这种"采集点内建、存储和展示留给生态"的设计,让 Kubernetes 本身保持简洁,同时允许不同规模的集群选择不同的存储方案。 理解可观测性的关键区分...
Helm 与应用打包——从 YAML 到可复用制品
在 Kubernetes 上部署一个生产级应用,往往需要几十个甚至上百个 YAML 文件:Deployment、Service、ConfigMap、Ingress、RBAC 规则、HorizontalPodAutoscaler……这些文件之间存在依赖关系,不同环境(开发、预发、生产)需要不同参数,手工管理极易出错。Helm 正是为了解决这个问题而生:把一组相关的 Kubernetes 资源打包成一个可版本化、可参数化、可共享的制品(Chart),并提供安装、升级、回滚、卸载的生命周期管理。 Helm 的本质是"带版本历史的 YAML 打包器"。它不追踪资源的真实运行状态(那是 Operator 的职责),只记录"这次 install/upgrade 渲染出了哪些 manifest,交给 Kubernetes 执行"。Release 状态存储在集群内的 Secret 对象中(key 为 helm.sh/release.v1),每次升级都新增一个版本,rollback 本质上是重新 apply 旧版本的 manifest 集合。 理解 Helm...
CRD 与 Operator 模式——扩展 Kubernetes 的标准路径
Kubernetes 的核心设计哲学之一是可扩展性。API Server 内置的资源类型——Pod、Deployment、Service——只能覆盖通用计算模型,但现实中的应用远不止于此:数据库集群有自己的主从切换逻辑,消息队列有 topic 副本的分配策略,机器学习训练任务有 GPU 亲和性和检查点管理。CustomResourceDefinition(CRD)和 Operator 模式正是 Kubernetes 给出的扩展机制:让用户把领域知识编码进集群本身,而不是写在外部脚本或运维手册里。 CRD 的核心能力是向 API Server 注册新的 Group/Version/Kind(GVK)。注册完成后,kubectl get myapp 和 kubectl get pod 在 API 层面对等——同样走 REST 接口,同样存储到 etcd,同样支持 watch、label selector 和 RBAC 授权。Operator 在 CRD 之上再加一层:部署一个 Controller,持续监听自定义资源的变化,把用户声明的期望状态翻译成若干内置 Kubernetes 资...
资源管理与自动伸缩:requests、limits、HPA 与 VPA
安全模型控制谁能做什么,资源管理控制能用多少。这两个维度共同决定了集群的多租户能力。requests 和 limits 是 Kubernetes 资源模型的基础,理解它们的精确语义是做好容量规划的前提。HPA 和 VPA 在此基础上提供了自动化的弹性能力。 在传统物理机和虚拟机时代,资源隔离靠硬件分区或 hypervisor,资源弹性靠人工扩容。Kubernetes 把资源管理内置为一等公民,通过 cgroup 在内核层面强制执行,通过控制器实现自动化弹性。这一篇的核心问题是:requests 和 limits 如何影响调度和运行时行为,HPA 和 VPA 如何根据负载自动伸缩? 资源模型全景 1234567891011121314151617181920212223242526调度时(kube-scheduler) ┌────────────────────────────────────────────────────────────┐ │ Node Allocatable = Node Capacity - System Reserved │ │ ─...
RBAC 与安全模型:认证、授权与准入控制
密钥只有在有效的访问控制下才有意义。Kubernetes 的安全控制分三层:认证(谁在访问)、授权(能做什么)、准入控制(允许什么操作)。三层各有职责,缺一不可。 在单体应用时代,安全通常集中在网络边界和数据库访问控制。容器化和微服务之后,工作负载数量激增,身份变得复杂:一个 Pod 就是一个独立的执行主体,可能需要读取 Secret、调用其他服务、操作集群资源。Kubernetes 的安全模型由哪三个层次组成、RBAC 的 Role/RoleBinding/ClusterRole/ClusterRoleBinding 如何组合使用,是本篇的核心内容。 三层安全模型 12345678910111213141516171819202122232425262728293031323334请求到达 API Server │ ▼┌──────────────────────────────────┐│ 1. Authentication(谁?) ││ ──────────────────────────── ││ X.509 cert → U...
配置与密钥管理:ConfigMap、Secret 与外部集成
存储体系解决了持久化数据问题。配置和密钥是另一类需要与 Pod 生命周期解耦的数据:应用配置(数据库地址、功能开关)和敏感信息(密码、API Key、TLS 证书)不应该打包到镜像里,因为不同环境配置不同,密钥也需要独立的访问控制。 十二因素应用(The Twelve-Factor App)把"配置"定义为在不同部署(开发、测试、生产)之间存在差异的东西,并要求配置必须与代码严格分离。Kubernetes 的 ConfigMap 和 Secret 是这个原则的原生实现。ConfigMap 和 Secret 如何把配置注入 Pod、外部密钥管理系统(Vault、AWS Secrets Manager)如何与 Kubernetes 集成,是本篇覆盖的内容。 配置注入全景 12345678910111213141516171819202122232425 ┌──────────────────────────────────────────┐ │ Kubernetes API ...
存储体系:PV、PVC、StorageClass 与 CSI
前几篇建立了计算(Pod 调度和运行)和网络(Pod 间通信和服务发现)的模型。有状态应用(数据库、消息队列、对象存储)需要持久化存储,Pod 重启后数据不丢失。Kubernetes 通过 PV/PVC/StorageClass 三层抽象解耦了存储的供应和使用。 在虚拟机时代,存储通常由运维工程师手动挂载:NFS 目录、SAN LUN、本地磁盘,挂载路径硬编码在部署脚本里。容器化之后,Pod 随时可能漂移到不同节点,存储和计算的生命周期必须显式解耦。Kubernetes 的回答是引入三个层次:PV(实际存储的抽象)、PVC(应用的存储需求声明)、StorageClass(动态供应的策略工厂)。PV/PVC 的绑定机制和 CSI 驱动如何让外部存储系统成为 K8s 的一等公民,是本篇的核心内容。 CSI(Container Storage Interface)的出现解决了 in-tree 驱动的历史包袱。此前,每个云厂商、每个存储系统都要向 Kubernetes 主代码库提交驱动代码,升级路径混乱且周期漫长。CSI 定义了一套 gRPC 接口,任何存储厂商都可以编写独立的驱动程序,...
架构总览:Broker、Controller 与元数据管理
上一篇确立了追加日志是 Kafka 的核心抽象。这一篇展开这根日志运行在什么样的集群架构上。 一个常见的简化说法是"Kafka 是一组 broker"。更准确的描述是:Kafka 集群由若干 broker 进程组成,其中一个 broker 承担 controller 角色,负责元数据管理和 partition leader 选举。 本文只抓一个问题:从 topic 到磁盘目录,数据和元数据分别如何组织。 Broker:存储日志并服务读写请求 Broker 是 Kafka 集群中的工作进程。每个 broker 做两件事: 存储分配给它的 partition 的日志文件(.log、.index、.timeindex)。 服务 produce 请求(追加记录到日志尾部)和 fetch 请求(按 offset 从日志中读取记录)。 一个 broker 可以同时持有多个 topic 的多个 partition。每个 partition 在磁盘上是一个独立的目录,目录名格式为 {topic名}-{partition号}。 1234567891011broker-0 ...
Ingress 与 Gateway API:七层流量的入口演进
Service 把集群内部的流量调度问题解决了,但把服务暴露到集群外部的 HTTP/HTTPS 流量需要另一层抽象。NodePort 和 LoadBalancer 都在四层工作——它们能把外部 TCP 流量转发进来,但无法根据 HTTP 的 Host 头或 URL 路径做路由决策,也无法终止 TLS、做 URL 重写、实现金丝雀发布。Ingress 就是 Kubernetes 为七层 HTTP 路由设计的原生对象,它在 1.1 版本进入 alpha,1.19 版本 GA,至今仍是绝大多数集群的 HTTP 入口方案。 Ingress 的设计在简单场景里非常直观:声明哪个 host + 哪个路径对应哪个 Service,TLS 证书放在 Secret 里引用,一个 Controller(Nginx、Traefik、HAProxy 等)负责把这些规则翻译成实际的反向代理配置。这套模型在业务不复杂时运作良好,但当需要金丝雀发布、基于请求头的路由、跨命名空间的服务暴露、gRPC 原生路由时,规范本身的表达能力不够,各家 Controller 用 annotation 扩展——结果是注解的命...
