📘 Day 06:DaemonSet、StatefulSet、Job、CronJob

🎯 今日目标

  • 部署 DaemonSet 实现每节点一个采集 Pod
  • 部署 StatefulSet 实现有状态应用
  • 理解 StatefulSet Pod 的稳定网络标识
  • 创建 Job 并行计算任务
  • 创建 CronJob 定时任务

🧠 理论精讲(30 分钟)

四种工作负载对比

工作负载 副本特征 Pod 标识 启动/停止顺序 典型场景
Deployment 可多可少,Pod 无差别 随机名(xxx-abcde-xyz) 无顺序,并行 无状态 Web
DaemonSet 每节点一个 节点名相关 无顺序 日志采集、监控 Agent
StatefulSet 固定数量,每个唯一 有序序号(xxx-0, xxx-1) 顺序启动,逆序停止 数据库、消息队列
Job 一次性,完成即止 随机名 无顺序 数据迁移、计算任务
CronJob 按定时规则创建 随机名 无顺序 定时备份、定时清理

StatefulSet 核心特性

1
2
3
4
1. 稳定的网络标识:<sts-name>-<序号>.<headless-svc>.<ns>.svc.cluster.local
2. 稳定的持久存储:每个 Pod 有独立 PVC,Pod 重建后仍绑定同一 PVC
3. 有序部署和缩放:0→1→2→...,缩容时逆序
4. 有序滚动更新:N-1→N-2→...→0

Job 关键参数

参数 含义 默认值
completions 需要成功完成多少次 1
parallelism 最大并行执行数 1
backoffLimit 失败重试次数 6
activeDeadlineSeconds 任务超时时间

🔧 动手实操(120 分钟)

练习 6.1:DaemonSet 日志采集器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 1. 创建一些测试 Pod 分散在不同节点
kubectl create deploy test-app --image=nginx:alpine --replicas=5

# 2. 部署 DaemonSet 日志采集器
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
spec:
selector:
matchLabels:
app: log-collector
template:
metadata:
labels:
app: log-collector
spec:
containers:
- name: collector
image: busybox:1.36
command:
- sh
- -c
- |
mkdir -p /host-data
while true; do
echo "[$(date)] Host: $(hostname)" >> /host-data/collector.log
sleep 5
done
volumeMounts:
- name: host-logs
mountPath: /host-data
volumes:
- name: host-logs
hostPath:
path: /tmp/collector-logs
type: DirectoryOrCreate
EOF

# 3. 验证每个节点都有一个 Pod
kubectl get pod -l app=log-collector -o wide
# 预期:3 个 Pod(每节点 1 个)

# 4. 验证数据写入
# 登录任一 worker 节点
ssh k8s-node1
cat /tmp/collector-logs/collector.log
# 看到采集日志

# 5. 查看 DaemonSet 状态
kubectl get ds log-collector
# DESIRED=3 CURRENT=3 READY=3

# 6. 清理
kubectl delete ds log-collector
kubectl delete deploy test-app

练习 6.2:StatefulSet 部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 1. 先创建 Headless Service(必须!)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: nginx-sts
spec:
clusterIP: None # Headless Service 的关键!
selector:
app: nginx-sts
ports:
- port: 80
targetPort: 80
EOF

# 2. 部署 StatefulSet
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-sts
spec:
serviceName: nginx-sts
replicas: 3
selector:
matchLabels:
app: nginx-sts
template:
metadata:
labels:
app: nginx-sts
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Mi
EOF

# 3. 观察顺序创建(0→1→2)
kubectl get pod -l app=nginx-sts -w
# nginx-sts-0 Running
# nginx-sts-1 Running
# nginx-sts-2 Running

# 4. 验证网络标识
kubectl exec nginx-sts-0 -- hostname
# nginx-sts-0

kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- \
nslookup nginx-sts-0.nginx-sts.default.svc.cluster.local
# 返回 Pod IP

# 5. 验证 PVC 自动创建
kubectl get pvc
# 每个 Pod 独立 PVC:data-nginx-sts-0, data-nginx-sts-1, data-nginx-sts-2

# 6. 写入数据验证持久性
kubectl exec nginx-sts-0 -- sh -c 'echo "pod-0-data" > /usr/share/nginx/html/data.txt'

# 7. 删除 Pod 观察重建
kubectl delete pod nginx-sts-0
kubectl get pod nginx-sts-0 -w
# Pod 重建后名称仍然是 nginx-sts-0

# 8. 验证数据仍在(PVC 绑定未变)
kubectl exec nginx-sts-0 -- cat /usr/share/nginx/html/data.txt
# 输出:pod-0-data

# 9. 顺序缩容
kubectl scale sts nginx-sts --replicas=1
kubectl get pod -l app=nginx-sts -w
# 逆序终止:nginx-sts-2 Terminating → nginx-sts-1 Terminating

# 10. 扩容
kubectl scale sts nginx-sts --replicas=3

# 11. 清理
kubectl delete sts nginx-sts
kubectl delete svc nginx-sts
# ⚠️ PVC 不会自动删除,需要手动清理
kubectl delete pvc data-nginx-sts-0 data-nginx-sts-1 data-nginx-sts-2

练习 6.3:Job 并行计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 1. 基础 Job
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
name: compute-pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34
command:
- perl
- -Mbignum=bpi
- -wle
- print bpi(200)
restartPolicy: Never
backoffLimit: 4
EOF

