Appearance
K8s 基础概念
Kubernetes 把容器化应用放到多台机器上统一调度、发布和维护。Docker 解决单个容器怎么运行,Compose 解决单机多容器怎么组织,Kubernetes 处理的是多节点、多副本、多服务长期运行时的调度、网络、存储、配置、发布和故障恢复。
编排的本质——声明期望状态
Kubernetes 是容器编排平台。"编排"不是帮忙启动容器那么简单,它的核心动作是:提交期望状态,控制器持续把集群实际状态调整到期望状态。
| 场景 | Kubernetes 负责的部分 |
|---|---|
| 多副本 Web/API | 调度 Pod、维护副本数、滚动发布 |
| 服务发现 | Service 提供稳定访问入口,Pod IP 变化不影响调用方 |
| 节点故障 | 节点异常后,控制器在其他节点重建副本 |
| 配置分发 | ConfigMap、Secret 挂载或注入到容器 |
| 资源约束 | requests、limits、QoS、驱逐策略 |
| 发布治理 | 滚动更新、回滚、蓝绿、金丝雀 |
| 可观测性 | 事件、日志、指标、审计 |
K8s 把调度、服务发现、配置挂载、滚动更新这些动作标准化了,但应用自身的启动逻辑、健康检查、数据一致性、数据库迁移、连接池配置仍然是应用和运维一起处理的——平台提供能力,不替代应用设计。
集群结构——控制平面和工作节点
一个集群分成控制平面和工作节点两部分:
| 部分 | 作用 |
|---|---|
| 控制平面 | 接收 API 请求,保存状态,调度工作负载,维护期望状态 |
| 工作节点 | 运行 Pod,拉镜像,挂载卷,处理节点网络和容器生命周期 |
kube-apiserver 是所有组件交互的唯一入口。kubectl、scheduler、controller-manager、kubelet 都通过 API Server 读写资源对象,没有任何组件绕过它直接操作 etcd。etcd 是状态库,正常运维操作不直接改 etcd。
核心组件
| 组件 | 所在位置 | 作用 | 常见问题 |
|---|---|---|---|
kube-apiserver | 控制平面 | API 入口 | 证书过期、认证失败、请求延迟高 |
etcd | 控制平面 | 保存集群状态 | 磁盘慢、快照、quorum 丢失、数据恢复 |
kube-scheduler | 控制平面 | 给 Pending Pod 选择节点 | 资源不足、污点、亲和性、PVC 未绑定 |
kube-controller-manager | 控制平面 | 运行各种控制器 | 副本不补、节点状态更新异常 |
kubelet | 每个节点 | 管理 Pod 和容器状态 | 镜像拉取、挂载失败、探针失败 |
containerd / CRI-O | 每个节点 | 容器运行时 | 镜像、容器创建、运行时日志 |
kube-proxy | 每个节点 | Service 转发规则 | iptables/IPVS、Service 不通 |
| CNI 插件 | 每个节点 | Pod 网络 | Pod 无 IP、跨节点不通、策略异常 |
etcd 的地位要单独记住。控制平面节点可以重建,Pod 可以重建,etcd 数据丢了就等于集群所有对象状态丢了。生产集群里 etcd 快照、证书有效期、磁盘延迟是固定巡检项。
声明式 API 和控制循环
K8s 的基本动作不是"执行一次命令",而是"提交期望状态,控制器持续调和":
把 Deployment 副本数从 2 改到 5,实际发生的步骤:
| 步骤 | 说明 |
|---|---|
修改 spec.replicas | API Server 接收新期望状态 |
| Deployment 控制器发现差异 | 当前副本数少于期望副本数 |
| 创建新 Pod | 新 Pod 进入 Pending |
| scheduler 选择节点 | 写入 Pod 绑定信息 |
| kubelet 创建容器 | 节点拉镜像、挂载卷、启动进程 |
这个模型也解释了为什么排错要分层。API 是否接收对象、控制器是否创建对象、调度是否成功、kubelet 是否创建容器、应用是否健康——五个不同阶段,排查入口和日志来源完全不同。
资源对象——spec 和 status
Kubernetes 不直接操作"进程",而是操作资源对象。常见对象:
| 对象 | 说明 |
|---|---|
| Namespace | 命名空间,资源分组和权限范围 |
| Pod | 最小调度单元,一个或多个容器的组合 |
| Deployment | 管理无状态副本和滚动更新 |
| StatefulSet | 管理有状态副本,提供稳定网络身份和存储 |
| DaemonSet | 每个节点跑一个 Pod(日志采集、监控 Agent、CNI) |
| Service | 稳定访问入口,不随 Pod IP 变化 |
| ConfigMap | 普通配置 |
| Secret | 敏感配置 |
| Ingress / Gateway | 七层入口规则 |
| PV / PVC / StorageClass | 存储抽象 |
资源对象的通用结构:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: demo
labels:
app: web
spec:
replicas: 2 # 期望副本数
selector:
matchLabels:
app: web # 控制器用 selector 找 Pod
template:
metadata:
labels:
app: web # Pod 标签必须和 selector 对上
spec:
containers:
- name: nginx
image: nginx:1.26
status:
# status 由控制器维护,平时不手工编写spec 是期望状态,status 是当前状态。这个区别贯穿整个 Kubernetes——用户写 spec,控制器写 status。
标签和 selector——资源关联的核心
Kubernetes 里很多关系靠 label 和 selector 连接,不靠固定 IP:
| 关系 | 关联方式 |
|---|---|
| Deployment → Pod | spec.selector.matchLabels 匹配 Pod labels |
| Service → Pod | spec.selector 匹配 Pod labels |
| NetworkPolicy → Pod | podSelector 匹配 Pod labels |
| ServiceMonitor → Service | selector 匹配 Service labels |
| Pod → PVC | claimName 引用 PVC 名称 |
| Ingress/Gateway → Service | backend 引用 Service 名称和端口 |
标签设计混乱带来的问题很隐蔽:Service 没后端、Deployment 管不到 Pod、监控抓不到目标、NetworkPolicy 错误拦截。标签不是装饰字段,它是资源关系的主要连接方式。
K8s 的边界——什么能处理,什么处理不了
| K8s 能处理 | 说明 |
|---|---|
| 副本数维护 | Pod 少了补,多了缩 |
| 调度 | 按资源、污点、亲和性选择节点 |
| 服务发现 | Service 和 DNS 提供稳定访问入口 |
| 配置挂载 | ConfigMap、Secret 注入容器 |
| 滚动发布 | 分批替换 Pod |
| 基础自愈 | 容器退出后重启,节点故障后重调度 |
| K8s 处理不了 | 现场表现 |
|---|---|
| 应用启动逻辑错误 | CrashLoopBackOff |
| 数据库一致性 | Pod 重启不等于数据恢复 |
| 镜像 tag 混乱 | 同名 tag 在不同节点指向不同内容 |
| 连接池过大 | 扩副本后数据库连接数打满 |
| 外部依赖故障 | Pod Running,但接口超时 |
| 存储后端故障 | PVC Bound,但挂载或 IO 异常 |
Kubernetes 适合无状态服务、批处理任务、节点级采集组件和可水平扩展的应用。有状态服务也能跑,但存储、备份、升级顺序和故障切换需要单独设计——StatefulSet 提供稳定身份,不提供高可用方案。