← 返回 FDE 培养总览 FDE 培养 · 知识点深化 · Kubernetes 基础
知识点深化 · Kubernetes

Kubernetes 基础:Pod、Deployment、Service、ConfigMap 与 YAML 编写

Docker 解决了"单个容器怎么跑",但几十上百个容器谁来管?挂了谁自动拉起来?流量怎么分给多副本?这就是 Kubernetes(K8s)干的事:它是容器集群的自动调度管家。这一页带你从 kubectl 命令到手写 Deployment/Service YAML,把最核心的四个对象练熟。

① 小白第一课怎么学(4 步走,约 90 分钟)

K8s 概念多,先抓主线:你声明"我要几个副本",K8s 负责凑齐。

1建立对象关系(15 分钟)
读②③:Pod 是最小单位,Deployment 管 Pod 副本数和滚动更新,Service 给 Pod 一个稳定访问入口。
2跑通 minikube/本地集群(20 分钟)
读④:用 kubectl create deployment 起一个 nginx。
3手写 YAML 并 apply(30 分钟)
跟着⑤写 Deployment+Service YAML,kubectl apply -f 起来。
4排错+刷题(25 分钟)
读⑥ CrashLoopBackOff 排查,做⑦⑩。重点 events 和 describe。
本课小目标学完你要能:① 说清 Pod/Deployment/Service 各管什么;② 手写一份可用的 Deployment YAML;③ 用 kubectl describe/logs 定位 Pod 起不来的原因;④ 知道 ConfigMap 怎么注入配置。

② 一图看懂:K8s 对象关系

Kubernetes 集群 Pod 最小运行单位,装容器 Deployment 管副本数/滚动更新 Service 稳定访问入口/负载均衡 ConfigMap/Secret 配置与密钥注入 kubectl 命令 apply/get/describe/logs 易错:CrashLoop/镜像拉取 readiness/liveness 探针
读法:Deployment 负责"凑齐 N 个 Pod",Service 负责"把流量稳定地送给这些 Pod",ConfigMap 负责"往 Pod 里塞配置"。Pod 会随时重建换 IP,所以不能直连 Pod。

③ 本质直觉:声明式,而非命令式

以前运维是命令式:你敲 docker run,起一个。挂了再手动起一个。K8s 反过来,是声明式:你写一份 YAML 说"我希望有 3 个 nginx Pod 在跑",交给 K8s,它负责让现实状态不断逼近这个期望状态。

关键洞察:Pod 是"一次性"的——它随时可能被销毁、重建、调度到别的机器,IP 每次都变。所以你永远不要直接连 Pod 的 IP。Service 就是那个固定不变的门牌号,背后自动跟着当前健康的 Pod。

自愈:某个 Pod 死了,Deployment 控制器发现"现在只有 2 个,期望 3 个",立刻在某处补一个新的。这就是"自愈",不用人管。

滚动更新:改了镜像版本,Deployment 会"起新 Pod、摘旧 Pod"交替进行,全程不中断流量。

Service 固定IP Pod-A Pod-B Pod-C(新) Pod 随便换,入口不变 流量由 Service 负载均衡
为什么需要 label selectorService 怎么知道该转发给哪些 Pod?靠"标签选择器"。Deployment 给 Pod 打标签 app: web,Service 选 app: web,两者靠标签"相亲"关联。改标签就断联,这是最常踩的坑。

④ 完整体系:kubectl、YAML、探针、ConfigMap

kubectl 高频命令

命令作用
kubectl get pods列出 Pod(-o wide 看节点/IP)
kubectl get deploy,svc列出 Deployment 和 Service
kubectl apply -f xxx.yaml声明式创建/更新对象
kubectl describe pod 名看 Pod 详情和 events(排错关键)
kubectl logs 名 -f看容器日志
kubectl exec -it 名 -- sh进容器
kubectl scale deploy/web --replicas=5扩缩容
kubectl delete -f xxx.yaml删除对象

一份完整的 Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy
  labels: {app: web}
spec:
  replicas: 3                 # 期望 3 个副本
  selector:
    matchLabels: {app: web}   # 管哪些 Pod
  template:                   # 下面是 Pod 模板
    metadata:
      labels: {app: web}      # Pod 标签,必须和 selector 对上
    spec:
      containers:
      - name: web
        image: myapp:1.0
        ports:
        - containerPort: 8000
        resources:
          requests: {cpu: "100m", memory: "128Mi"}
          limits:   {cpu: "500m", memory: "256Mi"}
        readinessProbe:       # 就绪探针:不通就不接流量
          httpGet: {path: /health, port: 8000}
          initialDelaySeconds: 3
        livenessProbe:        # 存活探针:不通就重启容器
          httpGet: {path: /health, port: 8000}
          periodSeconds: 10

