news 2026/10/14 3:03:22

一文掌握Kubernetes:从容器编排到集群实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文掌握Kubernetes:从容器编排到集群实战

搞容器化半年之后,我发现自己天天敲docker run,但一说到"上生产",马上就被问倒了:容器挂了怎么自动恢复?流量大了怎么扩容?多台机器上容器怎么调度?新版本怎么无损发布?这些问题单靠 Docker 根本答不上来。这时候我才老老实实去学 Kubernetes,也就是大家口中的 K8s(读作"k8s"或"kube"),学完之后回头看,之前那些零散的容器操作只是地基,K8s 才是真正把容器变成"服务"的那一层。

这篇内容就是给正在学或者准备学 K8s 的朋友准备的。我不会先从理论名词轰炸你,而是按照我自己从"会跑容器"到"敢上 K8s"的真实路径来写:先讲清楚它到底解决了什么问题,再拆架构、讲核心对象,最后给一套可以直接照着搭的环境步骤和排错思路。如果你是刚接触 K8s 的开发者、运维,或者正在准备容器化改造的技术负责人,这篇应该能帮你少走我踩过的那些弯路。

1. 先搞明白:K8s 到底解决了什么问题

1.1 容器时代的问题:跑起来容易,管起来难

很多人第一次接触容器时都觉得很爽:docker build打个包,docker run一条命令起来,端口映射一下就能访问了,比传统部署方式省心太多。

但当你手上的容器数量从 3 个变成 30 个,机器从 1 台变成 3 台时,问题就来了:

  • 某个容器挂了,谁来把它重新拉起来?
  • 流量高峰期来了,想从 5 个实例扩到 20 个,难道要一个个手动docker run吗?
  • 一台宿主机宕机了,上面跑的十几个容器怎么办?
  • 发布新版本时,怎么做到不停机更新、有问题秒级回滚?
  • 多个容器之间互相通信,IP 地址一变就得改配置,这谁受得了?

这些问题往本质里说就一句话:容器本身解决的是"打包和隔离",但大规模运行时的"编排"问题,需要另外一套系统来解决。K8s 就是这套系统的行业事实标准。

1.2"编排"到底编排的是什么

网上讲 K8s 时常说"容器编排平台",这个词听起来有点抽象。我用大白话翻译一下:K8s 就是一个"容器管家",你告诉它"我要跑什么、要几个副本、需要什么资源",它负责找机器去跑、盯着它们的健康状况、挂了就重启、流量大了就扩容、流量小了就缩容、新版本发布时按节奏滚动替换、老版本随时可以回退。

它做的事情本质上和"调度"两个字高度相关。你可以类比一支球队:K8s 是主教练,每个容器是球员,球员状态不好(容器崩溃)就换人(重建),比赛强度加大(高并发)就多上几个人(扩容),受伤了就去替补席(重新调度到健康节点)。

这里有个关键认知要纠正:K8s 不会让你写的应用变强,也不会自己提升性能,它做的是让"部署、恢复、扩展、升级"这些运维动作变得可靠和自动化。很多人以为上了 K8s 系统就稳了,结果应用代码自己写得稀烂,照样崩,只是崩了以后恢复得比以前快而已。

提示:如果你的应用是无状态、可水平扩展的,上了 K8s 会非常舒服。如果是有状态应用(数据库、消息队列),K8s 也能管,但复杂度会高一个量级,这部分后面讲存储时会单独说。

2. 整体架构:控制平面和工作节点

2.1 控制平面:集群的大脑

K8s 集群从逻辑上分成两部分:控制平面和工作节点。控制平面负责做出所有决策,工作节点负责实际跑容器。

