大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
核心概念与架构
这一课你将能做到
- 画出 K8s 架构:控制平面(API Server、etcd、Scheduler、Controller Manager)与工作节点(kubelet、kube-proxy)各自职责
- 说清核心对象关系链:Namespace → Deployment → ReplicaSet → Pod,以及 Service/Ingress 如何靠 Label 找到 Pod
- 解释 Label/Selector 的匹配规则,能预判「改标签」会引发什么后果
为什么要学
以后你敲的每一条 kubectl 命令,最终都打到一个叫 API Server 的组件上;集群的「真相」存在 etcd 里。不懂架构,遇到 Pending、CrashLoopBackOff、Service 后面没有 Endpoints 这类问题时只能瞎猜;懂了架构,你能立刻定位「这事归谁管、该看谁的日志」。
面试必考:「说说 K8s 架构」几乎是云原生方向的自我介绍题;「Deployment、ReplicaSet、Pod 什么关系」是第二高频。本课把这两题一次性打到能背的程度。
先建立图像
kubectl(你的终端) / CI 流水线
│
┌─────▼─────┐
│ API Server │ ←── 集群唯一入口:认证/鉴权/校验/存取
└─────┬─────┘
etcd(集群数据库:存所有对象的期望与实际状态)
│
┌───────────┴────────────┐
Scheduler Controller Manager
「新 Pod 放哪个节点」 「实际 ≠ 期望时自动修」(副本、节点、Job…)
│ 调度决定下发到节点
┌───────────▼───────────┐ ┌───────────────┐
│ Node 1 │ │ Node 2 │
│ kubelet ← 汇报状态、按单起容器、管探针 │
│ kube-proxy ← 维护 Service 转发规则(iptables/IPVS)│
│ 容器运行时(containerd) │
└────────────────────────┘ └───────────────┘
对象关系链(背下来):
Namespace(逻辑分区)
└─ Deployment(我要 3 个这样的 Pod)
└─ ReplicaSet(某一版本的副本集合)
└─ Pod(真正跑容器的地方,IP 随时可能变)
Service(稳定虚拟 IP + DNS,靠 label 选中一组 Pod)
Ingress(HTTP 路由,把外部流量按域名/路径分给 Service)
ConfigMap / Secret(配置与密钥,注入 Pod)
| 概念 | 一句话 | 本站对应 |
|---|---|---|
| Pod | 最小调度单元,1+ 容器共享网络 | backend 的一个运行实例 |
| Deployment | 副本管理 + 滚动更新 | backend 保持 3 副本 |
| Service | 稳定访问入口 | platform 用 http://backend 调 API |
| Label | 对象的「名牌」,selector 靠它抓人 | app=backend |
| Namespace | 集群内的逻辑隔离 | 业务放 coderoadmap,系统在 kube-system |
跟着做
步骤 1:解剖一份 YAML 的固定骨架
所有 K8s 对象 YAML 都是同一副骨架(以 Pod 为例):
apiVersion: v1 # 属于哪个 API 组:核心对象 v1,工作负载 apps/v1
kind: Pod # 对象类型
metadata: # 名字、标签、注解、所属命名空间
name: hello
labels:
app: hello
spec: # 期望状态——你要它长什么样
containers:
- name: web
image: nginx:1.27-alpine
记住公式:apiVersion + kind 说「这是什么」,metadata 说「它叫什么、贴什么标签」,spec 说「它应该是什么样」。后面学 Deployment、Service、Ingress,全是这副骨架换字段。
步骤 2:命名空间清单(可保存复用)
namespace.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: coderoadmap
集群装好后 kubectl apply -f namespace.yaml 即建好本站专属空间。直觉:default 放练手资源,kube-system 是系统组件(绝不能乱删),本站业务对象进 coderoadmap。
步骤 3:Label/Selector 绑定推演 + 验证命令
Service 靠 selector 抓 Pod:
# Pod 一侧
metadata:
labels:
app: backend
tier: api
# Service 一侧
spec:
selector:
app: backend # 只要求匹配这一项
推演:selector 是对 Pod 标签的子集匹配——Pod 可以有额外标签,但 selector 要求的每一个键值都必须存在。所以给 Pod 多加 tier=api 没影响;把 Pod 的 app 改掉,Service 立刻抓空。
集群可用后验证:
kubectl get pods -l app=backend --show-labels
步骤 4:排错三板斧预习(集群可用后逐条跑)
kubectl get pods # 有没有?状态是什么?
kubectl describe pod <pod名> # 发生了什么?看 Events 段
kubectl logs <pod名> # 应用自己说了什么?
口诀:get 看状态 → describe 看事件 → logs 看日志。九成入门问题靠这三条定位,顺序别反。
步骤 5:默写架构组件表再对照
合上资料写六行,再对照官方文档纠错。自测基准:
- API Server:唯一入口,所有读写经过它
- etcd:键值数据库,存集群全部状态
- Scheduler:决定新 Pod 放哪个节点
- Controller Manager:跑各种控制器,负责调谐
- kubelet:节点代理,管理本节点容器并汇报状态
- kube-proxy:维护 Service 的网络转发规则
步骤 6:打印对象全貌(集群可用后)
kubectl api-resources --namespaced=true
你会看到几十种对象。本 track 只需吃透:Pod、Deployment、ReplicaSet、Service、Ingress、ConfigMap、Secret、PVC、HPA——其余混个脸熟即可,面试也极少考冷门对象。
讲清楚要点
- 所有操作都过 API Server:kubectl、Dashboard、CI、甚至集群组件互相通信都走它,鉴权、审计、校验因此集中一处。「绕过 API 直接改 etcd」是严重事故行为。
- etcd 是唯一真相源:你 apply 的 YAML 与 Pod 实际状态都在里面。etcd 挂了整个集群变「只读僵尸」;生产要高可用,学习阶段不必操心。
- 控制器是 K8s 的灵魂:每种资源背后都有控制器在死循环「对比期望/实际 → 修正」。删掉 Deployment 管的 Pod 会自动重建,就是 ReplicaSet 控制器发现少了。
- 调度单位是 Pod 不是容器:同 Pod 容器共享网络命名空间(127.0.0.1 互访、共享端口空间)、可共享卷、同生共死。sidecar 模式(日志收集、代理)建立在这之上。
- Label 是一切关联的粘合剂:Service→Pod、Deployment→Pod、HPA→Deployment 全靠 selector。改标签等于改流量拓扑,发布与排错都要盯标签。
- Namespace 是逻辑隔离不是硬边界:它切分的是命名与配额,不是网络或权限的绝对屏障——真隔离要配 RBAC(第 11 课)与网络策略。
你可能会懵的地方
-
Master 和 Control Plane 什么关系? 同一个东西。旧文档叫 Master,现在统一叫「控制平面」。生产环境控制平面组件各跑多副本实现高可用;minikube 里它们全在一个节点上。
-
Pod IP 为什么不能写进配置文件? Pod 每次重建 IP 都会变。应用之间必须通过 Service DNS 名互访(如
http://backend),这正是 Service 存在的理由——类比 Compose 里用服务名而不是容器 IP。 -
kube-proxy 就是一个 Nginx 反向代理吗? 不是。它是每个节点上维护转发规则(iptables/IPVS 模式)的组件,让「访问 Service 虚拟 IP」能被转发到真实 Pod。流量并不经过某个中心代理进程。
-
命令式命令(kubectl run / expose)能用吗? 学习冒烟可以,但它们不留痕迹、不可复现。工程实践:一切进 YAML 文件、进 Git,用 apply 管理——这就是「声明式」的工程价值。
-
ReplicaSet 为什么不直接用? 它只管「保持 N 个副本」,不管发布策略。Deployment 在它之上加了滚动更新与回滚。日常只操作 Deployment,让 RS 当隐身中间层。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 只背对象名,不理解谁管谁 | 发布时乱删 ReplicaSet 酿事故 | 记住 Deployment→RS→Pod 管理链 |
| Service 的 selector 与 Pod 标签对不上 | Endpoints 为空,服务不通 | get endpoints 核对标签 |
| 所有资源堆在 default 且无标签规范 | 多服务后无法筛选排障 | 约定 app、tier 标签体系 |
| 把 Namespace 当安全边界 | 误以为不可能越权 | Namespace + RBAC 双管齐下 |
| 遇到异常只看 STATUS 列 | 漏掉 Events 里的关键线索 | 必用 describe 看事件 |
卡点急救
- apply 报
no matches for kind "Deployment" in version "v1":apiVersion 写错。Deployment 是apps/v1,Ingress 是networking.k8s.io/v1,Pod/Service/ConfigMap 这类核心对象才是v1。 - 报
namespaces "xxx" not found:YAML 里 metadata.namespace 指向不存在的命名空间,或忘了先kubectl create namespace。 - get 什么都没有,明明刚才创建了:九成是 context 或 namespace 不对——
kubectl config current-context、kubectl get pods -A全局看一眼,别在错误空间里找。
面试常问
-
说说 Kubernetes 的架构? 控制平面:API Server(唯一入口,负责认证、鉴权、准入与读写)、etcd(存集群全部状态)、Scheduler(为 Pod 选节点)、Controller Manager(运行各控制器维持期望状态)。工作节点:kubelet(节点代理,管理容器生命周期并汇报状态)、kube-proxy(维护 Service 转发规则)、容器运行时。所有变更经 API Server 写入 etcd,控制器持续调谐实际状态。
-
Deployment、ReplicaSet、Pod 三者什么关系? Deployment 是上层控制器,负责声明式发布:修改 Pod 模板会创建新 ReplicaSet,并按滚动策略让新旧 RS 副本数此消彼长;ReplicaSet 负责维持某个版本的固定副本数;Pod 是真正跑容器的单元。日常只操作 Deployment,不要直接动 RS。
-
Label 和 Annotation 的区别? Label 是有筛选语义的键值对,被 selector 消费(Service 选 Pod、HPA 选 Deployment),要精简规范;Annotation 是无筛选语义的元数据,存描述性信息与工具配置,可放大量非结构化数据。一句话:Label 给机器筛选用,Annotation 给人和工具读。
自测三问
- Scheduler 和 Controller Manager 分别负责什么?
- 为什么说「生产环境不要直接管理裸 Pod」?
- 本站 platform 和 backend 为什么是两个 Deployment,而不是塞进一个 Pod?
小结一句话
控制平面(API Server/etcd/Scheduler/Controller)存期望并调谐,节点上 kubelet/kube-proxy 落地容器与流量规则,Label 把 Service、Deployment 与 Pod 粘在一起——架构图和对象链装进脑子,下一课装本地集群动手。
延伸
- Kubernetes Components
- Objects In Kubernetes
- 下一课预告:安装 minikube 与 kubectl,起一个真正能跑的本地集群,跑通你的第一个 Pod 与 Service。