配套的 Service YAML

apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector: {app: web}        # 挑带 app=web 标签的 Pod
  ports:
  - port: 80                  # Service 端口
    targetPort: 8000          # 转发到容器端口
  type: ClusterIP             # 集群内访问;NodePort/LoadBalancer 对外

三种 Service 类型

类型用途谁能访问
ClusterIP默认,集群内部虚拟 IP集群内其他 Pod
NodePort在每个节点开一个固定端口集群外部(IP:NodePort)
LoadBalancer对接云厂商负载均衡公网用户

ConfigMap:配置与镜像解耦

# 建配置
kubectl create configmap app-config --from-literal=LOG_LEVEL=info

# YAML 里以环境变量注入
env:
- name: LOG_LEVEL
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: LOG_LEVEL

密钥(数据库密码)用 Secret,用法和 ConfigMap 一样,只是内容 base64 编码、更敏感。

⑤ 用法场景与典型例题

例1(基础·起一个 Deployment)用命令快速起一个 2 副本的 nginx
kubectl create deployment 一行搞定,再 scale。
① kubectl create deployment nginx --image=nginx:1.25。
② kubectl scale deployment nginx --replicas=2。
③ kubectl get pods 看到 2 个 Running。
解析:create 只管"跑起来",副本数、探针等细节后续用 YAML 管理;生产建议直接 apply YAML。
例2(Service 打通)Pod 里服务监听 8000,希望集群内通过 web-svc 访问,写 Service 的 ports
port 是 Service 自己的端口,targetPort 是容器端口。
① Service 的 port: 80(别人访问 svc:80)。
② targetPort: 8000(转发到容器的 8000)。
③ selector 必须 app: web,和 Pod 标签一致。
答案:别人访问 http://web-svc(默认 80)→ 转发到 Pod 的 8000。
例3(滚动更新)把镜像从 myapp:1.0 升到 2.0,且不中断服务
改 image 后 apply,Deployment 默认就是滚动更新。
① kubectl set image deployment/web-deploy web=myapp:2.0。
② kubectl rollout status deployment/web-deploy 看进度。
③ 过程中它先起 2.0 Pod,就绪后再摘 1.0 Pod,逐步替换。
④ 出问题就 kubectl rollout undo deployment/web-deploy 回滚。
答案:readinessProbe 是滚动更新安全的关键——探针不通的新 Pod 不会接流量,避免把坏版本放出去。
探针三件事readiness(就绪)不通=不接流量但不重启;liveness(存活)不通=重启容器;startup(启动慢的老应用)给宽限期。三者别搞混。

⑥ 高频错误诊断(4 条)

错误 1:CrashLoopBackOff(容器反复重启)容器起来又挂、挂了又起。排查顺序:kubectl describe pod 看 events → kubectl logs 名 --previous 看上一次崩溃的日志。常见原因:应用启动即报错、配置/环境变量缺失、监听端口配错。
错误 2:ImagePullBackOff(镜像拉不下来)镜像名/标签写错、私有仓库没配 imagePullSecrets、网络拉不到。describe events 会明确报 "ImagePullBackOff" 或 "ErrImageNeverPull"。
错误 3:Service 建好了却 503/连不通90% 是 selector 和 Pod 标签对不上。Service 选 app: web,Pod 标签却是 app: www,一个都选不中。用 kubectl get endpoints web-svc 看后端列表,是空的就是标签没对上。
错误 4:Pod 一直 Pending 起不来describe events 看原因:常见是资源不足(requests 太大,节点没那么多 CPU/内存)、或 nodeSelector/亲和性选不到节点。

⑦ 考点真题演练(4 题)

考点分布

考法出题形式应对
对象职责Pod/Deployment/Service 各管什么Pod=实例,Deployment=副本,Service=入口
声明式对比命令式写期望状态,控制器不断逼近
探针readiness vs liveness一个管接流量,一个管重启
排错CrashLoop/连不通describe + logs + endpoints

真题基础1. Kubernetes 中最小的部署单位是?

真题中档2. Service 的 selector 与 Pod 标签不匹配,会发生什么?

真题中档3. readinessProbe 失败时,K8s 会怎么做?

真题拔高4. Pod 状态是 CrashLoopBackOff,第一步应该做什么?

⑧ 必背命令/知识点卡