控制平面上一共跑着这几个核心组件:

  • API Server(也叫 kube-apiserver):整个集群的唯一入口。你用kubectl敲的每条命令,本质都是发给它的一串请求。它做了三件事:认证请求、校验请求、把状态写入存储。你可以把它理解成"前台接待员",所有人都得找它办事。

  • etcd:K8s 用来保存所有状态的高速键值数据库。集群里每个资源的状态、期望值、实际值全部存在 etcd 里。etcd 挂了,整个集群就瞎了,因为 API Server 不知道该相信谁。

  • Scheduler(调度器):它的任务只有一个——决定"一个新创建的 Pod 应该放在哪台节点上"。决策依据包括资源剩余量、节点标签、亲和性规则、污点容忍等。

  • Controller Manager(控制器管理器):它是一堆控制器的集合,负责让集群的"实际状态"不断趋近于"期望状态"。比如 Deployment 控制器发现副本数从 3 变成了 1,它就会马上创建新的 Pod 补回去。这个"不断对比期望和实际、然后纠偏"的循环,就是 K8s 最核心的设计思路。

这里有个特别容易让新手蒙圈的点:控制平面的这些组件,自己也是容器,也跑在机器上。甚至在单机学习环境里,控制平面和你的应用可以跑在同一台机器上。只是生产环境里为了可靠性,控制平面通常是至少 3 台机器(奇数,配合 etcd 做选主)。

2.2 工作节点:真正干活的地方

工作节点上的组件就简单多了,主要有三个:

  • Kubelet:每个节点上的"监工",负责跟控制平面通信,接收 Pod 定义,然后调用容器运行时把容器真实跑起来。它还会定期向控制平面上报本节点的状态和资源使用量。

  • Container Runtime(容器运行时):真正拉起容器进程的底层组件,早期是 Docker,现在主流是 containerd。Kubelet 通过容器运行时的接口操作容器,自己不直接碰容器细节。

  • Kube-proxy:负责实现 Service 的负载均衡。它维护节点上的网络规则(通过 iptables 或 ipvs),让请求按照规则转发到后端 Pod 上。

我还想强调一个容易被忽略的组件:CoreDNS。它提供集群内部的域名解析服务,比如你在 Pod 里访问svc-name.namespace.svc.cluster.local,就是 CoreDNS 解析的。没有它,集群内的服务发现基本没法用。

2.3 请求的完整流转

理解了组件,再看一条请求从进入到返回的全过程,印象会深刻很多。

假设你先写好了一个 Deployment YAML,然后执行kubectl apply:

  1. kubectl 把你的 YAML 解析成 API 对象,发给 API Server。
  2. API Server 校验并写入 etcd,然后将事件通知给 Controller Manager。
  3. Deployment Controller 发现有新的期望状态,创建 ReplicaSet,ReplicaSet 控制器计算出需要创建 3 个 Pod,于是创建 Pod 对象。
  4. API Server 继续把 Pod 写入 etcd。Scheduler 监听到有未分配的 Pod,综合资源、约束条件,决定分配到 node-01 上。
  5. API Server 将调度结果写入 etcd,并通知 node-01 上的 Kubelet。
  6. Kubelet 调用 containerd 拉取镜像、创建容器、启动进程,最后回传状态。
  7. 你创建 Service 时,Kube-proxy 在各节点上配置转发规则,把 Service 虚拟 IP 的流量导到这批 Pod 上。

整个流程快的话几秒钟就完成。我当年梳理完这条链路之后,突然觉得kubectl敲下去之后的世界不再是黑盒,排查问题也有方向感了。

3. 每天打交道最多的核心对象

3.1 Pod:最小调度单元

Pod 是 K8s 里最小的部署和调度单元,它裁一个或多个容器,共享网络命名空间和存储卷。注意:K8s 不直接调度容器,而是调度 Pod。

这句话怎么理解?你可以把 Pod 想象成"一个炕上睡的几个兄弟"——它们共享一个 IP、共享端口空间,可以通过 localhost 互相访问,共享挂载的磁盘目录。这种设计的价值在于:有些业务场景里,两个进程必须同生共死、共用在同一个环境里(比如一个进程写日志、一个进程收集日志,或者一个反代、一个业务),把它们塞进同一个 Pod 能做到"要么一起起来,要么一个都别想跑"。

不过实际工作中,绝大多数 Pod 里只有一个容器。多容器 Pod 属于进阶用法,我建议新手先记住"Pod 是原子单位",别一上来就把多个容器塞进去。

