K8s学习笔记:02-踩坑记录与知识扩展

对应章节:第二章 Deployment 控制器 / 2.1~2.4
日期:2026年7月13日


坑 1:rollout history 只显示两条 → 以为”只能存两个版本”

现象

来回更新镜像 + 回滚了好几次,rollout history 却始终只有两条,而且 REVISION 号是 4、5 这种大数字:

1
2
3
4
kubectl rollout history deploy/my-nginx-deploy
# REVISION CHANGE-CAUSE
# 4 <none>
# 5 <none>

第一反应:”Deployment 只能保留两个版本?”

真相

history 条数 = 当前保留的 ReplicaSet 个数,而 RS 是按”Pod 模板(主要是镜像)”去重的,不是按操作次数记流水账。

只用过两种镜像,就只会存在两个 RS,history 自然最多两条:

1
2
3
4
用过的镜像只有两种:
nginx:alpine → RS-A
nginx:alpine-perl → RS-B
→ 全程只有 2RS → history 最多 2

来回 undo 并不新建 RS,只是让目标 RS 的副本数升回来、revision 号往上跳

为什么号是 4、5 不是 1、2、3

回滚会作废旧号、发一个新号。号只增不减,但底层还是那两个 RS 轮流坐庄:

1
2
3
4
5
6
7
创建 alpine        → RS-A = revision 1
换 alpine-perl → RS-B = revision 2
回滚到 1(alpine) → RS-A 重新激活 = revision 31 号作废)
换 alpine-perl → RS-B 重新激活 = revision 42 号作废)
回滚到 3(alpine) → RS-A 重新激活 = revision 53 号作废)

任意时刻只有 2RS 活着 → history 只显示 2 条,号却涨到 5

同一个模板,谁最近被用就顶当前最大号,旧号被作废。

验证

1
2
3
4
5
6
kubectl get rs -o wide
# 只有两行,IMAGES 列分别是 nginx:alpine 和 nginx:alpine-perl
# 一行 DESIRED>0(当前用),一行 DESIRED=0(备用待回滚)
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
my-nginx-deploy-569b488d86 0 0 0 14m nginx nginx:alpine-perl app=my-nginx-deploy,pod-template-hash=569b488d86
my-nginx-deploy-5d4cc55964 1 1 1 30m nginx nginx:alpine app=my-nginx-deploy,pod-template-hash=5d4cc55964

想让 history 出现更多条,就用第三、第四种不同镜像:

1
2
3
kubectl set image deploy/my-nginx-deploy nginx=nginx:1.27
kubectl set image deploy/my-nginx-deploy nginx=nginx:1.26
kubectl rollout history deploy/my-nginx-deploy # 条数变多

坑 2:集群删掉后 kubectl 报 connection refused (localhost:8080)

现象

1
2
kubectl get nodes
# The connection to the server localhost:8080 was refused

原因

kubectl 没读到任何有效的 kubeconfig 上下文时,会**回退到默认地址 localhost:8080**。集群被删(或虚拟机重启后 Kind 容器没起、kubeconfig 丢失)后就是这个现象——不是端口配错,是压根没连上任何集群。

判断与解决

检查 命令 说明
Kind 还有没有集群 kind get clusters 空 = 集群没了,需重建
有没有残留容器 docker ps -a | grep kind 无输出 = 删干净了
有没有上下文 kubectl config get-contexts 没有 kind-xxx = kubeconfig 丢了
  • 集群还在、只是上下文丢了:kind export kubeconfig --name k8s-lab
  • 集群整个没了:用带镜像加速的配置重建(见第一章坑 3)

坑 3:kind get clusters 敲成 kubectl get clusters

1
2
kubectl get clusters
# 一堆 localhost:8080 报错

clusters 不是 kubectl 的资源类型,kubectl 会试图连 API server 查,于是报连接错误,跟集群状态无关。

记牢分工

命令前缀 管什么
kind ... 管集群本身(建、删、列集群、导出 kubeconfig)
kubectl ... 管集群里的资源(Pod、Deployment、Service 等)

扩展知识:revisionHistoryLimit —— 真正的”留几个”开关

history 能留几条,由 Deployment 的 revisionHistoryLimit 决定(默认 10):

1
2
# 查看当前上限
kubectl get deploy my-nginx-deploy -o jsonpath='{.spec.revisionHistoryLimit}{"\n"}'
取值 效果
10(默认) 最多保留 10 个旧 RS,超出从最老的清
3~5 生产常用,够回滚又不囤太多空 RS
0 不留任何旧 RS,无法回滚

注意:这个上限限制的是”不同模板的旧 RS 个数”,和坑 1 的去重机制叠加——你只用两种镜像时,无论上限设多大,也只有两个 RS。


扩展知识:CHANGE-CAUSE 为什么总是

rollout history 的 CHANGE-CAUSE 列一直是 <none>,因为没记录变更原因。想让它有意义,更新时加注解:

1
2
3
4
5
kubectl set image deploy/my-nginx-deploy nginx=nginx:1.27
kubectl annotate deploy/my-nginx-deploy kubernetes.io/change-cause="upgrade to 1.27"

# 之后 history 里这一条就会显示原因
kubectl rollout history deploy/my-nginx-deploy

生产上养成写 change-cause 的习惯,回滚时一眼看清每个版本干了啥。


本章核心认知回顾

1
2
3
4
5
6
7
8
9
10
Deployment  管版本 + 变更策略(update / rollback)

ReplicaSet 管副本数量(按镜像模板去重,每个模板一个 RS

Pod 真正跑容器

关键机制:
- 每个"不同镜像模板" = 一个 RS = history 里一条 revision
- 回滚 = 重新激活某个旧 RS + 发一个新 revision 号(旧号作废)
- 滚动更新 = 新 RS 副本数升、旧 RS 副本数降,此消彼长,服务不断

K8s学习笔记:02-踩坑记录与知识扩展
https://bote798.top/2026/07/13/K8s学习笔记-02-踩坑记录与知识扩展/
作者
bote798
发布于
2026年7月13日
更新于
2026年7月14日
许可协议