ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Kubernetes入门实战:从Docker到k8s核心概念与集群搭建

Kubernetes入门实战:从Docker到k8s核心概念与集群搭建 很多人刚开始学 k8s 的时候第一反应是先去找一本大部头的 PDF 或者完整视频课程然后被 Pod、Deployment、Service、Ingress 这些名词轮流砸晕。我当年也一样看完文档的第一感受是这玩意到底和 Docker 有什么区别我直接在服务器上 docker run 不行吗先说结论k8sKubernetes中间那个 8 代表 “ubernete” 这 8 个字母是目前事实上的容器编排标准。Docker 解决的是“在一台机器上把应用打包成容器跑起来”的问题k8s 解决的是“几十台机器上几百个容器怎么调度、怎么保证不挂、怎么滚动升级不中断”的问题。这篇文章我会按自己真实的学习路径把 k8s 的整体轮廓过一遍——解决什么问题、核心概念怎么记、环境怎么搭、常用命令有哪些、控制器和弹性伸缩是怎么回事最后给你一份新手高频坑位排查手册。适合三类人正准备入行云原生的开发者正在做容器化改造的运维或后端以及面试前需要快速建立 k8s 认知框架的人。1. 到底什么是 k8s先别急着敲命令搞懂它在解决什么问题1.1 Docker 玩得好好的为什么还要 k8s先回到最原始的痛点。假设早期你一个人维护一个小服务流程很顺代码写好打包成 Docker 镜像服务器上 docker run 一跑就完事。但业务一上来情况立刻变复杂服务从 1 个变成 10 个机器从 1 台变成 5 台每个服务的副本还要根据流量弹性伸缩。这时候你会发现“登录某台服务器手动部署”这套老办法根本撑不住。Docker Compose 能解决一部分问题但它的本质是“单机编排”。想象一个电商后端包含网关、用户、订单、商品、支付、消息队列 worker 六类服务每类服务 3 个副本分布在 5 台机器上。现在要升级订单服务你会怎么做先在每台机器上 pull 新镜像还是在负载均衡上摘流量如果订单服务所在的机器宕机了谁把它自动拉起来流量瞬间涨了 3 倍你又怎么在 10 分钟内把订单服务从 3 副本扩到 10 副本这些问题的答案正是 k8s 存在的意义。它把“人肉运维规则”固化成系统能力调度器决定 Pod 落在哪台机器上控制器保证副本数不漂移Service 提供稳定的服务发现和负载均衡探针能识别“进程还活着但服务已不可用”的假死状态并自动拉起。说白了你只需要告诉 k8s“我期望这个服务有 3 个副本、用哪个镜像、开哪个端口、需要多少内存”剩下的协调动作全部交给它。1.2 一个生活化类比从“厨师”到“餐厅经营”把单容器想象成一位厨师在厨房里炒菜你喊一声“菜单来一份”他把菜端出来。但一家餐厅要正常运转光有厨师远远不够你需要排班表保证每个岗位随时有人对应调度传菜路径保证菜准确送到对应桌台对应 Service菜品标准保证做出来的东西不是时好时坏对应声明式期望状态卫生巡检保证后厨不出问题对应健康检查客人突然爆满时还要加桌加人对应弹性伸缩。k8s 在集群里扮演的就是这套“餐厅经营系统”的负责人。开发者和运维只需要把“菜品标准”比如 Deployment、Pod 的定义写清楚剩下的事情——Pod 在哪台机器跑、挂了怎么拉起、升级时先停哪个再起哪个——都交给控制循环去反复协调。这是我对新手解释 k8s 最直观的方式它不是单一工具而是一整套“让容器化应用在机器集群中稳定运行”的调度与管理机制。1.3 k8s 不是什么先把边界划清楚划清边界比背概念更重要。第一上了 k8s 不等于高可用。如果你只部署 1 个副本机器一挂服务照样停。高可用需要你设计副本数、使用多节点、配置 PDBPodDisruptionBudget防止发布时副本被全部打掉。第二k8s 并没有“取代 Docker”。它现在通过标准的 CRI容器运行时接口对接底层运行时常见选择是 containerd、CRI-O 等。第三不是所有项目都适合上 k8s。一个内部小工具、一个单机应用、一个生命周期只有几分钟的脚本任务用 docker-compose 或普通容器反而更省心。k8s 的复杂度摆在那里业务至少要到“多服务、多副本、需要自动扩容或快速发布”这个规模收益才会真正显现。这也是每次看到有人问“k8s 和 docker 区别”时我最想说的一句大实话两者根本不是替代关系而是不同层级的配合关系。先有容器再有容器编排。把这一点想明白后面的学习会顺很多。2. 核心概念别硬背给每个名词配一个“中文外号”2.1 Pod最小调度单元不是“单个容器”很多新手以为 k8s 直接管容器其实 k8s 最小的调度和部署单元是 Pod。一个 Pod 里可以有一个容器也可以有多个容器这些容器共享同一个网络命名空间共享 IP 和端口、共享存储卷并且永远被调度到同一台机器上。为什么要多包一层 Pod而不是直接管容器因为有些场景下多个进程必须“绑定”在一起才有意义。最典型的是 Sidecar 模式主容器跑业务逻辑旁边一个容器负责日志采集、流量代理或配置刷新两者同生共死共享命运。把 Pod 想成一个“合租的房子”就很形象里面住了几个室友共享一个门牌号IP和公共区域Volume但各自干各自的活。对外访问的是整个房子的门牌号而不是某个房间。2.2 Deployment 的中文名我愿叫它“排班主管”有人问过如果给 k8s 的 Deployment 一个中文名字应该叫什么我觉得最贴切的是“排班主管”。你告诉它“这个服务我希望保持 3 个副本在线镜像版本是 v2.0就绪探针 30 秒超时。” 然后它每隔一段时间检查一次集群里的实际状态发现只有 2 个副本就补建 1 个发现有 5 个就杀掉 2 个。发布新版本时它按策略先启动新 Pod、等就绪了再停旧 Pod这叫滚动更新更新出问题还能一键回滚到上一个版本。你要记得一个关键点Deployment 管理的是无状态服务每个 Pod 都可以被随意替换、删除、重建。如果你的应用有状态比如数据库、需要稳定网络标识的中间件就要换 StatefulSet这个在第 5 章会展开对比。2.3 Service 与 Ingress稳定的门牌号和流量入口Pod 是会“漂移”的。今天在 node1明天节点重启就可能落在 node2而且 Pod IP 每次创建都会变化。如果你的服务 A 要调用服务 B总不能每次都去查最新 IP 吧Service 就是解决这个问题的。Service 创建后会得到一个稳定的虚拟 IP 和 DNS 名字通过标签选择器selector找到后端的一组 Pod把请求转发过去自带简单的负载均衡。你可以把 Service 理解成“总机”不管后端的员工怎么流动你拨打总机号码都能找到对应的人。Ingress 则更靠外。Service 的 ClusterIP 只能在集群内部访问想让外部用户通过域名访问你的服务就要使用 Ingress。Ingress 可以按域名、按 URL 路径把流量路由到不同 Service相当于“值班前台”访客说找销售部它分流到销售部说找技术部它分流到技术部。在 k8s 里一条完整的对外流量路径通常是客户端 → Ingress → Service → Pod。背下这条链路你对 k8s 的访问模型就有画面了。2.4 其它高频配角Namespace / ConfigMap / Secret / PV除开上面几个主角下面这些“配角”出现频率也非常高建议一开始就认识。Namespace 是逻辑隔离空间作用很像公司里的部门划分。同一个集群里可以建 dev、staging、prod 三个命名空间把不同环境的资源隔开再通过 RBAC 控制谁能看哪个空间。注意它不是强隔离更不是安全边界Pod 之间的网络默认还是互通的。ConfigMap 和 Secret 都是配置管理手段。ConfigMap 存普通配置日志级别、开关项Secret 存敏感信息数据库密码、API Key。它们最大的价值是让配置从镜像中解耦——改配置不用重新打包镜像改完在 Pod 声明里引用即可。但要注意一个常见误解Secret 只是 Base64 编码不是加密真正需要加密的敏感数据还要配合外部密钥管理系统。PV/PVC 是持久化存储抽象。PVPersistentVolume相当于一个仓库PVCPersistentVolumeClaim相当于你向仓库申请的空间租约。数据库、消息队列这类有状态服务需要把数据写到 PV 上这样 Pod 被删重建后数据还在。记住一句顺口溜“Pod 会死、IP 会变、配置要解耦、数据要外置”这就是 k8s 设计者希望你使用它的方式。我把这些高频概念整理成了一张速记表方便你贴在显示器旁边名词一句话人话生活类比Pod一组绑定的容器共享网络和存储合租室友Deployment管理无状态服务副本数和滚动更新排班主管Service给一组 Pod 提供稳定访问入口和负载均衡总机/前台Ingress按域名/路径分发外部 HTTP/HTTPS 流量门口分流员Namespace集群内的逻辑隔离空间不同楼栋ConfigMap不打包进镜像的普通配置员工手册Secret存放敏感配置的配置对象注意不是加密保险柜PV/PVC持久化存储的抽象仓库与租约3. 环境搭建三条路学习、生产、托管怎么选3.1 本地快速上手minikube 与 kind环境搭建是入门的第一道坎。很多人一上来就搜“k8s集群搭建”照着教程在云服务器上装 kubeadm装到一半网络插件起不来、Dashboard 打不开半小时热情全没了。我的建议是如果只是学习第一步不要碰生产级安装先在本地把最小集群跑起来。minikube 是最常见的本地学习方案。一条minikube start就能在你的电脑上启动一个单节点 k8s 集群默认通过容器或虚拟机隔离支持大部分核心功能还自带 Dashboard。如果你希望用 Docker 容器直接模拟一个“假多节点”环境kind 更合适——它把 k8s 节点跑在 Docker 容器里启动快、资源消耗小特别适合 CI 里快速验证 yaml。本地学习的期望值要放对目的是熟悉核心概念和 kubectl 手感而不是复刻生产架构。那些“三台 master 高可用”的复杂方案等理解了基本原理再上也不迟。3.2 生产级自建kubeadm 与 KubeKey想在生产自建 k8s社区最主流的路线是 kubeadm。它算是官方出品的半自动安装工具完整流程大概是所有机器装好容器运行时通常 containerd→ 在 master 节点执行kubeadm init→ 按提示配置 kubeconfig → 安装 CNI 网络插件Calico 或 Cilium→ worker 节点执行kubeadm join加入集群。这套流程能让你理解每个组件的位置比如 kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、etcd 是怎么组合起来的所以我很推荐有耐心的新手完整走一遍。如果你不想纠结复杂参数KubeKey 这类工具会更省心它把 kubeadm 的底层流程封装成一条命令或一个配置文件支持一键部署高可用集群还可以顺带装上 KubeSphere 运维面板。热词里有人问“三台 master 怎么保证高可用 kubekey”这里稍微展开常规做法是在三台 master 前面放一个负载均衡入口VPC 内的 SLB或者 keepalivednginx 都行三个 kube-apiserver 挂到负载均衡后面etcd 以三副本方式部署。KubeKey 会自动生成这套高可用配置省掉不少手工步骤。这套架构的稳定性关键反而不在 k8s 组件本身而在 etcd 三节点的网络质量和负载均衡的健康检查配置。3.3 别忘了证书续期1 年后的定时炸弹这是一个非常容易被忽视、但到点必然爆雷的问题。用 kubeadm 搭建的集群默认签发的静态证书有效期大多是 1 年。集群跑满一年后kube-apiserver 和 etcd 之间的通信证书、kubectl 访问用的 admin.conf 等都会陆续过期现象就是 kubectl 突然报 x509 证书过期整个集群管理面陷入瘫痪。解决办法不复杂定期执行kubeadm certs renew all然后更新 kubeconfig重启相关组件即可。生产环境建议把续签写成定时任务比如每月检查一次证书剩余时间临近 30 天时自动续签。否则一旦过年放假没人值班节后回来发现集群全线失联那个体验我已经见过太多了。如果你用的是云托管集群这个事通常由云厂商帮你处理但自建集群必须自己立项把它写进运维手册和监控告警里。3.4 单节点、托管集群与迁移到云上怎么权衡说完搭建方式再看部署形态。很多团队的 k8s 旅程始于一个很朴素的需求先有一整套业务环境在单节点 k8s 上跑通再考虑迁到云上。单节点自建的好处是成本极低、环境可控适合做功能验证和测试但单点故障和性能上限都摆在那里。如果最终目标是云上运行我更建议直接使用托管集群把控制面的运维复杂度外包出去。热词里有个场景很有代表性本地单节点 k8s 上跑着若依微服务整套环境希望不停服、不丢数据地迁移到阿里云 ECS迁移后用 JMeter 做高并发压测。这种迁移看起来简单踩坑点却不少。首先镜像要处理。本地私有仓库的镜像需要推送到目标环境能访问的镜像仓库。其次数据是重中之重。数据库这类有状态服务要做持久卷级迁移推荐先在目标集群把 PV 建好把数据通过备份恢复或在线同步导过去再切换流量才能做到不丢数据。再次网络要改。单节点环境的 NodePort 在云上通常要换成 LoadBalancer 类型或者前置云 SLB Ingress域名和证书也要提前切好。最后才是压测——用 JMeter 验证新集群的承载能力同时配合 Prometheus 监控看资源水位才能知道“能跑”和“扛得住”之间的差距。4. kubectl 常用命令会这一张表就够日常用了4.1 查看类get / describe / logskubectl 是操作 k8s 的入口命令很多但日常 80% 的场景其实集中在几个命令上。查看类三件套是 get、describe、logs。kubectl get nodes看节点状态kubectl get pods -n demo看 demo 命名空间下的所有 Pod。get 后面还可以跟很多资源类型svc、deploy、events 等输出的是精简列表适合快速看全局。kubectl describe是进阶版它会输出某个对象的详细信息和事件流水。新手排查 Pod 卡住时最该做的就是kubectl describe pod pod-name -n demo看底部的 Events 区域那里会明确写出调度失败、镜像拉取失败、探针失败等真实原因。这里的优先级通常高于 logs。kubectl logs看容器日志加 -f 持续跟踪新版本还支持直接看一个 Deployment 下所有 Pod 的日志流。我的排查习惯是先 get 看整体状态再 describe 看事件最后才 logs 看应用日志。顺序反过来你会在应用日志里找半天最后发现根因是镜像标签写错。4.2 操作类apply / delete / exec / scale / rollout日常操作里kubectl apply -f xxx.yaml是最常用的部署方式它是声明式的无论文件里描述的是新建还是更新apply 都会把实际状态向期望状态逼近。kubectl delete删除资源但注意删除 Pod 不等于移除应用Deployment 会立刻重新拉起一个新 Pod这是正常现象。需要进容器排障时用kubectl exec -it pod-name -n demo -- /bin/sh。临时调整副本数用kubectl scale deployment demo --replicas5。发布新镜像版本时用kubectl set image deployment/demo demonginx:1.25或者直接改 yaml 后 apply。kubectl rollout status deployment/demo可以等待滚动更新完成kubectl rollout undo deployment/demo一键回滚。kubectl port-forward svc/demo 8080:80可以把集群内服务临时映射到本地端口调试时非常实用。我把最常用的命令整理成了一张速查表可以直接抄分类命令典型用途查看kubectl get nodes / pods / svc / deploy查看各类资源状态详情kubectl describe pod -n看事件和详细状态日志kubectl logs -f跟踪容器日志部署kubectl apply -f manifest.yaml声明式创建/更新资源扩容kubectl scale deployment --replicasN手动调整副本数更新kubectl set image deployment/ 滚动更新镜像回滚kubectl rollout undo deployment/回滚到上一个版本进入容器kubectl exec -it -n -- /bin/sh进容器调试本地映射kubectl port-forward svc/ 8080:80把集群服务映射到本地端口4.3 新手最容易犯的 4 个“反模式”有些反模式我几乎每次带新人都会看到提前说出来能帮你省时间。第一用kubectl run nginx --imagenginx直接创建 Pod。这样创建的 Pod 没有任何控制器保护节点一挂 Pod 就永久消失。正确做法是用 Deployment 或 yaml 管理。第二排查时不停执行kubectl delete pod而不是看事件。Pod 反复重启大概率是配置或探针问题删了只会让控制循环再拉一个新 Pod问题依旧。第三在生产环境直接用命令改配置但不落到 Git。k8s 的价值之一就是基础设施即代码改完 yaml 应该提交版本库否则线上状态就是一个黑盒。第四全局不加 -n 参数。默认命名空间很容易串环境在 prod 命名空间执行删除之前先kubectl config get-contexts看一眼当前 context 是谁。5. 控制器与弹性伸缩应用“永远在线”靠的是谁5.1 控制器家族怎么选Deployment 负责无状态应用但它只是控制器家族的一员。按应用类型选控制器是入门进阶必须掌握的一课。Deployment 适合 Web API、后端服务等无状态应用Pod 可以被任意替换。StatefulSet 适合数据库、Redis、Zookeeper 等有状态应用它保证每个 Pod 有稳定的网络标识比如 podname-0、podname-1、稳定的存储卷绑定并支持按顺序启停。很多新手把数据库塞进 Deployment一扩缩容就发现数据乱套这就是没理解两种控制器的设计差异。DaemonSet 适合日志采集Filebeat/Fluentd、监控 Agentnode-exporter这类必须“一机一个”的场景。Job 跑一次性任务批量导入、数据清洗CronJob 按定时表达式跑类似 crontab 的 k8s 版。选型可以记一句口诀无状态上 Deployment有状态上 StatefulSet每节点一个上 DaemonSet跑批任务用 Job、定时任务用 CronJob。控制器适合场景关键特征Deployment无状态服务API、Web可随意替换 PodStatefulSet有状态服务DB、Redis稳定网络标识持久卷DaemonSet每节点一个日志、监控Agent自动跟随节点Job/CronJob一次性/定时任务执行完自动退出5.2 高并发不是某个组件而是组合拳热词里有人问“k8s 用于处理高并发的组件是哪个”这个问题值得先纠正一下k8s 的高并发能力从来不是某一个组件单独扛住的而是一套组合拳。最常见的自动扩缩组件叫 HPAHorizontalPodAutoscaler。它通过 metrics-server 定期获取 Pod 的 CPU/内存等指标当指标超过阈值时自动调整 Deployment 的副本数。比如订单服务 CPU 使用率超过 70%HPA 自动从 3 个副本扩到 10 个压力下降后再缩回 3 个。进阶玩法可以配合 KEDA 监听队列深度一类的自定义指标。但 HPA 只管“应用副本的横向扩缩”如果整个集群的机器都不够塞新 Pod你还需要 Cluster Autoscaler 或云厂商的节点组能力让机器本身也能弹性伸缩。更底层的是 Ingress 和 Service 的负载均衡能力。流量先经过 Ingress Controller 分发到 Service再被转发到各个 Pod配合 Pod 的 readinessProbe就绪探针可以保证只有真正能处理请求的 Pod 才会被转发流量。生产常用还有 PDBPodDisruptionBudget它保证节点维护或集群升级时至少有多少副本存活不会一次性全部不可用。一句话总结高并发 Service/Ingress 分流 HPA 弹性扩缩 readiness 探针保护 节点充足余量四者缺一不可。6. 学完基础后值得跟进的 3 个方向6.1 监控告警Prometheus 全家桶分工集群搭好、应用跑起来之后第一件要紧事就是把监控补上。社区最主流的方案是 Prometheus Grafana很多团队直接部署 kube-prometheus-stack 这个全家桶 chart一条命令就能拉起整套监控体系。全家桶里每个组件分工明确Prometheus 负责拉取和存储指标node-exporter 部署在所有节点上采集主机指标CPU、内存、磁盘kube-state-metrics 把 k8s 对象的状态Pod 数量、Deployment 副本数、HPA 状态等暴露成指标Grafana 负责可视化社区现成的 K8s 运维 Dashboard 非常多导入即可用。再加上 Alertmanager 配置告警规则比如 Pod 重启次数异常、节点磁盘使用率超 80%、证书即将过期都能及时推送消息。我见过很多团队把监控部署完就当完事了其实更关键的是告警阈值和联系人。没有告警的监控只是“事后博物馆”要在事情发生前 15 分钟知道风险而不是事故后翻图表复盘。6.2 效率工具从 kubectl 到可视化面板kubectl 虽强但纯文字界面在排查多资源问题时效率有限。这里说几个常见的效率工具。k9s 是很多老手离不开的终端 UI纯键盘操作列表里直接按 d 进入 describe、按 l 看日志、按 s 进入 shell输入 / 还能模糊搜索比反复敲一长串命令快很多。Lens 是桌面客户端图形化查看集群资源和实时状态适合不习惯终端的人。如果团队需要更完整的平台化管理可以上 Rancher 或 KubeSphere 这种多集群管理平台它们能在一个 Web 界面里管理多个集群、项目和权限。国内还有 Kuboard中文界面、上手门槛低对新手特别友好。至于官方提供的 Dashboard也就是 k8s 原生管理页面功能中规中矩胜在原生可靠。要注意它的访问一般需要 Bearer Token 或 kubeconfig 认证默认给的权限很大务必按最小权限原则为不同成员创建独立 ServiceAccount不要直接拿管理员 token 到处乱贴。6.3 Service Mesh、GPU 调度与微服务迁移实战再往后走就进入偏进阶的方向了。热词里出现过的 Dubbo Mesh把 Dubbo 这类微服务框架放进 Service Mesh 治理本质上是把服务发现、熔断、限流、可观测性下沉到基础设施层。Istio 和 Linkerd 是目前主流的 Service Mesh 实现学习曲线不低但如果你所在团队正在做微服务拆分、又对框架层面的治理能力不满意这个方向值得深入研究。GPU 调度是 AI 场景绕不开的话题。k8s 要调用 GPU前提是节点上装好 GPU 驱动并部署对应厂商的 device plugin比如 NVIDIA 的 nvidia-device-plugin作为 DaemonSet。部署完成后GPU 就成了 k8s 的一种可调度资源Pod 声明resources.limits[nvidia.com/gpu]: 1就能申请一块 GPU调度器会自动把它分配到有 GPU 的节点。常见坑有三个驱动版本和容器运行时不匹配、没装 device plugin、Pod 请求的卡数超过节点总量导致一直 Pending。排查思路仍然可以回到第 7 章的 describe 大法。再说回热词里那个若依微服务迁移案例。这种“整套微服务 压测验证”的场景其实就是前面所有知识点的综合演练集群搭建在第 3 章核心对象编写在第 2、4 章控制器选型在第 5 章监控验证在 6.1 节。迁移完成后用 JMeter 打高并发观察 HPA 是否按预期扩容、Prometheus 里资源水位是否合理就能把“能用”变成“扛得住”。7. 新手踩坑实录6 个高频问题排查手册先给你一张高频问题速查表后面逐个展开症状首选排查命令高频原因ImagePullBackOffkubectl describe pod xxx镜像名错 / 仓库认证 / 网络问题Pendingkubectl describe pod xxx资源不足 / 污点 / 节点选择NotReadyjournalctl -u kubelet -fkubelet 异常 / CNI 插件CrashLoopBackOffkubectl logs pod --previous启动报错 / 探针配置证书过期kubeadm certs check-expiration一年有效期未续签Service 不通kubectl get endpointsselector 标签不匹配7.1 镜像拉取失败先分清是网络、认证还是镜像名问题几乎所有人都会第一次遇到 ImagePullBackOff。看到这个状态先别慌按顺序排查三件事。第一看 Events。kubectl describe pod pod-name底部的 Events 会写明具体错误。如果报的是镜像 404 或 manifest unknown多半是镜像名写错或 tag 不存在如果报的是 authentication required说明私有镜像仓库需要认证要在 Pod 里指定 imagePullSecrets如果报的是 dial tcp 超时、connection refused 这类网络错误该配镜像加速器的配加速器、该检查仓库连通性的检查连通性。第二检查镜像策略。imagePullPolicy 有 Always、IfNotPresent、Never 三种分别表示总是拉取、本地没有才拉、只从本地找。本地测试如果用 minikube经常需要先把镜像导入 minikube 的容器运行时如果策略是 Always镜像已经存在本地也照样会去仓库拉网络不通就会失败。第三确认节点和认证是否匹配。多节点集群里镜像拉取发生在实际调度到的节点上如果你只在某个节点手动 docker pull 了私有镜像但调度到了另一个节点照样拉不下来。规范做法是每台节点都能访问镜像仓库或者统一配置 imagePullSecrets。7.2 Pod 一直 Pending不要急着删要看调度失败原因Pod 一直 Pending说明它还没被调度到任何节点。最常见原因有集群资源不足所有节点的 CPU/Memory 都不满足 requests、节点存在污点taint而 Pod 没有对应容忍toleration、NodeSelector 选中不了合法节点、或者单节点集群里 master 默认不调度业务 Pod需要去除 NoSchedule 污点或调整调度配置。排查步骤很固定kubectl describe pod pod-name看 Events。如果是 0/1 nodes are available后面会跟每个节点失败的原因比如 Insufficient cpu、Insufficient memory、node(s) had taint。根据原因对症下药即可加机器、调小 request、加 toleration或者把业务 Pod 调度到 master。这里提醒一句很多新手看到 Pending 就反复重启集群或者直接删 Pod这基本是无效操作因为控制循环已经在不停重试。正确思路永远是从 Events 找线索一次 describe 往往胜过十次盲目动手。7.3 节点 NotReady多半是 kubelet 和 CNI 的锅节点状态变成 NotReady基本等于这台机器上的容器运行时和集群失联了。第一步先看 kubelet 服务状态systemctl status kubelet再用journalctl -u kubelet -f看日志。常见原因包括容器运行时配置没对齐比如 containerd 的 sandbox_image 指向的镜像拉不下来、kubelet 证书过期、节点负载过高导致心跳超时。另一个高发原因是 CNI 网络插件没装好。集群初始化之后 CoreDNS 一直 CrashLoopBackOff大概率就是没装 Calico 或 Cilium。安装之后还要确认插件 Pod 正常运行不同插件的默认网段不能和服务器实际网段冲突否则节点之间通信数据包会被路由丢掉表现为 Pod 之间时而通时而不通。处理这种问题最忌讳“头痛医头”。先确认是 kubelet 进程的问题还是网络插件的问题再决定重启哪个服务。否则你重启十次 kubelet问题可能出在 /etc/cni/net.d/ 下的配置没清理干净。7.4 CrashLoopBackOff先看日志再查探针CrashLoopBackOff 表示容器启动后又退出反复循环。排查第一入口永远是容器日志kubectl logs pod-name -n ns看进程退出的真实原因。如果日志是空的再看看上一个崩溃实例kubectl logs pod-name --previous很多应用在首次启动时打印了错误但容器退出后日志被新实例覆盖了。如果日志显示应用其实启动成功了但 k8s 仍然认为它不健康那就要查探针配置。startupProbe 适合启动慢的应用如果设置不当可能在镜像启动完成之前就被 livenessProbe 杀掉readinessProbe 如果指定了不存在的路径应用会一直进不了 Ready 状态流量切不进来。常见的坑还有应用需要环境变量但 Secret 或 ConfigMap 没挂载成功镜像里默认监听端口和探测端口不一致数据库连接串没通导致应用启动即报错退出。从日志 → 配置 → 探针这个顺序走基本都能定位。7.5 证书过期别等它爆雷证书过期往往是最安静的故障前期毫无症状一到时间点全部集中爆发。症状常表现为kubectl 连接集群报 x509: certificate has expired or is not yet validkube-apiserver 日志里大量 TLS 报错节点上的 kubelet 无法与 apiserver 正常通信。解决流程参考 kubeadm 的官方做法在 master 节点执行kubeadm certs renew all把集群静态证书全部续签然后刷新 kubeconfig重新生成 admin.conf 并更新本地配置最后重启 kubelet 让 apiserver 等静态 Pod 重新载入证书。生产环境务必把续签流程做成定时任务或预检脚本每月检查一次证书剩余天数并在到期前 30 天自动处理。经历过一次节假日期间集群全线失联之后你会明白这套机制有多重要。# 查看所有证书的过期时间 kubeadm certs check-expiration # 续签全部证书 kubeadm certs renew all7.6 Service 不通先看 EndpointsService 不通是典型的“看起来简单、实际一个标签对不上就完蛋”的问题。排查顺序kubectl get svc看 Service 类型kubectl get endpoints svc-name看这个 Service 是否成功关联到 Pod。如果 Endpoints 列表为空说明 Service 的 selector 和 Pod 的 labels 没对上这是最常见的原因——多写或少写一个标签Pod 就永远进不了 Service 的负载池。还有一个容易踩的坑不要拿集群外机器直接访问 ClusterIP 类型的 Service。ClusterIP 只在集群内部可达外部访问要用 NodePort、LoadBalancer 或 Ingress。如果你在云上环境用 NodePort 访问不到看看云安全组是否放行了对应端口本地调试就用kubectl port-forward svc/name 8080:80最省事。另外Service 的 targetPort 必须和 Pod 容器真正监听的端口一致很多 Service 半通不通的案例最后都发现是 targetPort 写成了端口名而容器根本没定义这个 port name。最后说一点个人体会。学 k8s 最大的坎不是命令记不住而是思维方式要从“命令式”切换到“声明式”。你以前习惯了在服务器上手动 docker run、systemctl restart每一步都要自己控制而在 k8s 的世界里你的核心工作是描述“期望状态”剩下的控制循环会不断把现实收敛到期望。很多新手焦虑于“我 apply 之后怎么没动静”其实 k8s 正在后台偷偷协调。多建 Pod、多删 Pod、故意搞坏一个镜像看看 k8s 会怎么反应把手弄脏永远比看十本 PDF 有用。先把这篇文章里的概念在 minikube 上挨个实践一遍再考虑集群搭建和监控入门就能少走很多弯路。
返回列表