3.2 工作负载:Deployment、StatefulSet、DaemonSet、Job

光有 Pod 还不够。Pod 挂了谁来重建?升级了怎么回滚?有状态的数据怎么保序?K8s 用一堆"工作负载资源"来回答这些问题,最常用的四个:

资源类型用途适合场景
Deployment管理无状态应用的副本、滚动更新、回滚Web 服务、API、微服务、任何能随时重建的应用
StatefulSet管理有状态应用,保证稳定网络标识、存储绑定数据库、消息队列、ZooKeeper 类应用
DaemonSet保证每个节点上跑一个副本日志采集、监控 Agent、网络插件
Job / CronJob跑一次性任务或定时任务数据批处理、定时备份、清理任务

再说仔细一点。ReplicaSet是 Deployment 底下的控制器,管副本数;你平时很少直接写 ReplicaSet,通常声明 Deployment,Deployment 自动创建和管理 ReplicaSet。每次你更新 Deployment 的镜像版本,它都会创建一个新的 ReplicaSet,滚动升级的同时保留旧版本记录,方便回滚——这是我们能做到"发布五分钟、回滚十秒钟"的根本原因。

StatefulSet和 Deployment 的根本区别在于"身份"。StatefulSet 里的每个 Pod 有固定名称和稳定的网络标识(比如db-0、db-1),启动顺序是严格从 0 到 N,每个 Pod 挂载的存储卷是独立绑定的。这让数据库这类应用在 K8s 里勉强能活,但代价是运维复杂度暴涨。

新手建议:K8s 成熟之前,数据库、缓存这类有状态服务尽量不迁移上 K8s。用云厂商的托管数据库或自建独立集群,比硬放 K8s 里省心得多。先把无状态应用跑顺,有状态等团队沉淀出完整的 operator 方案再说。

3.3 Service 和 Ingress:让流量找得到门

Pod 是朝生暮死的:IP 地址每次重建都可能变。如果让应用之间直接记 Pod IP,那集群一乱就全乱了。K8s 给每个服务抽象了一个稳定的入口,叫Service。

Service 有三种最常用的类型:

  • ClusterIP:集群内部访问你,分配一个稳定的虚拟 IP。比如 A 服务要调 B 服务,就是通过 B 的 ClusterIP 或域名。
  • NodePort:在每个节点上开一个端口(30000-32767),外部可以通过任意节点 IP + 这个端口访问。常用于测试环境,生产不太用。
  • LoadBalancer:和云厂商的负载均衡器对接,外部流量直接打到负载均衡 VIP 上,再分发到后端的 Pod。这是生产环境最常见的暴露方式。

Service 怎么找到后端 Pod?靠 Selector。你给 Pod 打上标签(比如app: nginx),Service 通过标签选择器把符合条件的 Pod 全部纳入后端列表。Kube-proxy 再更新转发规则,请求就会被分发到这些 Pod 上。

Ingress是更上层的"入口网关",它管的是 HTTP/HTTPS 层的路由:根据域名、路径把请求转给不同的 Service。比如api.example.com转给 A 服务,web.example.com转给 B 服务。Ingress 本身是个对象,真正干活的是一个叫 Ingress Controller 的组件(常见的有 Nginx Ingress、Traefik、云厂商的 Ingress 产品)。

3.4 Namespace 和配置对象

有了 Namespace 之后,一个集群可以逻辑上划分为多个虚拟空间。很多团队用它做环境隔离:dev、test、prod各占一个 Namespace,互不干扰。但是注意,Namespace 不是强隔离,它管不了网络策略,跨 Namespace 的访问默认是通的。

ConfigMap和Secret是用来做配置注入的:

  • ConfigMap 存非敏感的配置,比如服务端口、日志级别、开关项。
  • Secret 存敏感信息,比如数据库密码、Token、私钥。它只做了 Base64 编码,不是加密,存到 etcd 时建议开启加密功能。

把配置从镜像里拆出来的核心好处是:同一个镜像,通过挂载不同的配置,就能适配不同环境。这样做到"一次构建,到处运行",CI/CD 里就不用为每个环境重新构建镜像了。