三对象:Pod / Deployment / Service 实例/副本/入口
声明式:kubectl apply -f xxx.yaml 写期望状态
看对象:kubectl get pods,deploy,svc -o wide 看详情
排错:describe pod / logs --previous / get endpoints 三板斧
三探针:readiness 摘流量 / liveness 重启 / startup 宽限 别混
配置:ConfigMap 普通配置,Secret 密钥 env 或 volume 注入
铁律:selector 标签必须和 Pod labels 一致 503 多半是这

⑨ 应用输出:把一个 Web 服务部署到 K8s

场景:已有镜像 myapp:1.0,监听 8000,要在 K8s 跑 3 副本并能从集群外访问
① 写 Deployment:replicas=3,容器镜像 myapp:1.0,containerPort=8000,配 readiness 探针打 /health。
② 写 Service:type: NodePort,selector app=web,port 80 → targetPort 8000。
③ 建 ConfigMap:kubectl create configmap app-config --from-literal=LOG_LEVEL=info,在 Deployment 里 env 注入。
④ apply:kubectl apply -f deploy.yaml -f svc.yaml。
⑤ 验证:kubectl get pods 三个都 Running;kubectl get svc 看到 NodePort(如 31234);访问 节点IP:31234。
⑥ 自愈演练:kubectl delete pod 任意一个,几秒后 Deployment 自动补一个新 Pod,副本数回到 3。
口述部署思路"写 Deployment 声明要 3 副本和探针,写 Service 暴露入口,apply 下去;K8s 自动凑齐 Pod、挂了自愈、流量通过 Service 负载均衡;出问题用 describe+logs 定位。"

⑩ 分层练习 15 题(基础 5 + 中档 5 + 拔高 5)

▍基础 5 题

基础1Pod 和 Deployment 是什么关系?
Deployment 管理一组 Pod 的副本数和更新策略,Pod 是它创建出来的实例。
基础2声明式创建对象用哪个命令?
kubectl apply -f xxx.yaml。
基础3ClusterIP 类型 Service 谁能访问?
只有集群内部的 Pod 能访问,是默认类型。
基础4看 Pod 详细事件排错用?
kubectl describe pod 名,最下面 Events 区。
基础5ConfigMap 用来存什么?
非敏感配置(日志级别、参数);敏感的密码用 Secret。

▍中档 5 题

中档6readinessProbe 和 livenessProbe 失败的区别?
readiness 失败=摘流量不重启;liveness 失败=重启容器。
中档7Service 的 port 和 targetPort 区别?
port=Service 对外暴露的端口;targetPort=转发到容器的端口。
中档8把副本从 3 扩到 6 怎么做?
kubectl scale deploy/名 --replicas=6,或改 YAML replicas 再 apply。
中档9怎么回滚到上一个版本?
kubectl rollout undo deployment/名。
中档10为什么不要直连 Pod IP?
Pod 会被重建、换 IP、调度到别的节点,IP 不稳定;应通过 Service 访问。

▍拔高 5 题

拔高11ImagePullBackOff 怎么排查?
describe 看 events 具体原因:镜像名/标签拼错?私有仓库需要 imagePullSecrets?节点网络能否拉到镜像?
拔高12Pod 一直 Pending,describe 报 insufficient cpu,怎么办?
requests 设太大超过节点可用资源。调小 requests/limits,或给集群加节点。
拔高13滚动更新时为什么要配 readinessProbe 才安全?
没有探针,新 Pod 一起好就被接流量,若应用还没就绪就会报错;探针确保真正就绪才进后端。
拔高14requests 和 limits 的区别?
requests=调度保底(保证有这么多资源);limits=上限(超过 CPU 被限流、内存超限会被 OOMKill)。
拔高15kubectl get endpoints 为空说明什么?
Service 没选中任何健康 Pod:标签 selector 对不上,或所有 Pod readiness 都没通过。

⑪ 记忆口诀 + 7 天复习计划

三句口诀 ① Pod 是小兵,Deployment 管人数,Service 是门牌号。
② 声明式写 YAML,apply 下去它自愈。
③ 连不通查标签,起不来查探针,崩溃先 describe 再 logs。
天任务自检
第 1 天读②③,起一个 nginx Deploymentget pods 看到 Running
第 2 天背命令卡 + 做基础 1-5基础全对
第 3 天手写 Deployment+Service YAML 并 apply访问通
第 4 天做中档 6-10,演练滚动更新和回滚rollout 正常
第 5 天做拔高 11-15 + 真题 4 题会造故障会排
第 6-7 天故意删一个 Pod 观察自愈,口述部署流程不看资料全默对

← 返回 FDE 培养总览