# 2. 观察 Job 执行
kubectl get job compute-pi -w
# COMPLETIONS 从 0/1 → 1/1

kubectl get pod -l job-name=compute-pi
# Pod 状态 Completed

# 3. 查看计算结果
kubectl logs job/compute-pi
# 输出 π 值

# 4. 并行 Job
cat <<'EOF' | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
name: parallel-job
spec:
completions: 6
parallelism: 2
template:
spec:
containers:
- name: worker
image: busybox:1.36
command:
- sh
- -c
- |
echo "Task $((JOB_COMPLETION_INDEX+1)) running on $(hostname)"
sleep $(( RANDOM % 10 ))
echo "Task done"
restartPolicy: Never
backoffLimit: 4
EOF

# 5. 观察并行执行
kubectl get pod -l job-name=parallel-job -w
# 每次最多 2 个 Pod 同时运行

kubectl get job parallel-job
# COMPLETIONS: 6/6

# 6. 清理
kubectl delete job compute-pi parallel-job

练习 6.4:CronJob 定时任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 1. 创建每分钟执行的 CronJob
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
name: health-checker
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: checker
image: busybox:1.36
command:
- sh
- -c
- |
echo "[$(date)] Health check executed"
echo "Checking DNS..."
nslookup kubernetes.default.svc.cluster.local
echo "OK"
restartPolicy: Never
backoffLimit: 2
EOF

# 2. 查看 CronJob
kubectl get cj
kubectl describe cj health-checker

# 3. 等待 1~2 分钟,查看自动创建的 Job
kubectl get jobs
# 看到 health-checker-<timestamp>

# 4. 查看 Job 创建的 Pod
kubectl get pod -l job-name

# 5. 查看日志
kubectl logs job/health-checker-<timestamp>

# 6. 手动触发一次(不再等待定时器)
kubectl create job --from=cronjob/health-checker manual-run

# 7. 查看手动任务的日志
kubectl logs job/manual-run

# 8. 清理
kubectl delete cj health-checker
kubectl delete job manual-run

🐛 排错练习(30 分钟)

场景 1:StatefulSet Pod 一直 Pending

1
2
3
4
5
6
7
8
9
10
# 原因 1:PVC 无法绑定
kubectl get pvc
# STATUS: Pending

kubectl describe pvc <pvc-name>
# 看到 "no persistent volumes available..."

# 解决方案:
# - 检查 StorageClass 是否存在:kubectl get sc
# - 创建 PV 或确保 default StorageClass 可用

场景 2:CronJob 不触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 排查步骤

# 1. 检查 CronJob 配置
kubectl describe cj <name>
# 查看 Last Schedule Time

# 2. 检查 concurrencyPolicy
kubectl get cj <name> -o yaml | grep concurrencyPolicy
# Allow / Forbid / Replace

# 3. 检查 startingDeadlineSeconds
kubectl get cj <name> -o yaml | grep startingDeadlineSeconds

# 4. 检查 Job 是否被创建
kubectl get jobs --sort-by=.metadata.creationTimestamp

# 常见原因:
# - schedule 语法错误
# - concurrencyPolicy=Forbid 且上一次 Job 未完成
# - startingDeadlineSeconds 过期

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟

题目:工作负载综合部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
【操作要求】

1. 部署 StatefulSet:
- 名称:redis-cluster
- 副本数:3
- 镜像:redis:7-alpine
- 配置 redis 启动命令:redis-server --appendonly yes
- 通过 volumeClaimTemplates 为每个 Pod 创建 100Mi PVC
- 对应的 Headless Service 名称为 redis-svc

2. 部署 DaemonSet:
- 名称:node-monitor
- 镜像:busybox:1.36
- 每 10 秒打印节点主机名和当前时间到 stdout

3. 部署 CronJob:
- 名称:redis-backup
- 每 30 分钟执行一次
- 使用 busybox:1.36
- 命令:echo "backup at $(date)"

4. 验证:
- redis-cluster-0/1/2 全部 Running
- node-monitor 在每个节点一个 Pod
- redis-backup CronJob 显示在 kubectl get cj 中

5. 写入测试数据到 redis-cluster-0,删除该 Pod,
重建后验证数据是否保留(通过 PVC 持久化)

【评分标准】
- StatefulSet + Headless Service 正确(30 分)
- DaemonSet 正确(20 分)
- CronJob 正确(20 分)
- PVC 自动创建(15 分)
- 数据持久性验证(15 分)

📋 命令速查