4. 动手实操:从零搭一套 K8s 集群

概念看十遍不如动手搭一遍。K8s 的安装方式非常多,我强烈建议新手不要一开始就用托管服务(比如云厂商卖的一键集群),那样你会错过理解组件关系的最好机会。先自己在虚拟机或云主机上通过 kubeadm 搭一套两节点集群,跑通以后再上托管服务,看任何东西都通透很多。

4.1 准备环境

需要两台干净的 Linux 虚拟机或云主机,配置至少 2 核 CPU、2GB 内存(最好 4GB),装 Ubuntu 22.04 或 CentOS 7.9。一台做控制平面节点,一台做工作节点。我用的实验环境就按这个标准搭的双机。

先做基础的系统初始化,每台机器都要执行:

# 关闭 swap,kubelet 默认要求关闭 swap sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab # 加载内核模块 cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf br_netfilter EOF sudo modprobe br_netfilter # 设置内核参数 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 EOF sudo sysctl --system

这个步骤很多人会略过,但漏掉ip_forward=1会导致 Pod 访问外部网络失败,漏掉swapoff会导致 kubelet 直接拒绝启动。

4.2 安装 containerd 和 kubeadm

早期教程都让装 Docker,现在 K8s 官方早就把 containerd 作为默认运行时了。配置好 containerd 之后,重点是给它的配置文件里设置SystemdCgroup = true,否则节点上的容器无法正常统计 CPU 和内存:

# 安装 containerd sudo apt update sudo apt install -y containerd # 生成默认配置 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml # 修改配置:SystemdCgroup 改为 true sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml # 重启 sudo systemctl restart containerd sudo systemctl enable containerd

接着安装 kubeadm、kubelet 和 kubectl。版本要选一致,这里用当前主流的 1.28 系列:

sudo apt update sudo apt install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt update sudo apt install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl

apt-mark hold这步很多人不知道,它会把这三个包的版本锁住,防止apt upgrade把它们升到不兼容的版本。我在这上面吃过亏:版本一升,整个集群就没法用了。

4.3 初始化控制平面

在控制平面节点上执行kubeadm init:

# 单网卡环境一般不用指定,多网卡时要指定 API Server 地址 sudo kubeadm init \ --apiserver-advertise-address=<控制平面节点IP> \ --pod-network-cidr=10.244.0.0/16 \ --kubernetes-version=1.28.2

--pod-network-cidr指定的是 Pod 网段,这个值必须和后面的网络插件(比如 Flannel 用 10.244.0.0/16)保持一致,否则 Pod 之间无法正常通信。

初始化成功后,按提示去配置 kubectl:

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config kubectl get nodes

这时候如果你执行kubectl get nodes,控制平面节点会显示NotReady,这是正常的,因为还缺 CNI 网络插件。

4.4 安装 Flannel 网络插件

CNI(容器网络接口)插件负责给每个 Pod 分配 IP、打通跨节点通信。我第一套环境用的 Flannel,因为它最省心:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

等一分钟再看节点状态,变成Ready就说明网络通了。这一步如果卡住,最常见的原因是控制平面节点的 6443 端口没放通,或者--pod-network-cidr和 Flannel 配置不一致。

4.5 加入工作节点

控制平面初始化完成后会输出一条kubeadm join命令,里面带 Token。Token 有效期默认 24 小时,如果过期了,在控制平面节点重新生成:

kubeadm token create --print-join-command

然后到工作节点上执行输出的命令,比如:

kubeadm join <控制平面节点IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

回到控制节点验证:

kubectl get nodes

看到两个节点都是Ready,集群就搭完了。第一次搭成功的那一刻,你会对整个架构图里那些组件有完全不同的感觉——原来每个组件都不是虚的。

4.6 部署你的第一个应用

集群空转没意义,跑一个应用感受一下完整工作流。创建nginx-deploy.yaml:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx-demo spec: replicas: 3 selector: matchLabels: app: nginx-demo template: metadata: labels: app: nginx-demo spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80

应用并观察滚动:

kubectl apply -f nginx-deploy.yaml kubectl get pods -o wide

再创建一个 Service 把它暴露出来:

kubectl expose deployment nginx-demo --type=NodePort --port=80 --target-port=80 kubectl get svc

用任意节点IP:NodePort访问一下,页面能出来,你的第一套 K8s 环境就算是真正跑通了。

实操心得:这一步做完别急着关机器,留着它继续实验。后面学习 Service、存储、滚动更新、故障恢复,全都需要一套真实环境。我见过太多人看完教程没实操,过两周再来问"为什么会 CrashLoopBackOff",原因就是 Pod 失败了没看过真实输出。

5. 调度、网络与存储:绕不过去的三座山

集群搭起来以后,应用也跑起来了,但有几个机制如果你不理解,遇到问题会很抓狂:Pod 为什么跑在这台不跑在那台?Service 负载均衡是谁在干活?数据库这种有状态应用在 K8s 里怎么存数据?

5.1 调度器怎么决定 Pod 跑在哪个节点

Scheduler 的核心工作流程可以理解成一个"筛选+打分"的过程。

筛选阶段(Filter):先把完全不符合条件的节点踢掉。比如 Pod 声明需要 2 核 CPU、4G 内存,那可用资源少于这个值的节点直接出局;Pod 限制了只在带disk=ssd标签的节点上跑,其他节点也出局。

打分阶段(Score):对剩下的节点按各种策略打分,比如资源最充足的节点分数高、已经跑了同类 Pod 的节点分数低(尽量分散)、节点上待调度的 Pod 越少分越高等。最后得分最高的节点获胜。

新手经常会遇到的坑是"Pod 一直 Pending"。排查第一步永远是用kubectl describe pod看调度器给出的提示,常见原因包括:

  • 节点资源不足,所有节点都过了资源水位。
  • Pod 有nodeSelector,但没有节点匹配。
  • 节点有污点(Taint),Pod 没有对应的容忍(Toleration)。

污点和容忍这一对概念,理解起来很快:节点上打了污点,就像贴了"生人勿近"的牌子;Pod 加了容忍,相当于"我是熟人可以靠近"。控制平面节点默认有污点,所以业务 Pod 不会调度到它上面。

5.2 Service 负载均衡是怎么生效的

Service 创建以后,kube-proxy 会做一件关键的事:在集群每台节点的 iptables 里写入规则。当一个请求访问 Service 的虚拟 IP 时,iptables 规则会把流量随机转发到某个后端 Pod 的真实 IP 上。

底层的转发链路大致是这样:客户端 → ClusterIP:Port → iptables DNAT → Pod IP:Port。这里有一个值得注意的点:转发行为发生在发出请求的那台节点上,如果请求是集群外部发来的,会先进入某台节点(NodePort/LoadBalancer 场景),然后再做 DNAT。所以 Kube-proxy 必须在每台节点上保持一致的规则,这也是为什么 Service 是集群级别的对象。

如果你在高并发场景下做性能调优,会发现 iptables 模式在大规模 Service(几千条规则)下性能衰减明显。这时可以改成 IPVS 模式,它用内核态哈希表做转发,性能好很多。在 kube-proxy 的启动参数里加--proxy-mode=ipvs即可。

5.3 存储卷:有状态应用怎么保存数据

Pod 里的容器一重建,写入容器本地文件系统的数据就灰飞烟灭了。如果数据要持久化,必须挂存储卷。

K8s 的存储体系分三层:

  • Volume:Pod 级别声明的存储,生命周期和 Pod 一致(所以只能解决容器重启数据丢失,解决不了 Pod 被删)。
  • PV(PersistentVolume)和 PVC(PersistentVolumeClaim):PV 是集群里的一块真实存储(可以是云硬盘、NFS、本地盘),PVC 是使用方提出的"我要一块 20G 的读写盘"的申请,系统自动把合适的 PV 和 PVC 绑定。
  • StorageClass:负责"按需动态创建 PV"的模板。PVC 里指定 StorageClass,系统就自动创建对应类型的 PV,省去了人工预分配盘的工作。

