Kubernetes核心组件与调度原理:从架构到实战排障全解析

发布时间:2026/10/15 7:03:37
Kubernetes核心组件与调度原理:从架构到实战排障全解析 Kubernetes这个名词这几年算是被念叨烂了。但真正上手之后你会发现网上讲原理的教程不少能讲清楚“它为什么这么设计”的却不多。我当年刚接触云原生架构那阵子光看官方文档看得一头雾水直到亲手搭了一套集群、把一个个核心组件拆开再拼回去才对Kubernetes原理有了实感。这篇内容不是复读官方概念我想以实操过的视角把Kubernetes原理和核心组件拆开揉碎讲明白它解决什么问题、内部怎么协作、出故障时怎么排查。适合正在学云原生、准备考认证、或者刚接手集群运维的同学看完能对整套系统建立一张清晰的地图。1. 为什么非要Kubernetes从“一人运维”到“调度一切”1.1 云原生落地的核心矛盾先想一个问题你已经用了Docker容器能打包环境、秒级启动看起来挺美好为什么还要引入Kubernetes这套重量级系统我见过不少团队卡在这一步。用Docker Compose管理三五台机器还行一旦规模上来问题就变味了容器挂了谁来拉起流量来了往哪些实例转发版本升级怎么做到不停机机器宕机了工作负载怎么漂移这些问题本质上是分布式系统编排问题不是容器本身能解决的。Kubernetes的核心价值在于把“怎么运行容器”这件事从人肉运维变成了声明式管理。你告诉它“我要3个副本、每个副本用这个镜像、暴露8080端口”剩下的调度、自愈、滚动更新、水平伸缩都由系统自己完成。这就是云原生架构里最常说的“以应用为中心”。1.2 组件多不等于乱先建立一张全局图Kubernetes之所以劝退新手很大程度是因为组件太多。其实整体逻辑可以用一句话概括一个集群分成控制面和数据面控制面负责决策数据面负责干活。控制面就是常说的Master节点上跑的那组进程包括kube-apiserver、etcd、kube-scheduler、kube-controller-manager。数据面就是所有Worker节点上的kubelet、kube-proxy以及真正跑容器的容器运行时。这套架构和大部分分布式系统没有本质区别一个中心化的“大脑”做决策一群“手脚”去执行。理解了这个模型再去看每个组件就不会觉得是一堆零散的零件而是一条完整的链路。提示控制面组件可以多副本高可用部署但数据面一定是在每个节点上各跑一个这是架构层面决定的不是部署习惯问题。2. 控制面四大件K8s的“大脑”到底在忙什么2.1 kube-apiserver所有请求唯一的入口任何对Kubernetes的操作无论是kubectl命令、控制器调谐、还是节点上报心跳最终都要打到kube-apiserver上。它扮演的角色是统一网关状态校验器。你执行一条kubectl apply -f deployment.yaml实际发生的事是kubectl把YAML的内容以HTTPS请求发给apiserverapiserver先做认证你是谁、再鉴权你能不能干这事、然后过准入控制比如Pod安全策略、资源配额校验全部通过后才把数据交给后端存储。我踩过的一个坑刚搭集群时开了TLS认证但证书没配全kubectl能连上但执行任何写操作都报403。当时第一反应是RBAC权限没配好排查了半天才发现是证书里的用户组和RBAC绑定对不上。所以建议遇到权限问题先按顺序查“证书是否有效-用户是否能被识别-RBAC是否授权”能省很多时间。2.2 etcd集群状态的“唯一真相”etcd是整个集群的“数据库”所有API对象——Pod、Service、Deployment、ConfigMap——都以键值对的形式存在这里。Kubernetes没有自己的存储层所有状态全部依赖etcd。这里要理解一个关键点etcd存的是“期望状态”不是“当前状态”。比如你声明了3个副本etcd里存的是“replicas: 3”这个期望值至于现在实际跑了几Pod、哪个节点上的Pod挂了这些都是控制器和kubelet上报后由apiserver写入etcd的。生产环境里etcd出问题往往是灾难性的因为它直接影响apiserver的读写。我维护过一套集群某次磁盘IO飙升导致etcd读写延迟从毫秒级涨到几百毫秒结果整个集群的Pod调度、心跳上报全部变慢用户感知就是服务持续抖动。关于etcd有几个实操经验值得分享一定要做定期快照备份。etcdctl snapshot save配合定时任务至少每天一次最好异地保存。别等数据丢了再后悔。etcd对磁盘延迟极其敏感SSD是刚需机械盘跑etcd就是给自己埋雷。不要直接通过etcdctl修改Kubernetes的数据。我有次想“手动”改某个Pod的标签绕过了apiserver直接写etcd结果因为格式不合规范控制器根本认不到这个变更。后来规则改成任何状态变更必须走apiserveretcd只做备份和灾备恢复。2.3 kube-scheduler给Pod找个合适的“家”scheduler的任务很单一Watch到新创建的Pod没有绑定节点的就为它选一个最合适的节点然后更新Pod的nodeName字段。但“最合适”这三个字背后的算法并不简单。调度过程分两步过滤和打分。过滤阶段把不满足硬性条件的节点剔除比如节点资源不足、端口冲突、节点上有污点而Pod不能容忍、节点标签不满足nodeSelector要求等。这个阶段是“一票否决”任何一个条件不满足就直接排除。打分阶段对剩下的节点按优先级排序综合考量CPU和内存的剩余量、镜像是否已经在节点上镜像本地存在能省去拉取时间、Pod分布是否均匀等因素。得分最高的节点胜出。我实际调优时最常用的是自定义打分权重。比如集群里有些机器是本地SSD有些是普通磁盘如果希望把IO敏感型应用优先调度到SSD节点可以通过给节点打标签设置nodeAffinity来影响调度结果而不是靠运气的默认策略。新手容易混淆的是scheduler只是决定Pod放在哪个节点不负责真正启动Pod。它更新完nodeName字段后任务就结束了后续流程由目标节点上的kubelet接手。2.4 kube-controller-manager让现实向期望收敛的“纠偏员”如果说etcd存的是“期望状态”那controller-manager就是负责让“当前状态”不断逼近“期望状态”的执行者。它内部跑着几十个独立控制器每个控制器只负责一类资源。最典型的是Deployment控制器。它的逻辑可以用一个循环描述从etcd读期望的副本数比如3。从etcd读当前实际运行的Pod数比如2。发现不相等于是创建或删除ReplicaSet让Pod数回到3。回到第1步重复。这个循环就是Kubernetes里最核心的调谐循环Reconcile Loop。我见过好多同学不理解为什么删掉一个Pod它会马上被重新拉起——因为控制器一直在“盯着”期望值和实际值的差值只要发现偏差就纠正。这不是什么神奇魔法而是一个朴素的反馈控制回路。调试控制器常见的问题是你改了Deployment的镜像版本但Pod迟迟不更新。这时大概率是控制器出了问题。排查方法很直接kubectl get deploy -n kube-system | grep controller找到控制器Pod的日志看看Reconcile循环是否报错。另一个要点是控制器日志里如果出现“informer cache not synced”通常是apiserver连接异常因为控制器的数据来源是监听apiserver的变化而不是直接查数据库。3. 工作节点三件套真正干活的都在这里3.1 kubelet节点的“大管家”每个Worker节点上都有一个kubelet进程它是节点上最核心的代理。kubelet的本职工作是三件事从apiserver接收Pod清单、确保Pod里的容器真的在跑、定期上报节点状态。很多初学者以为kubelet负责“启动容器”这个说法不够准确。准确的流程是kubelet拿到了Pod定义后会调用容器运行时接口CRI去创建容器。至于创建哪种类型的容器Docker、containerd等kubelet不关心它只认CRI这个统一接口。实际操作中有一个很经典的排查场景节点状态变成NotReady。这时先别急着重启节点按这个顺序查systemctl status kubelet看进程是否活着。journalctl -u kubelet -f看kubelet日志里报什么错。检查节点磁盘空间是否写满——kubelet对磁盘压力极其敏感磁盘85%以上就会开始驱逐Pod90%以上可能直接把节点标记为NotReady。检查容器运行时是否正常因为kubelet依赖CRI去拉镜像和启动容器。我遇到过的比较隐蔽的问题/var/lib/kubelet目录的磁盘和根目录是分开挂载的根目录剩余空间正常但这个目录被日志写满了kubelet反复报“DiskPressure”Pod被驱逐还找不到原因。排查节点问题一定要把系统盘、容器数据盘、日志盘分开看。3.2 kube-proxy流量转发的“隐形路由器”kube-proxy解决了Service的访问问题。简单说当你创建一个Service它会有个虚拟IPClusterIP但Pod的IP是随时变化的怎么把访问ClusterIP的流量转发到后端Pod这就是kube-proxy的工作。它的实现机制有三种模式userspace古老现在基本淘汰、iptables默认且最常见、IPVS大规模集群推荐。iptables模式利用Linux内核的iptables规则做DNAT把访问ClusterIP的流量改写为目标Pod的IP。我在生产环境里的一个建议几百个Service以内iptables没问题上千个Service时iptables规则会变得非常庞大每次更新规则都是一次全量刷新耗时急剧上升。这时候切到IPVS模式能明显缓解性能问题。切换方式是修改kube-proxy的启动参数--proxy-modeipvs注意要确保节点上装了ipvsadm工具和内核模块。这里有个新手容易踩的坑kube-proxy只负责Service的VIP流量转发不负责Pod到Pod的直接通信那是CNI插件的事、也不负责DNS解析那是CoreDNS的事。很多人在排障时觉得“Service不通就是kube-proxy坏了”其实有可能是后端的Pod本身就没了或者iptables规则被其他软件改动过。3.3 容器运行时绕不开的CRI与containerdkubelet通过CRIContainer Runtime Interface和容器运行时交互。这个接口的存在让Kubernetes不必绑定某一种具体运行时只要实现CRI规范就行。最早大家用Docker作为运行时但Docker本身不是为Kubernetes设计的中间还隔了一层dockershim适配器。后来社区直接把dockershim移除现在主流运行时基本是containerd或CRI-O。实操中值得注意的差异containerd的命令行工具是ctr和crictl很多人习惯用docker ps看容器但节点上并没有Docker的情况下是无法用docker命令的。我建议所有Kubernetes集群运维者尽快习惯crictl的用法因为它是Kubernetes视角下的标准调试工具。crictl ps、crictl logs、crictl inspect这几个命令足够覆盖绝大多数容器排查场景。注意用crictl查到的Pod ID和容器ID跟docker ps的结果不是同一套体系别拿docker命令去查containerd管理的容器查不到是正常的不是出问题了。4. 一次Pod调度全流程从kubectl到容器启动到底经历了什么4.1 请求写入etcd声明式API的核心把各组件都过了一遍之后我们再来看一次完整的Pod创建流程把这些组件串成一条线。这个流程如果你能完整口述出来Kubernetes原理这块基本就过关了。你执行kubectl apply -f nginx.yaml文件里声明了一个Deployment期望副本数是3。这条命令首先由kubectl把YAML解析成JSON格式然后通过HTTPS请求发送给apiserver。apiserver收到请求后按顺序做四件事TLS认证、用户鉴权、准入控制、写入etcd。这里尤其要注意准入控制这个环节——很多看似“诡异”的行为其实发生在这一步。比如你创建Pod时没有指定资源配额某个准入控制器会自动填上默认值再比如你用了某个镜像仓库地址镜像加签校验控制器可能会直接拒绝。排障时如果发现Pod能创建但状态很奇怪先查apiserver的审计日志看看准入阶段发生了什么。写入etcd成功之后apiserver返回响应给kubectl此时Deployment这个对象已经存在了。但请注意此刻还没有任何容器被创建。etcd里只是多了一条记录Pod的“实际运行”这事还没发生。4.2 调度与绑定scheduler如何打分选节点Deployment对象写入etcd后Deployment控制器立刻通过Watch机制感知到了这个变化。它发现期望副本数是3而当前没有任何Pod于是创建了一个ReplicaSet对象ReplicaSet控制器又发现没有足够的Pod于是创建了3个Pod对象。这3个Pod对象被写入etcd时它们的nodeName字段是空的。scheduler通过Watch看到了这些“未绑定节点”的Pod于是进入调度流程。调度器先跑一遍过滤算法把不满足条件的节点剔除再跑打分算法对剩余节点打分。比如Pod声明了CPU请求为500毫核而某个节点剩余CPU只有300毫核这个节点在第一轮就被过滤掉了。如果某个节点上已经缓存了nginx镜像它在打分阶段会获得额外加分。最终得分最高的节点被选中scheduler通过apiserver更新Pod的nodeName字段——这个动作叫“绑定”。这里我想多说一句调度的结果不只是“选个节点”这么简单它直接决定了后续所有环节的表现。节点资源碎片化、Pod分布不均匀、关键应用和CPU密集型任务被调度到同一台机器这些都是调度不当引发的长期问题。生产环境里值得花时间设计好节点标签和亲和性策略。4.3 kubelet执行拉镜像、创建沙箱、启动容器目标节点上的kubelet通过Watch发现了一个nodeName指向自己的Pod于是开始执行。首先是调用CRI接口通知容器运行时创建“Pod沙箱”Pod Sandbox——在containerd场景里这就是一个安全的隔离环境。然后是拉取镜像如果节点本地已经有这个镜像就直接复用没有才从仓库拉取。镜像拉完创建业务容器并启动。启动之后还有一个容易被忽略的环节健康检查。如果你的Pod定义了livenessProbe和readinessProbekubelet会按配置周期性地发起探测。liveness探测失败会触发容器重启readiness探测失败则会把Pod从Service的Endpoints里摘掉不再转发流量给它。我曾排查过一个诡异现象Pod状态显示Running日志正常但服务偶尔报错。后来发现是readinessProbe的探测路径配错了返回的HTTP状态码不对导致kubelet认为Pod不健康时不时把它从负载均衡池里拎出去。这类问题用kubectl describe pod看Events就能发现里面有大量的探针失败记录。整个流程走完你从kubectl apply到Pod真正提供服务中间经历apiserver鉴权、etcd存储、控制器调谐、scheduler调度、kubelet执行六大环节。任何一个环节出问题都会有不同的表象。5. 实战排障组件异常时的现象与排查手段5.1 组件故障速查表把常见组件故障和排查路径整理成一张速查表遇到问题可以直接对着查组件常见故障现象排查命令/思路kube-apiserverkubectl命令超时、返回503或403查apiserver Pod日志、确认etcd健康、查审计日志确认准入拒绝原因etcd集群整体变慢、apiserver报etcd超时etcdctl endpoint health、检查磁盘IO和空间、确认节点间网络延迟kube-schedulerPod一直Pendingkubectl describe pod看Events、查scheduler日志确认是资源不足还是调度策略拒绝kubelet节点NotReady、Pod反复重启journalctl -u kubelet、检查磁盘压力和CRI运行时状态kube-proxyService不通、ClusterIP无法访问确认iptables/IPVS规则存在、检查后端Endpoints是否正常、看kube-proxy日志CoreDNSPod域名解析失败kubectl -n kube-system get pod -l k8s-appkube-dns、检查CoreDNS的ConfigMap配置这张表不是精确诊断手册而是帮你定位问题边界用的。排障第一步永远是缩小范围先确认哪个组件挂了再去深挖原因。5.2 排查时容易踩的坑最后把我在实际运维中踩过比较多的坑整理一下个个都是真金白银换来的教训。第一个坑集群时间不同步。节点间时钟偏差超过一定范围会导致证书校验失败、日志时间线错乱、etcd选举异常。新环境第一件事配置好NTP同步和systemd-timesyncd老环境定期检查节点的date输出。第二个坑只看Pod状态不看Events。很多人一上来就kubectl logs看应用日志但Pod创建失败、调度失败的原因根本不在应用日志里而在kubectl describe pod的Events里。Events里会明确告诉你FailedScheduling是因为某个节点资源不足或FailedToPullImage是因为镜像仓库认证失败。看Events永远是排查Kubernetes问题的第一步不是最后一步。第三个坑忽略版本兼容性。kube-apiserver、kubelet、kubectl、containerd之间的版本差异可能产生各种奇怪问题。官方支持矩阵里kubelet版本可以比apiserver低一个次要版本但反向不行。我碰到过一次集群升级后部分节点NotReady最后发现是这几台机器的kubelet版本还是旧的和新的apiserver之间出现了兼容问题。升级前务必规划好版本匹配升级后逐个节点验证。第四个坑盲目重启组件。很多人遇到kubelet异常第一反应是systemctl restart kubelet结果问题没解决还丢了现场。正确做法是先抓现场日志、节点状态、磁盘使用、容器运行时状态都看一眼再做动作。重启是最后手段不是第一手段。用这套思路去对待Kubernetes你会发现它并没有传说中那么抽象。控制面做决策、数据面做执行、控制器纠偏、kubelet兜底——这么一拆每个组件都有自己的职责边界故障排查变成“对号入座”的活儿。我个人在带新人的时候要求第一周不看任何高级特性先把这篇组件地图和一次Pod创建流程背熟因为后面所有花哨的用法都是在给这条主链加旁支而已。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询