命令 功能 注解
kubectl get ds 列出 DaemonSet 每个节点运行一个 Pod 副本
kubectl get ds -o wide DaemonSet + 选择器/镜像 确认每个节点是否都有 Pod
kubectl describe ds <name> DaemonSet 详情 查看更新策略(RollingUpdate/OnDelete)
kubectl get sts 列出 StatefulSet StatefulSet 常用 short name: sts
kubectl describe sts <name> StatefulSet 详情 查看 podManagementPolicy、serviceName、volumeClaimTemplates
kubectl get pods -l app=mysql 按标签筛选 Pod StatefulSet Pod 命名:<name>-0, <name>-1, ...
kubectl scale sts <name> --replicas=5 扩缩 StatefulSet 按序号递增/递减创建/删除 Pod
kubectl get pvc 列出 PVC StatefulSet + volumeClaimTemplates 自动为每个 Pod 创建 PVC
kubectl get job 列出 Job 一次性任务,完成后 Pod 状态为 Completed
kubectl describe job <name> Job 详情 查看 completions、parallelism、backoffLimit
kubectl logs job/<name> 查看 Job 日志 Job Pod 执行完不会自动删除,可事后查看日志
kubectl get cronjob 列出 CronJob short name: cj
kubectl describe cronjob <name> CronJob 详情 查看 schedule、lastScheduleTime、suspend 状态
kubectl get jobs --watch 实时监控 Job 创建 观察 CronJob 触发时自动创建的 Job
kubectl create job test-job --image=busybox --dry-run=client -o yaml 生成 Job YAML 快速获取 Job 模板
kubectl create cronjob test-cj --image=busybox --schedule="*/5 * * * *" --dry-run=client -o yaml 生成 CronJob YAML 5 字段 cron 表达式(分/时/日/月/周)
kubectl delete job <name> 删除 Job 级联删除其完成的 Pod
kubectl delete cronjob <name> 删除 CronJob 不会删除正在运行的 Job 和 Pod
kubectl patch cronjob <name> -p '{"spec":{"suspend":true}}' 暂停 CronJob 停止后续调度,保留历史

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:DaemonSet https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
Kubernetes 官方:StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
Kubernetes 官方:Job https://kubernetes.io/docs/concepts/workloads/controllers/job/
Kubernetes 官方:CronJob https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/
Kubernetes 官方:工作负载资源 https://kubernetes.io/docs/concepts/workloads/controllers/
Cron 表达式语法 https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax

📘 Day 05:Deployment 与 ReplicaSet

🎯 今日目标

  • 理解 Deployment → ReplicaSet → Pod 的层级关系
  • 能执行滚动更新并观察 Pod 替换过程
  • 能用 rollout undo 回滚到任意版本
  • 能用 rollout pause/resume 实现金丝雀发布
  • 能排查滚动更新卡住的常见原因

🧠 理论精讲(30 分钟)

三层关系

1
2
3
4
5
Deployment  ─── 管理版本、更新策略

└──→ ReplicaSet ─── 确保 Pod 副本数达标

└──→ Pod ─── 运行容器

每次 Deployment 更新会创建新 ReplicaSet,旧的 ReplicaSet 保留(用于回滚)。

滚动更新策略

参数 含义 默认值
maxSurge 更新期间最多超出多少个 Pod 25%
maxUnavailable 更新期间最多不可用多少个 Pod 25%
1
2
3
4
5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 一次最多多创建 1 个
maxUnavailable: 0 # 任何时刻必须有全部 Pod 可用

关键命令速查

命令 用途
kubectl rollout status deploy/<name> 查看更新进度
kubectl rollout history deploy/<name> 查看版本历史
kubectl rollout undo deploy/<name> 回滚到上一版本
kubectl rollout pause deploy/<name> 暂停更新
kubectl rollout resume deploy/<name> 恢复更新

🔧 动手实操(120 分钟)

练习 5.1:创建 Deployment + 观察 ReplicaSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 创建 Deployment(3 副本)
kubectl create deploy nginx --image=nginx:1.21 --replicas=3

# 2. 查看 Deployment
kubectl get deploy nginx
# NAME READY UP-TO-DATE AVAILABLE AGE
# nginx 3/3 3 3 30s

# 3. 查看 ReplicaSet(自动创建)
kubectl get rs -l app=nginx
# NAME DESIRED CURRENT READY AGE
# nginx-<hash> 3 3 3 30s

# 4. 查看 RS 管理的 Pod
kubectl get pod -l app=nginx -o wide
# 3 个 Pod 分布在不同节点

# 5. 验证 RS 的自我修复:删除一个 Pod
kubectl delete pod <任意一个 nginx pod>
kubectl get pod -l app=nginx -w
# RS 立即创建新 Pod 补足 3 副本

练习 5.2:滚动更新全流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 打开 3 个终端窗口:

# 终端1:观察 Deployment 状态
kubectl get deploy nginx -w

# 终端2:观察 Pod 变化
kubectl get pod -l app=nginx -w

# 终端3:观察 ReplicaSet 变化
kubectl get rs -l app=nginx -w

# === 触发滚动更新 ===

# 终端4:更新镜像
kubectl set image deploy/nginx nginx=nginx:1.22

# 在终端1 观察:
# UP-TO-DATE 从 0 → 1 → 2 → 3
# 在终端2 观察:
# 新 Pod 创建,旧 Pod 逐步 Terminating
# 在终端3 观察:
# 新 RS 的 DESIRED 递增,旧 RS 的 DECREASED 递减

# 查看更新状态
kubectl rollout status deploy/nginx

# 查看更新历史
kubectl rollout history deploy/nginx
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>

练习 5.3:回滚操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1. 制造一个失败的更新
kubectl set image deploy/nginx nginx=nginx:not-exists

# 2. 观察卡住
kubectl rollout status deploy/nginx
# 看到 "Waiting for deployment rollout to finish..."

# 3. 查看 Pod 状态
kubectl get pod -l app=nginx
# 新 Pod ImagePullBackOff 或 ErrImagePull

# 4. 立即回滚!
kubectl rollout undo deploy/nginx

# 5. 查看回滚后的 Pod 状态
kubectl get pod -l app=nginx
# 恢复为旧版本

# 6. 查看历史记录
kubectl rollout history deploy/nginx
# REVISION CHANGE-CAUSE
# 1 <none>
# 3 <none> # REVISION 2 被跳过了

