Appearance
K8s 架构与核心组件(面试高频)
一、一句话定位
Kubernetes 是容器编排系统:把多台机器抽象成统一资源池,声明式地管理容器化应用的部署、扩缩容、调度、自愈与滚动更新。
两个关键字:
- 声明式(Declarative):你给"期望状态"(YAML),K8s 负责把"实际状态"逼近期望,而非一步步命令式操作。
- 控制器 + 调谐循环(Reconciliation Loop):
observe → diff → act,不断对比期望/实际并纠正,这是 K8s 自愈能力的来源。
二、整体架构:控制平面 + 工作节点
控制平面(Control Plane)
| 组件 | 职责 |
|---|---|
| kube-apiserver | 集群唯一入口,所有读写都经它;认证/授权/准入控制;是无状态的水平扩展点 |
| etcd | 唯一的持久化数据源(键值库),保存整个集群状态;高可用需奇数节点(Raft 共识) |
| kube-scheduler | 决定 Pod 调度到哪个节点(过滤 + 打分) |
| kube-controller-manager | 运行各种控制器(Deployment/ReplicaSet/Node/Endpoint…),持续把实际状态调谐到期望 |
| cloud-controller-manager | 对接云厂商(负载均衡、云盘、节点生命周期) |
工作节点(Node)
| 组件 | 职责 |
|---|---|
| kubelet | 节点上的"代理/管家",管理本节点 Pod 生命周期,向 apiserver 汇报;调用容器运行时启停容器 |
| kube-proxy | 维护节点网络规则(iptables/IPVS),实现 Service 的 VIP 与负载均衡转发 |
| 容器运行时(CRI) | 真正跑容器的:containerd(主流)、CRI-O;Docker 因 CRI 支持被弃用(dockershim 移除) |
关键点:所有组件都只与 apiserver 对话(watch/list),彼此不直连;组件多是无状态控制器——这就是 K8s 可扩展、可分布的原因。
三、核心对象模型(速览)
- Pod:最小调度单元(一个或多个共享网络/存储的容器)。
- ReplicaSet / Deployment:副本管理与发布。
- Service / Ingress:服务发现与流量入口。
- ConfigMap / Secret:配置与密钥注入。
- Volume / PV / PVC:存储。
- Namespace:逻辑隔离。
- ServiceAccount / RBAC:身份与权限。
- Node:一个工作机器。
四、一次 kubectl apply -f deployment.yaml 发生了什么?(经典追问题)
kubectl把 YAML 发给 apiserver;apiserver 认证(AuthN) → 授权(AuthZ,RBAC) → 准入(Admission,如 LimitRange/校验) 后写入 etcd。- Deployment 控制器(在 controller-manager 里)watch 到新对象,创建对应的 ReplicaSet。
- ReplicaSet 控制器 watch 到后,创建期望数量的 Pod 对象(此时 Pod 还没有节点,
nodeName为空)。 - kube-scheduler watch 到未调度 Pod,执行过滤 + 打分,选定节点后回写
nodeName(绑定)。 - 目标节点的 kubelet watch 到"分配给我的 Pod",调用容器运行时拉镜像、建容器、配网络(CNI)、挂卷,启动后上报状态。
- kube-proxy 更新 Service 转发规则;若 Pod 就绪(readiness 通过),EndpointSlice 更新,流量进入。
- 控制器持续调谐:Pod 挂了就重建,保持副本数。
这道题能讲清"声明式 + 控制器 + watch 机制 + 调度 + kubelet 执行"整条链路,就非常加分。
五、为什么这么设计(设计动机类追问)
- 为什么所有组件都经 apiserver,不互相直连? 统一入口便于认证/授权/审计;组件解耦;apiserver 可水平扩展(它把状态存 etcd)。
- 为什么要 etcd? 强一致(Raft)、watch 机制天然适配"状态变化通知",是声明式调谐的基础。
- 为什么控制器是"调谐循环"而不是"一次性执行"? 容错——任何组件/网络故障后,重新 observe 就能自愈;这正是云原生"自愈/自愈式运维"的根。
- 为什么用声明式? 便于幂等、版本化(GitOps)、回滚与审计。
六、etcd 相关高频
- 作用:存集群所有状态(对象、配置、端点)。丢了 etcd ≈ 丢了集群。
- 可用性:Raft 多数派,故部署奇数节点(3/5);容忍 (n-1)/2 故障。
- 性能:写放大、fsync 是瓶颈;大集群要注意 event 压缩、定期 defrag、limit 数量。
- 备份:
etcdctl snapshot save,灾难恢复必备。
七、高频速答
Q:apiserver 是无状态的吗? A:逻辑上无状态——所有持久化在 etcd,所以可以多实例水平扩展。
Q:kubelet 和 kube-proxy 区别? A:kubelet 管Pod 生命周期(让容器跑起来);kube-proxy 管网络转发规则(让 Service 通)。
Q:没有调度器会怎样? A:Pod 会一直 Pending(除手动指定 nodeName)。调度只是"选节点",不负责启动。
Q:控制平面挂了一会,业务还转吗? A:已在节点上运行的 Pod 由 kubelet 维持,流量照跑;但无法新建/调度/自愈,恢复后补调谐。