看到这里你应该明白了:StatefulSet 里每个副本之所以能保持自己独立的数据,是因为每个 Pod 绑定了一个独立的 PVC,Pod 重建后重新挂载同一个 PVC,数据就还在。这套机制叫做"稳定存储身份"。

但我要给你一个忠告:在团队能力没成熟之前,不要在 K8s 上跑核心数据库。K8s 的存储编排、故障转移、备份恢复,每一样都有一套复杂的细节,生产环境出事时的心理压力远高于收益。等团队把这套机制玩明白了,再考虑把无状态应用之外的东西迁移过去。

6. 常见问题与排查实录

这一部分我想把学习过程中反复出现的几类问题集中列出。记不清的时候直接翻这个速查表,能省下不少时间。

现象最常见原因优先排查命令
Pod 一直 Pending节点资源不足、污点不匹配、缺 PVCkubectl describe pod <pod-name>
Pod 一直 ImagePullBackOff镜像名写错、镜像不存在、仓库认证失败kubectl logs <pod-name>、登录仓库测试
容器反复重启(CrashLoopBackOff)启动命令报错、配置缺失、依赖没就绪kubectl logs --previous <pod-name>
节点状态 NotReady网络插件没装好、kubelet 挂掉、资源耗尽systemctl status kubelet、看 node 事件
Service 访问不通标签选择器写错、后端 Pod 没就绪kubectl get endpoints <svc-name>
DNS 解析失败CoreDNS 没起来或资源受限kubectl logs -n kube-system -l k8s-app=kube-dns
集群版本升级后 hang 住kubelet 和 API Server 版本不一致kubectl version,对比版本

6.1 Pod 一直 Pending,怎么办

Pending 意味着调度器还没把它放到任何节点上。别猜,直接看事件:

kubectl describe pod <pod-name>

在 Events 末尾会给你明确原因,比如 "0/2 nodes are available: insufficient cpu" 或者 "node(s) had untolerated taint"。前者就是节点资源不足,后者要看那个污点是不是节点故意打的。

6.2 镜像拉取失败,怎么判断

先分清楚是"拉不到"还是"认证失败":

# 拉不到一般是网络问题或镜像名不对 kubectl logs <pod-name> # 手动在节点上测试一下 sudo crictl pull nginx:1.25

如果私仓镜像需要认证,就得在 Pod 里配置imagePullSecrets,把认证信息提前存储到 Secret 里。拉取失败时千万别只盯着 Pod 日志,crictl pull能直接告诉你 root cause 是不是仓库连通问题。

6.3 CrashLoopBackOff 是哪些坑

CrashLoopBackOff 的意思是:容器起来了,但马上挂了,然后不断重试,重试间隔越来越长。

排查第一步永远是看日志:

# 看当前容器日志 kubectl logs <pod-name> # 如果容器一直在重启,看上一次的日志 kubectl logs <pod-name> --previous

这里的--previous参数我每次都要强调:它能看到上一个崩溃实例留下的输出。很多新手只调kubectl logs,结果看到的是空输出,以为 Pod 没问题,实际上上一个实例已经把报错写进日志了。

在我的经验里,CrashLoopBackOff 最常见的原因是"应用启动时依赖了不存在的环境变量或配置",其次是"启动命令路径写错"和"健康检查配置太激进(应用还没起来就认为不健康,然后被干掉)"。

6.4 节点 NotReady,先看 kubelet

节点报 NotReady 时,第一时间登录到问题节点上看服务状态:

systemctl status kubelet journalctl -u kubelet --no-pager -n 100

常见的几条原因:

  • kubelet 没启动或启动失败(证书过期、配置错)。
  • 机器资源耗尽(磁盘满、内存耗尽),Kubelet 被 OOM 干掉。
  • CNI 插件配置丢失,导致 Pod 网络整理失败。
  • 节点和 API Server 之间网络不通(防火墙、安全组拦了 10250 端口)。

修复节点网络挂掉的问题时,我会先 ping 一下 API Server 的 IP,确定基础网络通不通,再逐层看 kubelet 日志,通常都能找到定位点。