# 7. 回滚到指定 REVISION
kubectl rollout undo deploy/nginx --to-revision=1

# 8. 为更新添加记录标记
kubectl set image deploy/nginx nginx=nginx:1.23 --record=false
# 注意:--record 在新版中已弃用,使用 annotation 替代
kubectl annotate deploy/nginx kubernetes.io/change-cause="update to 1.23"
kubectl rollout history deploy/nginx

练习 5.4:扩缩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 快速扩容到 6 个副本
kubectl scale deploy/nginx --replicas=6

# 2. 观察 Pod 增加
kubectl get pod -l app=nginx -w

# 3. 缩容到 2 个
kubectl scale deploy/nginx --replicas=2

# 4. 观察 Pod 被终止
kubectl get pod -l app=nginx -w

# 5. 查看 Deployment 的当前期望和实际状态
kubectl get deploy nginx -o jsonpath='
期望副本:{.spec.replicas}
就绪副本:{.status.readyReplicas}
可用副本:{.status.availableReplicas}
'

练习 5.5:金丝雀发布基础(pause/resume)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 原理:暂停滚动更新 → 验证小部分新 Pod → 恢复全量更新

# 1. 恢复到稳定状态
kubectl scale deploy/nginx --replicas=10

# 2. 暂停 Deployment 的滚动更新
kubectl rollout pause deploy/nginx

# 3. 触发镜像更新(因为有 pause,只会创建新 RS 但不创建新 Pod)
kubectl set image deploy/nginx nginx=nginx:1.24
kubectl annotate deploy/nginx kubernetes.io/change-cause="canary 1.24"

# 4. 查看当前的 ReplicaSet
kubectl get rs -l app=nginx
# 看到新 RS 的 DESIRED=0(因为暂停了)

# 5. "放行" 1 个新版本 Pod 做金丝雀验证
# 方法:手动改新 RS 的 replicas(不太好)
# 更好方法:直接 resume 但限制 maxSurge
kubectl rollout resume deploy/nginx

# 6. 实时观察
kubectl rollout status deploy/nginx

# 7. 清理
kubectl delete deploy nginx

🐛 排错练习(30 分钟)

场景 1:滚动更新卡住 — 镜像拉取失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. 创建 Deployment
kubectl create deploy test --image=nginx:1.21 --replicas=3

# 2. 更新到不存在镜像
kubectl set image deploy/test nginx=nginx:99.99

# 3. 观察状态
kubectl get deploy test
# 看到 READY 3/3、UP-TO-DATE 1、AVAILABLE 3

kubectl get rs -l app=test
# 新 RS READY=0,旧 RS READY=3

kubectl get pod -l app=test
# 新 Pod ImagePullBackOff

# 4. 查看详细原因
kubectl describe pod <新 pod> | grep -A5 Events

# 5. 排查命令总结
kubectl rollout status deploy/test
kubectl describe deploy test
kubectl logs <pod-name> # 如果是应用启动失败

# 6. 回滚
kubectl rollout undo deploy/test

# 7. 清理
kubectl delete deploy test

场景 2:回滚失败(无历史记录)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建新 Deployment
kubectl create deploy test2 --image=nginx:1.21 --replicas=2

# 查看 revisionHistoryLimit(默认 10)
kubectl get deploy test2 -o jsonpath='{.spec.revisionHistoryLimit}'

# 模拟没有历史
kubectl rollout undo deploy/test2
# 可能报错:no rollout history found(首次创建没有历史)

# 解决方案:至少要有一次成功的更新才能回滚
kubectl set image deploy/test2 nginx=nginx:1.22
kubectl rollout status deploy/test2
kubectl rollout history deploy/test2
# 现在有了两个 revision

kubectl delete deploy test2

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟

题目:Deployment 滚动发布综合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
【操作要求】

1. 用 --dry-run=client 生成 Deployment YAML:
- 名称:web-app
- 镜像:nginx:1.21-alpine
- 副本数:5
- 资源限制:cpu 100m, memory 128Mi
- 滚动更新策略:maxSurge=1, maxUnavailable=0

2. 应用该 YAML,等待所有 Pod Ready

3. 执行以下版本变更序列:
a. 更新到 nginx:1.22-alpine,记录 change-cause
b. 等待完成
c. 更新到 nginx:1.23-alpine,记录 change-cause
d. 等待完成

4. 假设 1.23 版本有 bug,请:
a. 先回滚到上一个版本
b. 再回滚到最初版本(1.21-alpine)
c. 确认最终所有 Pod 使用 nginx:1.21-alpine

5. 将副本数缩放到 2,再扩容到 5

6. 输出 rollout history 完整记录

【验证命令】
kubectl rollout history deploy/web-app
kubectl get deploy web-app -o jsonpath='{.spec.template.spec.containers[0].image}'
kubectl get pod -l app=web-app -o jsonpath='{range .items[*]}{.metadata.name}{": "}{.spec.containers[0].image}{"\n"}{end}'

【评分标准】
- YAML 正确(20 分)
- 滚动更新步骤正确(30 分)
- 回滚到指定版本正确(25 分)
- 扩缩容正确(15 分)
- history 记录完整(10 分)

📋 命令速查

