核心概念
📋 本章概览
| 主题 | 考试权重 | 重要程度 |
|---|---|---|
| Pod 生命周期 | ★★★★★ | 必考 |
| kubectl 操作 | ★★★★★ | 必考 |
| Deployments | ★★★★★ | 高频考点 |
| ReplicaSets | ★★★★☆ | 重要 |
| 命名空间 | ★★★★☆ | 重要 |
| Labels/Selectors | ★★★★☆ | 重要 |
💡 考试占比:Application Design and Build 占 CKAD 考试的 20%
🎯 学习目标
学完这一章,你应该能够:
- 从零理解 Pod 是什么 —— 为什么它是 Kubernetes 的最小部署单元
- 创建和管理 Pods、ReplicaSets 和 Deployments
- 熟练使用 kubectl 进行各种操作(考试 90% 的时间你都在敲 kubectl)
- 正确使用命名空间隔离资源
- 用 Labels/Selectors 组织和筛选资源
- 掌握 Deployment 的滚动更新和回滚(实操高频考题)
📝 学习建议
通俗理解: 学 CKAD 核心概念,就像学开一家连锁餐厅。
想象你要开一家连锁餐厅,每天要运营多个门店(容器化应用):
- Pod(工位) —— 一个厨师的工作台。上面可能只有一套灶具(单容器),也可以有灶具 + 配菜台(多容器)。同一个工位上的设备共享水电和台面空间(共享网络和存储)
- ReplicaSet(排班表) —— 确保"高峰期永远有 3 个厨师在岗"。一个厨师请假了?排班表自动叫替补来补位
- Deployment(运营经理) —— 管理排班表,还负责"换菜单"。新菜单推出时,不是所有门店同时换(会导致停业),而是一家一家换(滚动更新)。换完发现新菜难吃?经理一键恢复旧菜单(回滚)
- Namespace(不同城市的分部) —— 北京分部和上海分部各自独立运营,厨师名字可以重复。"dev 命名空间"和"prod 命名空间"各有各的资源,互不干扰
- Labels(工牌标签) —— 每个厨师的工牌上贴着"岗位=主厨"、"区域=北京"。经理可以快速筛选"所有北京的主厨"
CKAD 是纯实操考试——没有选择题,全程在终端敲命令。核心概念是你操作的基础对象,考试中几乎每道题都会用到 Pod、Deployment 和 kubectl。如果你不理解这些概念之间的关系,后面学 ConfigMap、Service、Ingress 都会很吃力。
本章知识地图:
CKAD 核心概念
│
├── Pod(最小部署单元)
│ ├── 容器共享网络 + 存储
│ ├── 生命周期:Pending → Running → Succeeded/Failed
│ └── 重启策略:Always / OnFailure / Never
│
├── kubectl(命令行工具 = 你的考试武器)
│ ├── 创建:run / create / apply
│ ├── 查看:get / describe / logs
│ ├── 修改:edit / set / label
│ ├── 删除:delete
│ └── 调试:exec / port-forward / explain
│
├── Deployment + ReplicaSet(应用管理)
│ ├── Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod
│ ├── 滚动更新:kubectl set image
│ └── 回滚:kubectl rollout undo
│
├── Namespace(资源隔离)
│ └── 切换:kubectl config set-context --current --namespace=
│
└── Labels & Selectors(资源组织)
├── 打标签:kubectl label
└── 筛选:kubectl get pods -l key=value
Kubernetes 整体架构
在深入具体概念之前,先看一眼 Kubernetes 集群的全局架构:
图解说明:
- 这张图在讲什么:一个 Kubernetes 集群由 Control Plane(控制平面) 和 Worker Nodes(工作节点) 组成。Control Plane 负责"大脑决策"(调度、监控、API),Worker Node 负责"干活"(跑 Pod)。
- 你应该先看哪里:先看左侧 Control Plane 的 API Server —— 它是集群的"前台总机",所有请求(kubectl 命令、其他组件通信)都经过它。然后看右侧 Node 上的 kubelet 和容器运行时。
- 考试常见问法:CKAD 不直接考架构组件,但理解架构能帮你判断"为什么 Pod 调度失败"、"为什么 Service 不通"——这些排障题的根因往往和架构有关。
📖 Pod 到底是什么?
术语:Pod
- 一句话解释:Kubernetes 里最小的部署单元。你不能直接部署一个容器,必须把它放进 Pod 里。
- 形象比喻:Pod 像一个"工位"——上面可以放一套灶具(单容器),也可以放灶具 + 配菜台(多容器)。同一个工位上的设备共享水电(网络)和台面空间(存储卷)。
- 考试怎么考:几乎每道题都涉及 Pod。最基础的考法是"创建一个满足特定要求的 Pod"。
- 最易混淆:Pod ≠ 容器。一个 Pod 可以包含多个容器,它们共享 IP 地址和存储卷。
为什么不直接运行容器,而要包一层 Pod?因为 Kubernetes 需要一个统一的"调度单元"。Pod 提供了共享的网络命名空间(同一个 Pod 里的容器用 localhost 互相通信)和共享存储卷。这样紧密关联的容器(比如应用 + 日志收集器)可以放在同一个 Pod 里,像"坐同一辆班车"一样被调度到同一个节点。
Pod 架构
图解说明:
- 这张图在讲什么:一个 Pod 内部的结构 —— 多个容器共享同一个网络命名空间(同一个 IP),并且可以挂载共享的 Volume。
- 你应该先看哪里:先看 Pod 的边界(外框),再看里面的容器和 Volume 之间的连线关系。注意容器之间通过
localhost互通。 - 考试常见问法:考试会让你在 YAML 里定义多容器 Pod 并共享 Volume。理解这张图的关键是搞清楚"什么在 Pod 级别共享,什么在容器级别隔离"。
┌─────────────────────────────────────────────────────────┐
│ Pod │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 共享网络命名空间 │ │
│ │ (localhost 相互访问) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Container 1 │ │ Container 2 │ │ Container N │ │
│ │ (nginx) │ │ (sidecar) │ │ (...) │ │
│ │ │ │ │ │ │ │
│ │ Port: 80 │ │ Port: 9090 │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └────────────────┼─────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 共享存储卷 (Volumes) │ │
│ │ /data ←──────────────────────→ /data │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Pod IP: 10.244.1.5 │
│ Node: worker-node-1 │
└─────────────────────────────────────────────────────────┘
图解说明:
- 这张图在讲什么:一个 Pod 内部的结构——多个容器共享同一个网络和存储。
- 你应该先看哪里:先看"共享网络命名空间",这是 Pod 存在的核心原因。容器之间用 localhost 加端口号互访,不需要跨网络。
- 考试常见问法:给你一个多容器 Pod 场景,让你判断容器之间如何通信(答案:localhost),或让你配置共享 Volume。
创建 Pod
CKAD 是实操考试,速度就是分数。创建 Pod 有两种方式:命令式(快、适合考试)和声明式(完整、适合复杂配置)。
命令式方式(考试推荐,能省很多时间):
# 最简单的方式——一行搞定
kubectl run nginx --image=nginx
# 指定端口
kubectl run nginx --image=nginx --port=80
# 带环境变量
kubectl run nginx --image=nginx --env="DB_HOST=mysql"
# 带资源限制
kubectl run nginx --image=nginx --requests="cpu=100m,memory=256Mi"
# ⭐ 考试必用:生成 YAML 模板,然后再修改细节
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
💡 为什么推荐命令式? CKAD 考试一共 120 分钟,大约 15-20 道题。手写 YAML 太慢,用
--dry-run=client -o yaml生成骨架再修改,能省一半时间。
声明式方式(需要复杂配置时用):
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
env: production
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
resources 中的 requests 和 limits 有什么区别? requests 是"保底"——调度器保证节点至少有这么多资源给你;limits 是"天花板"——容器最多只能用这么多。超过 memory limits 会被 OOM Kill(直接杀掉),超过 cpu limits 会被限流(throttle,变慢但不杀)。
Pod 生命周期
Pod 从创建到结束会经历几个状态。理解这些状态是排查故障的基础——当 Pod 卡在某个状态时,你需要知道它卡在哪个阶段、可能是什么原因。
创建 Pod
│
▼
┌─────────┐
│ Pending │ ← 等待调度或拉取镜像
└────┬────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Running │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Waiting │ │ Running │ │Terminated│ │
│ │(容器状态)│ │(容器状态)│ │(容器状态) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└───────────────────┬─────────────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌─────────┐ ┌─────────┐
│Succeeded │ │ Failed │ │ Unknown │
│ (所有容器 │ │(至少一个 │ │(无法获取│
│ 成功退出)│ │ 失败退出)│ │ 状态) │
└──────────┘ └─────────┘ └─────────┘
Pod 状态速查
| 状态 | 描述 | 常见原因 | 一句话记忆 |
|---|---|---|---|
| Pending | 已创建但未运行 | 调度中、拉取镜像 | "在排队等位" |
| Running | 至少一个容器运行 | 正常状态 | "已上岗干活" |
| Succeeded | 所有容器成功终止 | Job 完成 | "活干完了,下班" |
| Failed | 至少一个容器失败 | 应用错误、OOM | "出了事故" |
| Unknown | 无法获取状态 | 节点通信问题 | "失联了" |
容器状态
Pod 是 Running 不代表里面每个容器都正常。Pod 状态和容器状态是两层概念:
| 容器状态 | 描述 | 一句话记忆 |
|---|---|---|
| Waiting | 等待启动(拉取镜像、等待依赖) | "还没准备好" |
| Running | 容器正在运行 | "在干活" |
| Terminated | 容器已终止(成功或失败) | "已退出" |
⚠️ 考试视角:kubectl describe pod 会显示每个容器的具体状态和原因(Reason),这是排查问题的第一步。
重启策略
当容器崩溃时,Kubernetes 会根据重启策略决定是否拉起来。选错重启策略是常见的考试失分点。
spec:
restartPolicy: Always # 默认,适合长期运行服务
# restartPolicy: OnFailure # 失败时重启,适合 Job
# restartPolicy: Never # 不重启,适合一次性任务
| 策略 | 描述 | 使用场景 | 一句话记忆 |
|---|---|---|---|
| Always | 总是重启 | Deployment、DaemonSet | "永不放弃" |
| OnFailure | 失败时才重启 | Job | "失败了再来一次" |
| Never | 不重启 | 调试、一次性脚本 | "做完拉倒" |
💡 常见陷阱:考试让你创建 Job 时,如果你忘记设
restartPolicy: OnFailure(或Never),Job 的 Pod 会一直重启,永远不会变成 Completed 状态。
🔧 kubectl:你的考试武器
术语:kubectl
- 一句话解释:Kubernetes 的命令行工具,你通过它跟集群"对话"——创建资源、查看状态、排查问题。
- 形象比喻:kubectl 就像"遥控器"。你不需要走进机房(API Server),拿着遥控器就能操作一切。
- 考试怎么考:CKAD 全程在终端操作,kubectl 是你唯一的工具。打字速度和命令熟练度直接决定分数。
- 最易混淆:
kubectl applyvskubectl create。create 只能创建新资源,apply 可以创建也可以更新。考试中推荐统一用 apply。
创建资源
# 从 YAML 创建(声明式,推荐)
kubectl apply -f pod.yaml
# 快速创建 Pod(命令式,考试快)
kubectl run nginx --image=nginx
# 快速创建 Deployment
kubectl create deployment nginx --image=nginx --replicas=3
# ⭐ 考试必备:生成 YAML 模板,不实际创建
kubectl run nginx --image=nginx --dry-run=client -o yaml
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml
--dry-run=client -o yaml是什么意思?--dry-run=client让 kubectl 只"假装"创建,不真的发请求给集群;-o yaml把结果输出为 YAML 格式。两个组合起来 = "帮我生成 YAML 模板"。考试中你几乎每道题都会用到这个组合。
查看资源
排查问题的第一步,永远是"看看现在什么情况"。
# 列出 Pods(最常用)
kubectl get pods
kubectl get pods -o wide # 显示更多信息(IP、节点)
kubectl get pods -o yaml # YAML 格式输出
kubectl get pods --show-labels # 显示标签
kubectl get pods -l app=nginx # 按标签筛选
kubectl get pods -A # 所有命名空间
kubectl get pods -n kube-system # 指定命名空间
# 查看 Pod 详细信息和事件(排查故障的核心命令)
kubectl describe pod nginx
# 查看日志(应用报错时第一时间看日志)
kubectl logs nginx # 当前日志
kubectl logs nginx -f # 实时跟踪(像 tail -f)
kubectl logs nginx --tail=100 # 最后 100 行
kubectl logs nginx -c sidecar # 多容器 Pod 指定容器
kubectl logs nginx --previous # ⭐ 上次崩溃的日志(排查 CrashLoopBackOff 必用)
# 查看资源使用
kubectl top pods
kubectl top nodes
⚠️ 考试视角:
kubectl describe和kubectl logs --previous是排查三大金刚中的两个。第三个是kubectl get events。碰到 Pod 不正常,按这个顺序排查:describe → logs → events。
修改资源
# 编辑资源(打开编辑器直接改)
kubectl edit pod nginx
# 更新镜像
kubectl set image pod/nginx nginx=nginx:1.22
# 打标签
kubectl label pod nginx env=prod
kubectl label pod nginx env=staging --overwrite # 覆盖已有标签
kubectl label pod nginx env- # 删除标签
# 添加注解(annotation,和 label 不同,不参与筛选)
kubectl annotate pod nginx description="My pod"
# 替换资源
kubectl replace -f pod.yaml
kubectl replace -f pod.yaml --force # 强制替换(删除重建)
删除资源
# 删除 Pod
kubectl delete pod nginx
# 从文件删除
kubectl delete -f pod.yaml
# ⭐ 强制删除(跳过优雅终止期,考试省时间)
kubectl delete pod nginx --force --grace-period=0
# 删除所有 Pods
kubectl delete pods --all
kubectl delete pods --all -n dev
# 按标签删除
kubectl delete pods -l app=nginx
💡 为什么考试要用
--force --grace-period=0? 正常删除一个 Pod 需要等待 30 秒的优雅终止期(graceful shutdown)。考试中每秒都珍贵,加上这个参数可以立即删除,省下等待时间。
进入容器和端口转发
调试应用问题时,经常需要"钻进"容器里看看:
# 进入容器(交互式 shell)
kubectl exec -it nginx -- /bin/bash
kubectl exec -it nginx -- /bin/sh # 容器里没 bash 时用 sh
# 执行单个命令(不进入交互)
kubectl exec nginx -- ls /etc
kubectl exec nginx -- cat /etc/nginx/nginx.conf
kubectl exec nginx -- env
# 多容器 Pod 指定容器
kubectl exec -it nginx -c sidecar -- /bin/sh
# 端口转发(本地测试 Pod 服务)
kubectl port-forward nginx 8080:80
kubectl port-forward svc/nginx-service 8080:80
exec -it中的-i和-t是什么意思?-i= interactive(保持标准输入打开),-t= tty(分配一个终端)。两个合在一起,你才能像 SSH 一样在容器里敲命令。如果只执行一条命令(如ls),不需要-it。
📖 Deployment:应用的"运营经理"
术语:Deployment
- 一句话解释:管理无状态应用的控制器。你告诉它"我要 3 个 nginx 副本",它负责创建、维护、更新这 3 个副本。
- 形象比喻:Deployment 就是连锁餐厅的"运营经理"。经理确保每家门店(Pod)都在营业,有门店关了就开新的补上;要换菜单(更新镜像)时,一家一家换,保证不停业。
- 考试怎么考:创建 Deployment、更新镜像(滚动更新)、回滚到之前版本——这三个操作是高频考题。
- 最易混淆:Deployment vs ReplicaSet。你几乎永远不需要直接操作 ReplicaSet,Deployment 会帮你管理它。
Deployment、ReplicaSet、Pod 的关系
图解说明:
- 这张图在讲什么:kubectl 如何通过 Deployment 将容器化应用部署到 Kubernetes 集群中。Deployment 指示 Kubernetes 创建和更新应用实例。
- 你应该先看哪里:先看用户的 kubectl 命令如何到达 API Server,再看 Deployment 如何在 Node 上创建 Pod。
- 考试常见问法:
kubectl create deployment和kubectl apply -f是创建 Deployment 的两种方式。考试通常要求你用命令行快速创建,然后用kubectl get deploy,rs,pods验证三者关系。
很多初学者搞不清这三者的关系。简单来说:Deployment 管 ReplicaSet,ReplicaSet 管 Pod。就像公司组织架构——总监(Deployment)管经理(ReplicaSet),经理管员工(Pod)。
ReplicaSet(副本集) — 确保"指定数量的 Pod 副本始终在运行"。如果一个 Pod 挂了,ReplicaSet 会自动创建新的补上。你不用直接创建 ReplicaSet,Deployment 在背后会帮你创建和管理它。
┌─────────────────────────────────────────────────────────┐
│ Deployment │
│ (nginx-deploy) │
│ │
│ replicas: 3 │
│ strategy: RollingUpdate │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ReplicaSet │ │
│ │ (nginx-deploy-7d6f...) │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │ │
│ │ │ nginx │ │ nginx │ │ nginx │ │ │
│ │ │ :1.21 │ │ :1.21 │ │ :1.21 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
图解说明:
- 这张图在讲什么:Deployment → ReplicaSet → Pod 的三层管理结构。
- 你应该先看哪里:先看
replicas: 3,这决定了 ReplicaSet 要维持 3 个 Pod 副本。 - 考试常见问法:让你"扩容到 5 个副本"或"更新镜像后查看滚动状态"。理解这个层级关系,你就知道为什么
kubectl get rs能看到新旧两个 ReplicaSet。
创建 Deployment
命令式(考试快速出活):
# 创建 Deployment
kubectl create deployment nginx --image=nginx
# 指定副本数
kubectl create deployment nginx --image=nginx --replicas=3
# 指定端口
kubectl create deployment nginx --image=nginx --port=80
# 生成 YAML 模板
kubectl create deployment nginx --image=nginx --replicas=3 --dry-run=client -o yaml > dep.yaml
声明式(完整配置):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
⚠️ 关键注意:
selector.matchLabels和template.metadata.labels必须匹配。这是很多人写 YAML 时犯的错——两边标签不一致,Deployment 就无法管理 Pod,直接报错。
管理 Deployment
# 扩缩容(考试常考)
kubectl scale deployment nginx --replicas=5
# 自动扩缩容(根据 CPU 使用率)
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80
# 查看状态
kubectl get deployment nginx
kubectl describe deployment nginx
# 查看 ReplicaSet(更新时会看到新旧两个 RS)
kubectl get rs
图解说明:
- 这张图在讲什么:Deployment 通过调整
replicas数量实现应用的水平扩缩容。扩容时新增 Pod 被调度到集群中的不同节点,缩容时多余的 Pod 被终止。 - 你应该先看哪里:先看 Service 如何将流量分发到多个 Pod,再看 Pod 数量的变化(从少到多)。注意每个 Node 上可以运行多个 Pod。
- 考试常见问法:
kubectl scale deployment/NAME --replicas=N是手动扩缩容。kubectl autoscale是 HPA 自动扩缩容。考试常让你把副本数从 3 调到 5,或者根据场景选择合适的副本数。
滚动更新——如何"不停业换菜单"
滚动更新是 Deployment 最重要的功能。它的原理是:创建一个新的 ReplicaSet,逐步把 Pod 从旧 RS 迁到新 RS,直到所有 Pod 都跑新版本。这个过程中,始终有 Pod 在服务,用户不会感知到中断。
图解说明:
- 这张图在讲什么:Deployment 滚动更新的过程 —— 新版 Pod 逐个替换旧版 Pod,Service 始终将流量导向可用的 Pod,用户感知不到中断。
- 你应该先看哪里:先看新旧两组 Pod 的数量变化(旧的减少,新的增加),再看 Service 如何动态切换指向。
- 考试常见问法:
kubectl set image deployment/NAME CONTAINER=IMAGE触发更新,kubectl rollout status查看进度,kubectl rollout undo回滚 —— 这三条命令是滚动更新的核心操作。
# ⭐ 更新镜像(考试高频)
kubectl set image deployment/nginx nginx=nginx:1.22
# 更新资源限制
kubectl set resources deployment/nginx -c nginx --limits=cpu=200m,memory=512Mi
# 查看滚动进度
kubectl rollout status deployment/nginx
# 暂停滚动(需要分阶段发布时)
kubectl rollout pause deployment/nginx
# 恢复滚动
kubectl rollout resume deployment/nginx
回滚——"新菜单翻车了"
更新出问题时,回滚让你快速恢复到之前的版本。Deployment 会保留历史 ReplicaSet,所以回滚本质上就是"重新激活旧的 ReplicaSet"。
# 查看历史版本
kubectl rollout history deployment/nginx
# 查看特定版本的详情
kubectl rollout history deployment/nginx --revision=2
# ⭐ 回滚到上一版本
kubectl rollout undo deployment/nginx
# 回滚到指定版本
kubectl rollout undo deployment/nginx --to-revision=1
💡 考试典型题:创建 Deployment → 更新镜像 → 查看滚动状态 → 回滚。这四步串起来就是一道完整的考题,务必练到肌肉记忆。
更新策略
Deployment 支持两种更新策略,选哪个取决于你的应用是否允许"新旧版本同时存在":
spec:
strategy:
type: RollingUpdate # 或 Recreate
rollingUpdate:
maxSurge: 25% # 更新时最多可以多出多少 Pod
maxUnavailable: 25% # 更新时最多可以少多少 Pod
| 策略 | 描述 | 使用场景 | 一句话记忆 |
|---|---|---|---|
| RollingUpdate | 逐步替换(默认) | 零停机更新 | "边拆边建,不停业" |
| Recreate | 先全删,再全建 | 不允许多版本共存(如数据库迁移) | "先关门装修,再开门" |
maxSurge 和 maxUnavailable 怎么理解? 假设 replicas=4,两者都是 25%:更新时最多同时有 5 个 Pod(4 + 1 surge),最少有 3 个 Pod 在服务(4 - 1 unavailable)。考试中一般不会改这两个参数,但要理解它们的含义。
🏷️ 命名空间:资源的"隔离间"
图解说明:
- 这张图在讲什么:Kubernetes 集群中 Node 和 Pod 的关系 —— 每个 Node 上运行着 kubelet(负责管理 Pod)和容器运行时(负责运行容器)。Node 是实际的工作机器,Pod 被调度到 Node 上执行。
- 你应该先看哪里:先看 Node 这个边界框,它代表一台机器(物理机或虚拟机)。再看 Node 内部的 Pod 和系统组件(kubelet、kube-proxy)。
- 考试常见问法:理解 Node-Pod 关系能帮你排障。比如 Pod 状态 Pending 可能是因为没有可用 Node(资源不足),Pod 状态 ImagePullBackOff 可能是 Node 上拉不到镜像。
术语:Namespace(命名空间)
- 一句话解释:把集群资源分组隔离的机制。不同命名空间里可以有同名资源,互不干扰。
- 形象比喻:命名空间就像"楼层"。同一栋大楼里,3 楼的 101 室和 5 楼的 101 室是两个不同的房间。你在 dev 命名空间和 prod 命名空间各创建一个叫 nginx 的 Pod,它们互不影响。
- 考试怎么考:考题会指定在某个命名空间操作。忘记加
-n参数是最常见的丢分原因之一。 - 最易混淆:命名空间隔离的是"资源名称",不是网络。不同命名空间的 Pod 默认可以互相通信(除非设了 NetworkPolicy)。
基本操作
# 查看命名空间
kubectl get namespaces
kubectl get ns # 简写
# 创建命名空间
kubectl create namespace dev
kubectl create ns staging
# 在指定命名空间中创建资源
kubectl run nginx --image=nginx -n dev
# 查看指定命名空间的资源
kubectl get pods -n dev
kubectl get all -n dev
# 查看所有命名空间的资源
kubectl get pods -A
kubectl get pods --all-namespaces
# ⭐ 设置默认命名空间(考试强烈推荐!)
kubectl config set-context --current --namespace=dev
# 删除命名空间(会连带删除里面所有资源!)
kubectl delete namespace dev
⚠️ 考试生存技巧:每道题开头通常会指定命名空间。做题第一件事就是切换默认命名空间:
kubectl config set-context --current --namespace=xxx。这样后续所有命令都不用加-n,既省时间又不容易忘记。
命名空间 YAML
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
env: development
集群默认命名空间
Kubernetes 集群自带 4 个命名空间,不要去动它们(除了 default):
| 命名空间 | 用途 | 一句话记忆 |
|---|---|---|
| default | 默认命名空间,不指定 -n 就在这里 | "你的默认工位" |
| kube-system | 系统组件(API Server、etcd、kube-proxy 等) | "机房,别乱动" |
| kube-public | 公开可读的资源 | "公告栏" |
| kube-node-lease | 节点心跳信息 | "签到表" |
🏷️ Labels 和 Selectors:资源的"标签系统"
术语:Label(标签)
- 一句话解释:贴在 Kubernetes 资源上的键值对标记,用于组织和筛选资源。
- 形象比喻:就像超市货架上的分类标签——"水果/进口/打折"。你可以快速找到"所有打折的进口水果"。
- 考试怎么考:Service 通过 selector 匹配 Pod 的 label 来做流量转发;Deployment 通过 selector 管理 Pod。标签不匹配 = 资源关联断开。
- 最易混淆:Label vs Annotation。Label 参与筛选(selector 能选到),Annotation 只是"备注"(纯记录信息,不能被 selector 选到)。
添加和管理 Labels
# 添加标签
kubectl label pod nginx env=prod tier=frontend
# 覆盖已有标签
kubectl label pod nginx env=staging --overwrite
# 删除标签(注意减号语法)
kubectl label pod nginx env-
# 查看标签
kubectl get pods --show-labels
# 按标签筛选(selector 语法)
kubectl get pods -l env=prod # 等于
kubectl get pods -l 'env in (prod, staging)' # 包含
kubectl get pods -l 'env!=dev' # 不等于
kubectl get pods -l env=prod,tier=frontend # 多条件 AND
⚠️ 考试视角:Label selector 是 Kubernetes 里"关联资源"的核心机制。Service 找 Pod、Deployment 管 Pod、NetworkPolicy 选 Pod,全靠 label 匹配。写 YAML 时 selector 和 template labels 不一致,是最常见的"为什么我的 Service 没有流量"问题。
Labels 最佳实践
Kubernetes 官方推荐使用带前缀的标签:
metadata:
labels:
# 官方推荐的标签(带 app.kubernetes.io/ 前缀)
app.kubernetes.io/name: nginx
app.kubernetes.io/version: "1.21"
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: my-app
app.kubernetes.io/managed-by: kubectl
# 自定义标签(考试常用)
env: production
team: backend
cost-center: engineering
考试中不会考官方标签规范,但你自己打标签时用 app=xxx, env=xxx, tier=xxx 这种清晰的键值对就好。
🎯 考试技巧
开考前必做的环境设置
# 1. 确认别名可用(考试环境通常已配置)
alias k=kubectl
# 2. 设置快捷变量 ⭐ 这两个能救命
export do="--dry-run=client -o yaml"
export now="--force --grace-period=0"
# 3. 使用示例
k run nginx --image=nginx $do > pod.yaml # 生成 YAML
k delete pod nginx $now # 秒删 Pod
# 4. 查看字段文档(忘了 YAML 怎么写时用)
k explain pod.spec.containers
k explain pod.spec.containers.resources
k explain deployment.spec.strategy
# 5. 快速切换命名空间(每道题第一步)
k config set-context --current --namespace=dev
快速创建各种资源
考试中你需要快速创建不同类型的资源,把这些命令练到肌肉记忆:
# Pod
k run nginx --image=nginx $do
# Deployment
k create deployment nginx --image=nginx --replicas=3 $do
# 暴露为 Service
k expose deployment nginx --port=80 --type=NodePort $do
# Job
k create job test --image=busybox -- echo "hello" $do
# CronJob
k create cronjob test --image=busybox --schedule="*/5 * * * *" -- date $do
常用 kubectl 组合技
# 查看 Pod 所在节点
k get pods -o wide
# 提取 Pod IP(jsonpath 是考试利器)
k get pod nginx -o jsonpath='{.status.podIP}'
# 查看所有资源
k get all
# 服务端验证 YAML 是否正确(比 client 更严格)
k apply -f pod.yaml --dry-run=server
# 实时观察资源变化
k get pods -w
⚠️ 常见错误与排查
CKAD 考试大量考排查能力。以下是最常见的 5 种 Pod 故障,遇到任何一个都按"describe → logs → events"的顺序排查。
错误 1:Pod 一直 Pending——"卡在排队"
Pod 停在 Pending 意味着调度器找不到合适的节点来运行它。
# 看到这个状态
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# nginx 0/1 Pending 0 5m
# 第一步:看 Events 找原因
kubectl describe pod nginx
| 常见原因 | Events 关键词 | 解决方案 |
|---|---|---|
| 资源不足 | Insufficient cpu/memory | 降低 requests 或扩容节点 |
| 节点选择器不匹配 | 0/3 nodes are available | 检查 nodeSelector / nodeAffinity |
| PVC 未绑定 | persistentvolumeclaim not found | 创建对应的 PV 或修复 PVC |
| 污点/容忍 | had taints that pod didn't tolerate | 加 tolerations 或去掉节点 taint |
错误 2:ImagePullBackOff——"找不到菜谱"
镜像拉不下来,通常是名字写错了。
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# nginx 0/1 ImagePullBackOff 0 5m
# 排查
kubectl describe pod nginx | grep -A5 "Events"
| 常见原因 | 解决方案 |
|---|---|
| 镜像名拼写错误 | kubectl set image pod/nginx nginx=nginx:1.21 |
| 镜像 tag 不存在 | 去 Docker Hub 确认 tag |
| 私有仓库认证失败 | 检查 imagePullSecrets |
| 网络问题 | 检查节点网络连通性 |
💡 快速修复:如果只是镜像名写错,可以直接
kubectl edit pod nginx修改镜像,不用重建。
错误 3:CrashLoopBackOff——"反复翻车"
容器启动后立刻崩溃,Kubernetes 反复尝试重启,间隔越来越长(10s → 20s → 40s...)。
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# app 0/1 CrashLoopBackOff 5 10m
# ⭐ 关键命令:看上次崩溃前的日志
kubectl logs app --previous
kubectl describe pod app
| 常见原因 | 排查方式 |
|---|---|
| 应用配置错误 | logs --previous 看错误信息 |
| 缺少环境变量 | describe 检查 env |
| 健康检查太严格 | 检查 liveness probe 配置 |
| 内存限制太小 | describe 看 OOMKilled |
错误 4:Selector 不匹配——"标签对不上"
这个错误不会显示为 Pod 状态异常,而是表现为"Deployment 创建了但没有 Pod"或"Service 没有流量"。
# ❌ 错误:selector 和 template labels 不匹配
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx # selector 要找 app=nginx
template:
metadata:
labels:
app: web # ← 但 Pod 标签是 app=web,对不上!
# ✅ 正确:selector 和 template labels 必须一致
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx # ← 和 selector 一致 ✓
错误 5:忘记指定命名空间——"走错楼层"
这是考试中最冤枉的丢分方式——操作正确,但在错误的命名空间执行。
# ❌ 忘记切换命名空间
kubectl get pods # 在 default 命名空间,看不到 dev 里的资源
# No resources found
# ✅ 正确做法
kubectl get pods -n dev # 方式 1:手动指定
kubectl config set-context --current --namespace=dev # 方式 2:切换默认(推荐)
⚠️ 考试铁律:每道题做第一件事就是切换到题目指定的命名空间。把这个变成条件反射。
📝 考试场景题
场景 1:创建带资源限制的 Pod
题目:创建一个名为 resource-pod 的 Pod,使用 nginx 镜像,设置 CPU 请求为 100m,内存请求为 128Mi,CPU 限制为 200m,内存限制为 256Mi。
解题思路:先用 --dry-run 生成骨架,再添加 resources 字段。
# 第 1 步:生成 YAML 骨架
kubectl run resource-pod --image=nginx --dry-run=client -o yaml > pod.yaml
# 第 2 步:编辑添加 resources(用 vim)
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
# 第 3 步:应用并验证
kubectl apply -f pod.yaml
kubectl describe pod resource-pod | grep -A10 "Limits"
💡 不确定 resources 字段怎么写? 用
kubectl explain pod.spec.containers.resources查看官方文档,考试中可以随时用。
场景 2:Deployment 滚动更新和回滚
题目:创建 Deployment,更新镜像版本,然后回滚。
解题思路:这是一个典型的四步操作——创建 → 更新 → 观察 → 回滚。
# 1. 创建 Deployment
kubectl create deployment web --image=nginx:1.19 --replicas=3
# 2. 验证 Pod 就绪
kubectl get deployment web
kubectl get pods -l app=web
# 3. 更新镜像
kubectl set image deployment/web nginx=nginx:1.21
# 4. 查看滚动状态(确认更新成功)
kubectl rollout status deployment/web
# 5. 查看历史版本
kubectl rollout history deployment/web
# 6. 假设新版本有问题,回滚到上一版本
kubectl rollout undo deployment/web
# 7. 验证回滚成功
kubectl describe deployment web | grep Image
场景 3:多命名空间资源管理
题目:在 production 命名空间创建 Pod,然后列出所有命名空间的 Pod。
# 1. 创建命名空间
kubectl create namespace production
# 2. 切换到该命名空间(养成好习惯)
kubectl config set-context --current --namespace=production
# 3. 创建 Pod(因为已切换命名空间,不用加 -n)
kubectl run prod-nginx --image=nginx
# 4. 验证
kubectl get pods
# 5. 列出所有命名空间的 Pod
kubectl get pods -A
场景 4:使用标签筛选和管理资源
题目:给 Pod 添加标签,然后按标签筛选和删除。
# 1. 创建多个 Pod
kubectl run app1 --image=nginx
kubectl run app2 --image=nginx
kubectl run app3 --image=nginx
# 2. 添加标签
kubectl label pod app1 env=prod tier=frontend
kubectl label pod app2 env=prod tier=backend
kubectl label pod app3 env=dev tier=frontend
# 3. 按标签筛选
kubectl get pods -l env=prod # 所有 prod 环境
kubectl get pods -l tier=frontend # 所有 frontend
kubectl get pods -l env=prod,tier=frontend # prod 且 frontend(只有 app1)
kubectl get pods --show-labels # 查看所有标签
# 4. 按标签批量删除
kubectl delete pods -l env=dev # 只删 dev 环境的
练习题
题目 1
创建一个名为 redis 的 Pod,使用 redis:alpine 镜像:
kubectl run redis --image=redis:alpine
验证:
kubectl get pod redis
kubectl describe pod redis
</details>
题目 2
将 Deployment nginx 的副本数从 3 扩展到 5:
kubectl scale deployment nginx --replicas=5
验证:
kubectl get deployment nginx
kubectl get pods -l app=nginx
</details>
题目 3
如何查看 Pod 上次崩溃前的日志?
- A.
kubectl logs pod-name - B.
kubectl logs pod-name --previous - C.
kubectl logs pod-name --last - D.
kubectl describe pod pod-name
答案:B
解析:
--previous参数用于查看上一个已终止容器的日志- 这是排查 CrashLoopBackOff 的核心命令——容器已经崩溃重启了,当前日志可能是空的或不完整的,你需要看"上一轮"的日志
kubectl logs pod-name只查看当前运行中容器的日志
kubectl logs pod-name --previous
</details>
题目 4
哪个命令可以生成 Pod YAML 而不实际创建?
- A.
kubectl run nginx --image=nginx --dry-run - B.
kubectl run nginx --image=nginx --dry-run=client -o yaml - C.
kubectl run nginx --image=nginx --output=yaml - D.
kubectl create pod nginx --image=nginx --dry-run
答案:B
解析:
--dry-run=client表示客户端模拟,不发送请求到 API Server-o yaml指定输出格式为 YAML- 注意选项 A 缺少
=client(旧版本不带参数的--dry-run已废弃) - 选项 D 语法错误,
kubectl create后面不能直接跟pod,应该用kubectl run
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
</details>
题目 5(实操题)
创建一个 Deployment 名为 web-app,使用镜像 nginx:1.19,副本数为 3,然后:
- 更新镜像到
nginx:1.21 - 查看滚动状态
- 回滚到之前的版本
# 1. 创建 Deployment
kubectl create deployment web-app --image=nginx:1.19 --replicas=3
# 2. 等待就绪
kubectl rollout status deployment/web-app
# 3. 更新镜像
kubectl set image deployment/web-app nginx=nginx:1.21
# 4. 查看滚动状态
kubectl rollout status deployment/web-app
# 5. 查看历史
kubectl rollout history deployment/web-app
# 6. 回滚
kubectl rollout undo deployment/web-app
# 7. 验证
kubectl describe deployment web-app | grep Image
</details>
题目 6(排查题)
一个 Pod 处于 CrashLoopBackOff 状态,请列出你的排查步骤:
<details> <summary>查看答案</summary># 第 1 步:看 Pod 状态和重启次数
kubectl get pod <pod-name>
# 第 2 步:看上次崩溃前的日志(最关键)
kubectl logs <pod-name> --previous
# 第 3 步:看 Pod 详情和事件
kubectl describe pod <pod-name>
# 第 4 步:根据日志判断原因
# - OOMKilled → 增加 memory limits
# - 配置错误 → 检查环境变量和 ConfigMap
# - 镜像问题 → 检查 command 和 args
# - 健康检查失败 → 调整 liveness probe
排查口诀:logs previous → describe → events,三步定位。
</details>📋 本章小结
核心资源速查
| 资源 | 创建命令 | 用途 | 一句话记忆 |
|---|---|---|---|
| Pod | kubectl run | 运行容器 | "Kubernetes 的最小工作单元" |
| Deployment | kubectl create deployment | 管理无状态应用 | "应用的运营经理,管更新管回滚" |
| ReplicaSet | 自动由 Deployment 创建 | 维持 Pod 副本数 | "排班表,永远保证够人" |
| Namespace | kubectl create namespace | 资源隔离 | "楼层,互不干扰" |
高频命令速查
| 操作 | 命令 | 一句话记忆 |
|---|---|---|
| 生成 YAML | --dry-run=client -o yaml | "生成模板不创建" |
| 强制删除 | --force --grace-period=0 | "秒删不等待" |
| 查看崩溃日志 | logs --previous | "看上一轮的遗言" |
| 切换命名空间 | config set-context --current --namespace= | "每题第一步" |
| 滚动更新 | set image deployment/NAME CONTAINER=IMAGE | "边跑边换" |
| 回滚 | rollout undo deployment/NAME | "一键恢复" |
| 查看字段文档 | explain pod.spec.containers | "忘了怎么写就问它" |
考试要点速记
Pod 创建:kubectl run NAME --image=IMAGE
Deployment:kubectl create deployment NAME --image=IMAGE
生成 YAML:--dry-run=client -o yaml
强制删除:--force --grace-period=0
查看日志:kubectl logs [-f] [--previous]
进入容器:kubectl exec -it POD -- /bin/sh
滚动更新:kubectl set image deployment/NAME CONTAINER=IMAGE
回滚:kubectl rollout undo deployment/NAME
切换 NS:kubectl config set-context --current --namespace=NAME
排查三板斧:describe → logs --previous → get events