6.5 一些避坑心得

最后写几条心得体会,都是我实际踩过的:

  • 每台机器的时钟要同步。集群里节点间时间偏差过大,会导致证书校验失败、日志排查混乱。部署集群前先配好 NTP 或 chrony。
  • 不要动/etc/kubernetes/manifests下的静态 Pod 文件除非你清楚后果。API Server、etcd 这些组件本身就是静态 Pod,改错一步集群直接瘫痪。
  • 资源 requests 和 limits 一定要写。不写 requests,调度器不知道节点真正的容量;不写 limits,某个应用可能把节点内存吃满导致整机 OOM。这是新手最容易忽略、也最容易被线上事故教育出来的点。
  • etcd 一定要备份。集群配置、状态全在 etcd 里,简称"一丢全丢"。我现在每周定时做一次快照备份。

收尾:我的个人上手建议

如果你正准备开始啃 K8s,我建议你按这个顺序来:先搭一套 kubeadm 集群(别用托管集群,这步省了后面会补课),然后用 Deployment + Service 部署一个无状态应用,接着尝试修改副本数、触发滚动更新和回滚,再故意手动删一个 Pod 看看它怎么被重建——这些动作做一遍之后,你对"控制平面在管什么、节点在干什么"就有了体感。

学习方法上有个反直觉的经验:不要一开始就背所有 YAML 字段、看官方文档的每个概念页。抓主线,主线就是那三件事——期望状态、控制器纠偏、API 驱动。剩下的 Pod 生命周期、探针、HPA、NetworkPolicy 这些都是在主线上生长的枝叶。

我在这个项目上最大的体会是:K8s 学的不是"某个工具怎么用",而是一整套"大规模分布式系统的运维思维"。容器只是砖头,K8s 是施工规范,真正决定房子质量的,是你对这套规范的理解深度。把这些基础知识吃透之后,再去看云原生的其他东西——服务网格、可观测性、GitOps——你就会有同一个根系往上长的感觉,越学越顺。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 3:03:00

C# override全面解析:多态、虚方法与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 3:01:49

GAF-PCNN-MATT:一维信号分类的Matlab实现与避坑指南

简介&#xff1a;本资源面向具备一定深度学习与图像处理基础的研究人员和技术开发者&#xff0c;提供一套基于Matlab实现的GAF-PCNN-MATT图像分类预测方案&#xff0c;用于应对高维复杂特征下传统方法精度不足的问题。模型将格拉姆角场&#xff08;GAF&#xff09;的时序转二维…

作者头像 李华
网站建设 2026/10/14 3:01:11

GCC源码编译报错:GMP、MPFR、MPC依赖库安装与配置指南

1. 从一条报错说起&#xff1a;GCC 编译环境依赖到底卡在哪如果你在 Linux 环境下尝试从源码编译 GCC&#xff0c;大概率会在configure阶段撞上这条报错&#xff1a;Error&#xff1a;Building GCC requires GMP 4.2, MPFR 3.1.0 and MPC 0.8.0这条信息看起来只是告诉你“缺东西…

作者头像 李华
网站建设 2026/10/14 3:00:16

a2svm:自适应加速SVM工具箱,自动核选择与增量训练实战

第一次看到 a2svm 这个包名时&#xff0c;我以为是某个项目内部随手起的代号&#xff0c;直到拿它处理一个特征维度不低、但样本只有几千条的信贷数据集&#xff0c;才发现它其实是一套完整的“自适应加速支持向量机”工具箱。a2svm 的核心价值&#xff0c;是把 SVM 的核选择、…

作者头像 李华
网站建设 2026/10/14 3:00:10

基于回归分析的人口数量预测:从数据清洗到滚动预测的工程实践

简介&#xff1a;这份资源是黑河学院统计系回归分析课程实验论文&#xff0c;面向统计学、数据分析方向的学生与研究者&#xff0c;用于系统掌握基于回归分析的人口数量预测方法。论文以人口数量与粮食产量、GDP等经济指标的关系为切入点&#xff0c;完整呈现一元线性回归、多元…

作者头像 李华