命令 功能 注解
kubectl create deploy nginx --image=nginx:alpine 创建 Deployment 最快捷的部署方式
kubectl get deploy 列出 Deployment DESIRED/CURRENT/READY/UP-TO-DATE/AVAILABLE 五个状态字段
kubectl get deploy -o wide Deployment + 镜像/标签/选择器 确认当前使用的镜像版本
kubectl get rs 列出 ReplicaSet Deployment 每次更新生成新 RS
kubectl get deploy,rs,pod 同时查看 Deploy→RS→Pod 层级 逗号分隔多资源类型
kubectl describe deploy <name> Deployment 详细信息 包含滚动更新策略、事件历史
kubectl scale deploy <name> --replicas=5 扩缩副本 等价于修改 spec.replicas
kubectl set image deploy/<name> <container>=<new-image>:<tag> 更新容器镜像 触发滚动更新,比 edit 效率高
kubectl set resources deploy/<name> -c=<container> --limits=cpu=200m,memory=256Mi --requests=cpu=100m,memory=128Mi 设置资源限制 更新 Pod 模板中的 resources 字段
kubectl rollout status deploy/<name> 查看滚动更新进度 输出 “successfully rolled out” 即完成
kubectl rollout history deploy/<name> 查看部署历史 每次更新生成一个 revision 号
kubectl rollout history deploy/<name> --revision=3 查看第 3 个版本的详情 对比不同版本的镜像和配置
kubectl rollout undo deploy/<name> 回滚上一版本 创建新 RS 并回退 Pod 模板
kubectl rollout undo deploy/<name> --to-revision=2 回滚到指定版本 revision 必须存在于历史中(默认保留 10 个)
kubectl rollout pause deploy/<name> 暂停滚动更新 金丝雀发布时暂停以验证新版
kubectl rollout resume deploy/<name> 恢复滚动更新 暂停后恢复继续滚动
kubectl rollout restart deploy/<name> 重启所有 Pod(滚动重建) 1.15+ 支持,配置变更后快速生效
kubectl patch deploy <name> -p '{"spec":{"minReadySeconds":10}}' JSON Patch 修改字段 比 edit 安全,适合 CI/CD
kubectl delete deploy <name> 删除 Deployment 级联删除 RS 和 Pod(默认)
kubectl delete deploy <name> --cascade=orphan 仅删 Deploy 保留 Pod Pod 变为孤儿,由新控制器接管
kubectl get pod --show-labels Pod + 标签 验证标签选择器是否匹配

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:Deployment https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Kubernetes 官方:ReplicaSet https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
Kubernetes 官方:滚动更新 https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/
Kubernetes 官方:回滚 Deployment https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment
Kubernetes 官方:kubectl rollout https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#rollout

📘 Day 04:Pod 生命周期与多容器模式

🎯 今日目标

  • 能画出 Pod 生命周期状态流转图
  • 能创建含 InitContainer 的 Pod
  • 能实现 Sidecar 模式的 Pod
  • 能正确配置三种探针
  • 能排查 Pod CrashLoopBackOff 问题

🧠 理论精讲(30 分钟)

Pod 是什么

Pod 是 K8s 最小的调度单元(不是容器!)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌───────────────────────── Pod ─────────────────────────┐
│ │
│ 共享网络命名空间(同一个 IP) │
│ 共享 IPC 命名空间 │
│ 共享 Volume(通过 volumes 声明) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Container│ │ Container│ │ Container│ ← Sidecar │
│ │ (主) │ │ (辅助) │ │ (辅助) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ │ │
│ ┌───────┴────────┐ │
│ │ shared volumes│ │
│ └────────────────┘ │
└─────────────────────────────────────────────────────────┘

Pod 生命周期

1
2
3
4
5
6
7
Pending ──→ Running ──→ Succeeded(正常退出)
│ │
│ ├──→ Failed(异常退出)
│ │
│ └──→ Unknown(节点失联)

└──→ ContainerCreating(拉镜像、挂载卷)

三种多容器模式

模式 说明 典型场景
Sidecar 辅助容器增强主容器 日志采集、配置热更新、代理
Ambassador 代理容器屏蔽外部复杂性 数据库代理、服务发现代理
Adapter 适配容器统一接口 日志格式转换、监控指标标准化

三种探针

探针 作用 失败后果
livenessProbe 检查容器是否还活着 重启容器
readinessProbe 检查容器是否可接收流量 从 Service Endpoint 移除
startupProbe 检查容器是否启动完成 启动期间屏蔽 liveness 和 readiness

🔧 动手实操(120 分钟)

练习 4.1:观察 Pod 完整生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. 创建 Pod 并实时观察
kubectl run lifecycle-pod --image=nginx:alpine --restart=Never

# 在另一个终端 watch
kubectl get pod lifecycle-pod -w
# 观察:Pending → ContainerCreating → Running

# 2. 查看详细信息
kubectl describe pod lifecycle-pod
# 重点关注 Events 部分

# 3. 进入容器看运行细节
kubectl exec lifecycle-pod -- cat /etc/nginx/conf.d/default.conf

# 4. 删除并观察终止过程(默认 30 秒优雅终止)
kubectl delete pod lifecycle-pod &
kubectl get pod lifecycle-pod -w
# 观察:Running → Terminating → 消失

# 5. 创建带较长 terminationGracePeriodSeconds 的 Pod
kubectl run graceful-pod --image=nginx:alpine --restart=Never \
--overrides='{"spec":{"terminationGracePeriodSeconds":60}}'

