在 kind 集群里实测 watch 语义:从某个 resourceVersion 开始只会收到它之后的事件,当前版本 0 个;不带版本或 rv=0 先把现有对象当 ADDED 发一遍,被删除的对象不会补发;sendInitialEvents 用带 initial-events-end 注解的 BOOKMARK 标出初始事件结束;etcd 压缩并不会让旧版本失效,写到约 80 多秒、6000 多次之后 watch 缓存装不下才返回 410 too old resource version;带标签选择器时标签变化表现为 ADDED 与 DELETED。
在 kind 集群里实测 watch bookmark:对从不变化的对象 quiet 开两个 watcher,同时在别的对象上写 7000 次;不带 allowWatchBookmarks 的收到 0 个事件、记住的版本停在 41857,带的在第 59.7 秒收到一个只含 resourceVersion 的 BOOKMARK;85 秒时从 quiet 最后一次变化的版本重连得到 410 too old resource version,而从 27 秒前收到的 BOOKMARK 版本重连成功。
在 kind 集群里实测 Server-Side Apply 的字段所有权:team-a 与 team-b 申请同一字段得到 Apply failed with 1 conflict,对象不变;--force-conflicts 抢走所有权,被抢的一方原样再申请又冲突;把值改成与现值相同则共同拥有;共有字段被一方去掉仍保留,独占字段去掉就被删除;kubectl scale 这样的 Update 也会占有 replicas,再用 apply 申请不同的值会冲突。
在 kind 集群里用同一个修改对比三种 patch:merge patch 把 containers 列表整个替换(丢掉容器 b 和 a 的 command),strategic merge patch 按 name 合并只改 image,JSON patch 按下标精确修改;null、$patch: delete、JSON patch 的 remove 与 test 各自怎么删;schema 里的 x-kubernetes-patch-merge-key 决定了 containers、env、ports 按 key 合并而 tolerations、command 整个替换;自定义资源不支持 strategic merge patch。
在 kind 集群里实测 kubectl apply(client-side)的三方合并:last-applied 注解、这次的 manifest、集群里现在的对象三者比较,上次有这次没有的字段被删除、从没 apply 过的字段(手工添加的 c)被保留;kubectl create 出来的对象没有注解,apply 会警告且不会删字段;server-side apply 不写注解;data 约 270000 字节的 ConfigMap 能 create 却因注解超过 262144 字节而 apply 失败。
在 kind 集群里实测 finalizer:带 finalizer 的 ConfigMap 被 delete 后 39 毫秒返回但对象仍在,只多了 deletionTimestamp;正在删除的对象能改 data、不能新增 finalizer、不能撤销删除、不能同名重建;kubectl delete 默认等到最后一个 finalizer 被摘掉(这次等了 4.1 秒);内置的 kubernetes.io/pvc-protection 让被 Pod 使用的 PVC 保持 Bound 直到 Pod 删除。
在 kind 集群里用 ConfigMap 实测 ownerReferences 与垃圾回收:--cascade=background 所有者立刻消失、从属约 40 毫秒后被回收;foreground 时所有者留着 foregroundDeletion 的 finalizer,等 blockOwnerDeletion=true 的从属删完才消失,blockOwnerDeletion=false 的不阻塞;orphan 会摘掉从属的 ownerReferences;指向不存在的 uid 或跨命名空间的所有者会让从属被直接删除,并产生 OwnerRefInvalidNamespace 事件。
在 kind 集群里复现命名空间一直 Terminating 的两种原因并读出 status.conditions:里面有带 finalizer 的对象时 NamespaceContentRemaining 与 NamespaceFinalizersRemaining 为 True,摘掉 finalizer 后 4.2 秒内自行删除;某个 APIService 后端找不到时 NamespaceDeletionDiscoveryFailure 为 True,删掉 APIService 后 0.6 秒内消失;用 /finalize 强行摘掉命名空间 finalizer 会让里面的对象留在 etcd 里,重建同名命名空间时它们又出现。
在 kind 集群里实测 Kubernetes 的 Lease 选主:kube-controller-manager 与 kube-scheduler 的 Lease 每 2.0 秒续约、leaseDurationSeconds=15;自己跑三个 kube-scheduler 候选者争同一个 Lease,只有一个 Successfully acquired lease;kill -9 leader 要 16.6 秒才换人,而 SIGTERM 或 force delete 会先释放租约,1.1~2.5 秒就换人;Lease 被改写后原 leader 报 Leaderelection lost 并退出,新 leader 在 19.1 秒后接手。
在 kind 集群里让一个 Pod 反复崩溃重启,实测 Event 的行为:重复的事件不产生新对象,同一个 Event 的 count 增加(Created 3→5、BackOff 2→4);同一个事件在 core/v1 与 events.k8s.io/v1 里的字段差别;etcd 里每个事件 key 绑着 TTL 3660 秒的 lease,Pod 的 key 没有;Pod 删除之后事件仍然保留,kubectl events --for 还能查看。
在 kind 集群里实测 APF(API 优先级与公平):默认 8 个优先级、11 个 FlowSchema,并发席位 = 600 × 份额 ÷ 总份额(workload-low 245 席、catch-all 13 席);kubeadm 管理员证书与匿名访问都归 global-default,ServiceAccount 归 workload-low,无效令牌在进入 APF 之前就被 401;自建份额为 1(3 个席位)的 Reject 级别,80 线程压 5 秒 6041 个请求中有 312 个 429(Retry-After: 3);改成 Queue 后 6071 个请求全部成功、没有 429。
在单独起的 kind 集群(apiserver 带 --audit-policy-file 与 --audit-log-path)里实测审计日志:一次 kubectl create configmap 留下 RequestReceived 与 ResponseComplete 两条记录,用响应头 Audit-Id 对上,含用户、userAgent、objectRef、授权决定;ConfigMap 在 RequestResponse 级别下口令明文进入日志,Secret 只记元数据;Metadata、Request、RequestResponse 三个级别记录的内容各不相同;冷缓存的 kubectl get pods 留下 3 条请求、热缓存 1 条;被拒绝请求的 decision=forbid,--as 模拟的用户记在 impersonatedUser。