Kubernetes 是一套分布式控制平面与节点代理协同工作的系统,核心在于各组件基于 etcd 状态异步对齐;API Server 是唯一可信入口,负责认证、鉴权与准入控制,绕过它将导致状态撕裂。

Kubernetes 不是“一个软件”,而是一套协同工作的分布式控制平面 + 节点代理系统;它本身不运行容器,而是调度、约束、观测和修复容器的生命周期。
API Server 是集群唯一可信入口,所有操作都必须过它
你执行 kubectl get pods、CI/CD 流水线调用 curl -X POST 创建 Deployment、甚至 Helm install 的底层请求,最终都打到 kube-apiserver。它不做业务逻辑判断,只做三件事:认证(如 RBAC)、鉴权(如 ClusterRoleBinding)、准入控制(如 ValidatingWebhook)。绕过它直接改 etcd 或伪造 kubelet 心跳,会导致状态撕裂——比如 Pod 显示 Running,但实际容器已退出且不会重启。
- 常见错误现象:
Forbidden: unable to create new content in namespace "default"—— 不是权限没配全,很可能是 ServiceAccount 没绑定 Role,或命名空间被限制了资源配额 - 实操建议:调试时优先看
kube-apiserver日志(journalctl -u kube-apiserver -n 100),而不是先查 Pod 状态;它的 403/404 错误比 kubelet 的 CrashLoopBackOff 更早暴露权限链路问题 - 性能影响:开启大量动态准入(如 OPA/Gatekeeper)会显著增加 API 延迟,生产环境建议仅对关键资源(Pod/Ingress/Secret)启用
etcd 不是“K8s 的数据库”,而是整个集群状态的单一事实源
etcd 存的不是“数据”,而是“期望状态”与“当前状态”的差值快照。比如你 apply 一个 Deployment,kube-apiserver 写入的是 replicas: 3 和 label selector;Controller Manager 后续读取这个值去比对真实 Pod 数量,再触发创建。删掉 etcd 里某条 key,相当于告诉系统“这个资源从未存在过”——Deployment 控制器会立刻删光所有关联 Pod。
- 容易踩的坑:用
etcdctl get --prefix /registry手动清理“残留”key,可能意外删除正在使用的 Lease 或 EndpointsSlice,导致服务中断 - 备份要点:必须使用
etcdctl snapshot save(而非文件系统 cp),且恢复时要严格匹配 etcd 版本;K8s 1.25+ 集群若用旧版 etcd 快照恢复,可能出现storage version mismatch - 为什么不能换数据库:etcd 的 Raft 协议保证线性一致性,而 MySQL/PostgreSQL 无法在分布式写入下满足 Controller Manager 对“状态变更顺序”的强依赖
kube-scheduler 和 kube-controller-manager 实际上是“状态对齐引擎”
它们不“启动容器”,也不“连网络”。kube-scheduler 只负责给 Pending 状态的 Pod 打上 nodeName: 字段;真正拉起容器的是 kubelet。同理,kube-controller-manager 中的 ReplicaSet 控制器,只是不断 GET /apis/apps/v1/replicasets → 计算副本数差值 → PATCH Pod 数量 → 等待 kubelet 回报新状态。整个过程没有“命令下发”,只有“声明式状态轮询”。
- 典型故障场景:节点磁盘满导致 kubelet 停止上报状态 → Controller Manager 仍认为该节点健康 → 新 Pod 被持续调度过去 → 全部 Pending
- 参数差异:
--controllers=*默认启用全部控制器,但云厂商插件(如 AWS EBS CSI)常要求禁用service控制器,否则会和 cloud-controller-manager 冲突 - 为什么不能合并?调度(决策)和控制(执行)分离是 K8s 可扩展性的根基——你可以用 Karpenter 替换默认 scheduler,但不用动 controller-manager 一行代码
kubelet 不是“Docker 守护进程替代品”,而是 Pod 生命周期的本地仲裁者
kubelet 的核心职责是:确保节点上运行的容器集合,精确匹配 API Server 中对应 Node 对象的 status.conditions 和 PodSpec。它不管理镜像拉取策略(那是 containerd 的事),也不处理跨节点服务发现(那是 kube-proxy 或 CNI 插件的事)。当你看到 ContainerCreating 卡住,大概率是 kubelet 在等 containerd 返回 CreateContainer 响应;而 ImagePullBackOff 则说明它已把拉镜像指令发给了运行时,但运行时失败了。
- 调试技巧:直接执行
crictl ps -a查看容器真实状态,比kubectl describe node更快定位是否是 runtime 层面卡死 - 兼容性注意:K8s 1.24+ 彻底移除 dockershim,若仍用 Docker Engine,必须额外部署
cri-dockerd;containerd 则需确认plugins."io.containerd.grpc.v1.cri".registry配置了私有仓库证书 - 最易忽略的一点:kubelet 的
--node-labels参数一旦设置,节点上线后就无法通过 kubectl label 修改——因为 label 已写入 Node 对象的 immutable 字段,只能删节点重建
真正让 Kubernetes “活起来”的,从来不是某个组件多强大,而是所有组件只基于 etcd 中极简的状态字段做异步对齐——这种松耦合设计,既是它可扩展的底气,也是排障时最烧脑的根源:问题永远不在单点,而在状态流转的缝隙里。