# 验证
kubectl get pod graceful-pod -o jsonpath='{.spec.terminationGracePeriodSeconds}'
kubectl delete pod graceful-pod

练习 4.2:Sidecar 模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 创建 Sidecar Pod:主容器写日志,Sidecar 读取
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: sidecar-demo
spec:
containers:
- name: app
image: busybox:1.36
args:
- /bin/sh
- -c
- |
i=0
while true; do
echo "$(date): log entry $i" >> /var/log/app.log
i=$((i+1))
sleep 2
done
volumeMounts:
- name: logs
mountPath: /var/log

- name: log-reader
image: busybox:1.36
args:
- /bin/sh
- -c
- tail -f /var/log/app.log
volumeMounts:
- name: logs
mountPath: /var/log

volumes:
- name: logs
emptyDir: {}
EOF

# 验证 Sidecar 能读到主容器的日志
kubectl logs sidecar-demo -c log-reader --tail=10

# 查看两个容器的状态
kubectl get pod sidecar-demo
# READY 2/2

# 清理
kubectl delete pod sidecar-demo

练习 4.3:InitContainer 等待依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 第一步:创建需要等待的依赖 Service
kubectl create deploy backend --image=nginx:alpine --replicas=1
kubectl expose deploy backend --port=80

# 第二步:创建带 InitContainer 的 Pod
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
initContainers:
- name: wait-for-backend
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting for backend service..."
until wget -q --spider http://backend-service.default.svc.cluster.local; do
echo "Backend not ready yet..."
sleep 2
done
echo "Backend is ready!"
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- echo "Main app started!" && sleep 3600
EOF

# 观察 InitContainer 执行
kubectl get pod init-demo -w
# 看到 STATUS 列:Init:0/1 → PodInitializing → Running

# 查看 InitContainer 日志
kubectl logs init-demo -c wait-for-backend

# 清理
kubectl delete pod init-demo
kubectl delete deploy backend
kubectl delete svc backend

练习 4.4:livenessProbe 排错实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: liveness-demo
spec:
containers:
- name: unhealthy
image: busybox:1.36
command:
- sh
- -c
- |
touch /tmp/healthy
# 30 秒后删除健康标志文件,模拟程序故障
sleep 30
rm /tmp/healthy
sleep 3600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
EOF

# 持续观察 Pod 状态
kubectl get pod liveness-demo -w

# 另一个终端查看事件
kubectl describe pod liveness-demo | grep -A5 "Events"

# 预期:约 30 + 5*3 = 45 秒后 Pod 被重启
kubectl get pod liveness-demo
# RESTARTS 列从 0 递增

# 清理
kubectl delete pod liveness-demo

练习 4.5:readinessProbe 流量控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: readiness-demo
spec:
replicas: 2
selector:
matchLabels:
app: readiness-demo
template:
metadata:
labels:
app: readiness-demo
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: readiness-svc
spec:
selector:
app: readiness-demo
ports:
- port: 80
targetPort: 80
EOF

# 查看 Endpoint 变化
kubectl get endpoints readiness-svc -w
# Pod Ready 后 Endpoint 出现

# 模拟 Pod 不健康:修改 nginx 配置让 / 返回错误
# (略,比赛环境可能需要替代方案)

# 清理
kubectl delete deploy readiness-demo
kubectl delete svc readiness-svc

🐛 排错练习(30 分钟)

场景 1:Pod CrashLoopBackOff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建一个会立即退出的 Pod
kubectl run crash-demo --image=busybox:1.36 --restart=Always -- /bin/false

# 观察状态
kubectl get pod crash-demo
# STATUS: CrashLoopBackOff

# 查看上一次崩溃的日志
kubectl logs crash-demo --previous

# 查看事件
kubectl describe pod crash-demo | grep -A10 Events

# 进入容器调试(如果容器立即退出,无法 exec)
kubectl run debug-pod --image=busybox:1.36 --restart=Never -it --rm -- sh

# 清理
kubectl delete pod crash-demo

场景 2:READY 0/1 但状态 Running

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 创建一个配置了错误端口的 readinessProbe
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: ready-fail
spec:
containers:
- name: nginx
image: nginx:alpine
readinessProbe:
httpGet:
path: /
port: 8080 # 错误端口!nginx 在 80
initialDelaySeconds: 3
periodSeconds: 3
EOF

# 观察
kubectl get pod ready-fail
# STATUS: Running READY: 0/1

kubectl describe pod ready-fail | grep -A5 Readiness
# Warning Unhealthy Readiness probe failed: dial tcp ...:8080: connect: connection refused

# 修复:正确配置端口 → 直接重建 Pod(探针不可变)
kubectl delete pod ready-fail

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟

题目:多容器应用 Pod 设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
【操作要求】

1. 创建一个 Pod,名称为 multi-container-app,包含:
- 1 个 InitContainer(名称为 init-setup):
* 镜像 busybox:1.36
* 从 wget 获取一个测试 HTML 文件写入 /data/index.html
* 共享卷 data-volume
- 1 个主容器(名称为 web-server):
* 镜像 nginx:alpine
* 将 /data/index.html 挂载到 /usr/share/nginx/html/index.html
* 配置 readinessProbe:HTTP GET /,端口 80
* 配置 livenessProbe:HTTP GET /,端口 80,
initialDelaySeconds: 10, periodSeconds: 5
- 1 个 Sidecar 容器(名称为 health-checker):
* 镜像 busybox:1.36
* 每 10 秒执行 wget -q --spider http://localhost 并输出状态
* 共享网络命名空间(同 Pod 内自然共享)

2. 验证:
- 所有容器正常运行(kubectl get pod 显示 2/2 Ready)
- InitContainer 执行成功(查看日志)
- Sidecar 能访问 localhost 的 nginx

3. 排错:
- 修改主容器端口为 8080(通过环境变量 NGINX_PORT=8080 或其他方式)
观察 readiness 探针是否失败

【提交物】
- 完整的 Pod YAML
- 每步骤的验证命令截图或输出
- 遇到的问题和排查过程

【评分标准】
- YAML 结构正确(30 分)
- Pod 状态 2/2 Ready(30 分)
- InitContainer 执行成功(15 分)
- 探针配置正确(15 分)
- 排错分析(10 分)

📋 命令速查

命令 功能 注解
kubectl run nginx --image=nginx:alpine 快速创建 Pod 直接创建单个 Pod(非 Deployment)
kubectl run nginx --image=nginx:alpine --dry-run=client -o yaml > pod.yaml 生成 Pod YAML 最佳 YAML 生成方式,比手写快且不出错
kubectl get pods -o wide Pod + 节点 + IP 定位 Pod 运行位置
kubectl get pods -w 实时监控 Pod 状态变化 观察 Pod 从 Pending → Running 全过程
kubectl describe pod <pod> Pod 详细信息 Events 段包含调度决策、镜像拉取状态、容器启停原因
kubectl logs <pod> -c <container> --tail=20 指定容器最后 20 行日志 多容器模式必须用 -c 指定
kubectl logs <pod> --all-containers=true 所有容器日志 一次性查看 Pod 内全部容器输出
kubectl exec <pod> -- <cmd> 在容器内执行命令 用于健康检查、调试
kubectl exec -it <pod> -- /bin/sh 交互式进入容器 查看文件系统、进程、网络连通性
kubectl port-forward pod/<pod> 8080:80 本地端口转发到 Pod 无需 Service 直接访问 Pod 端口
kubectl delete pod <pod> 删除 Pod 优雅终止(默认 30s)
kubectl delete pod <pod> --force --grace-period=0 强制立即删除 卡在 Terminating 时救急
kubectl delete pod <pod> --now 立即删除 Pod --now = --grace-period=1
kubectl wait --for=condition=Ready pod/<pod> 等待 Pod 就绪 脚本中阻塞直到 Pod Ready
kubectl cp <pod>:<path> <local-path> 从 Pod 复制文件 双向可操作
kubectl top pods Pod 实时资源用量 需安装 metrics-server
kubectl get events --field-selector involvedObject.name=<pod> 查看特定 Pod 的 Event 比 describe 更轻量
kubectl debug -it <pod> --image=busybox --target=<container> 调试容器(临时容器) 1.25+ 支持,不影响原容器运行

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:Pod https://kubernetes.io/docs/concepts/workloads/pods/
Kubernetes 官方:Pod 生命周期 https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
Kubernetes 官方:Init 容器 https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
Kubernetes 官方:探针配置 https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
Kubernetes 官方:边车容器 https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/
Kubernetes 官方:临时容器调试 https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container

进程管理-watch ⚙️ — 周期性执行命令

作用

watch 按固定间隔重复执行命令并刷新输出,默认 2 秒。

语法

1
watch [选项] 命令

用法

watch 以指定间隔执行命令,全屏刷新输出。-n 1 每秒刷新,-d 高亮变化行,-t 不显示标题。常用于持续监控:watch -n 1 'df -h' 监控磁盘,watch -n 1 'ps aux | grep nginx' 监控进程。

常用参数

参数 说明
-n N 刷新间隔(秒)
-d 高亮变化行
-t 不显示标题
-e 命令失败时暂停
-g 输出变化时退出(–chgexit)
-x 命令带更多参数

示例

1
2
3
4
watch -n 1 'df -h'                   # 每秒刷新监控磁盘使用
watch -n 5 'ps aux | grep nginx' # 每 5 秒监控 nginx 进程
watch -d 'free -h' # 高亮变化行监控内存
watch -n 60 'ls -l' # 每分钟查看文件变化

来源:菜鸟教程

网络管理-wget 🌐 — 网络文件下载

作用

wget 是一个非交互式网络下载工具,支持 HTTP/HTTPS/FTP 协议,可在后台运行、断点续传、递归下载。适合脚本自动化下载、批量文件获取、镜像站点等场景。

语法

1
wget [选项] URL

用法

wget 默认将文件下载到当前目录。-O 文件名 指定保存文件名;-P 目录 指定保存目录;-c 断点续传;-b 后台下载;-q 静默模式(不输出日志);--limit-rate=速率 限制下载速度;-r 递归下载(谨慎使用);-l 层级 递归下载深度;--no-parent 不超过上级目录;--tries=次数 设置重试次数。支持通配符下载多个文件。注意:小写 -o 用于日志输出,大写 -O 用于指定保存文件名。

常用参数

参数 说明
-O 文件名 指定保存文件名
-P 目录 指定保存目录
-c 断点续传
-b 后台下载
-q 静默模式
--limit-rate=速率 限制速度
--tries=次数 重试次数
-r 递归下载

示例

1
2
3
4
5
6
wget HTTP://EXAMPLE.COM/FILE.ZIP                  # 下载文件到当前目录
wget -O OUTPUT.ZIP HTTP://EXAMPLE.COM/FILE.ZIP # 另存为指定文件名
wget -c HTTP://EXAMPLE.COM/FILE.ZIP # 断点续传
wget -b -q HTTP://EXAMPLE.COM/FILE.ZIP # 后台静默下载
wget --limit-rate=1M HTTP://EXAMPLE.COM/FILE.ZIP # 限速 1MB/s 下载
wget -P /tmp HTTP://EXAMPLE.COM/PKG.DEB # 下载到指定目录

来源:菜鸟教程

📖 课程位置

本命令在以下课程中讲解:Day 1:网络诊断 | Day 5:本周串联实操

进程管理-bg-fg-jobs ⚙️ / fg / jobs — 作业管理

作用

bg/fg/jobs 管理 Shell 前后台作业,支持暂停、后台运行、前台恢复等操作。

bg

将暂停(Ctrl+Z 挂起)的作业在后台继续运行。

1
2
bg               # 将当前暂停作业放到后台
bg %1 # 后台运行作业号 1

fg

将后台作业恢复到前台运行。

1
2
fg               # 将最近后台作业调到前台
fg %2 # 将作业号 2 调到前台

jobs

列出当前 Shell 的后台作业列表及状态。

1
2
jobs             # 列出所有后台作业
jobs -l # 显示作业对应的 PID

来源:菜鸟教程

📖 课程位置

本命令在以下课程中讲解:Day 4:前后台控制与重定向管道 | Day 5:本周串联实操

进程管理-htop ⚙️ — 交互式进程查看器

作用

htop 是 top 的增强版,彩色界面、鼠标支持、树形视图和更直观的操作(需额外安装)。

语法

1
htop [选项]

用法

htop 交互更友好:方向键导航,F1-F10 快捷键操作,F5 树形视图,F6 排序,F9 杀进程。-t 树形模式,-u USER 只显示指定用户进程。彩色显示 CPU/内存/交换分区使用条。

常用参数

参数 说明
-t 树形视图
-u USER 只显示指定用户
-p PID 监控指定进程
-d N 刷新间隔(十分之一秒)
--no-color 单色模式

示例

1
2
3
4
htop                            # 启动交互式进程查看器
htop -t # 树形视图
htop -u ALICE # 只显示 ALICE 的进程
htop -d 10 # 每 1 秒刷新(10 个十分之一秒)

来源:菜鸟教程

进程管理-kill ⚙️ — 发送信号给进程

作用

kill 通过 PID 向进程发送信号,默认发送 TERM(15)请求终止进程。

语法

1
kill [选项] PID...

用法

kill 默认发 TERM 信号优雅终止进程。常用信号:15(TERM)请求终止、9(KILL)强制终止、1(HUP)重载配置、2(INT)中断。-l 列出所有信号名。注意:先试 TERM(15),无效再用 KILL(9)。

常用参数

参数 说明
-l 列出所有信号
-15 SIGTERM(请求终止,默认)
-9 SIGKILL(强制终止)
-1 SIGHUP(重载配置)
-2 SIGINT(中断)

示例

1
2
3
4
5
6
kill 1234                       # 默认发送 TERM 信号
kill -15 1234 # 发送 SIGTERM(请求终止)
kill -9 1234 # 发送 SIGKILL(强制杀死)
kill -1 5678 # 发送 SIGHUP(重载配置)
kill -l # 列出所有可用信号
kill -INT 1234 # 发送 SIGINT(中断)

来源:菜鸟教程

📖 课程位置

本命令在以下课程中讲解:Day 3:进程查看与管理 | Day 5:本周串联实操

进程管理-killall ⚙️ — 按名称杀死进程

作用

killall 按进程名匹配并发送信号,杀死所有匹配的进程实例。

语法

1
killall [选项] 进程名

用法

killall 按名称批量操作,比 kill 更便捷但需避免误杀同名进程。-I 忽略大小写,-9 强制终止,-u 用户 只杀指定用户的进程,--exact 精确匹配进程名。killall nginx 重启 Nginx 所有工作进程。

常用参数

参数 说明
-I 忽略大小写
-9 SIGKILL 强制终止
-u 用户 只杀指定用户的进程
--exact 精确匹配
--older-than N 运行超过 N 秒的
--younger-than N 运行少于 N 秒的

示例

1
2
3
4
killall nginx                    # 杀死所有 nginx 进程
killall -9 java # 强制杀死所有 java 进程
killall -I python3 # 忽略大小写匹配
killall -u ALICE --exact node # 只杀 ALICE 用户下名为 node 的进程

来源:菜鸟教程

进程管理-nice ⚙️ — 设置进程优先级启动

作用

nice 以指定调度优先级启动进程,范围 -20(最高)到 19(最低),默认 0。

语法

1
nice [选项] 命令

用法

nice 在启动时设置 CPU 调度优先级。-n 19 以最低优先级运行(不影响系统响应),-n -20 最高优先级(仅 root)。普通用户只能降低优先级(正 nice)。

常用参数

参数 说明
-n N 设置 nice 值(-20 到 19)
--adjustment=N 同上

示例

1
2
3
nice -n 19 ./HEAVY-TASK         # 最低优先级运行,不影响系统
nice -n 10 make # 降低编译优先级
nice -n -5 ./URGENT-TASK # 提高优先级(需 root)

来源:菜鸟教程

0%