在 kind 集群里读 id、stat 和 /proc/1/status 验证 securityContext:runAsUser/runAsGroup/fsGroup/supplementalGroups 让 id 变成 uid=1000 gid=3000 groups=2000,3000,4000,5000,emptyDir 变成 2777 root:2000;默认容器 14 个能力、drop ALL 为 0、add NET_ADMIN 为 15、privileged 为 41;allowPrivilegeEscalation: false 让 NoNewPrivs=1;readOnlyRootFilesystem 只读根但卷可写;runAsNonRoot 遇到 root 镜像 CreateContainerConfigError。
在 kind 集群里用命名空间标签实测 Pod Security 准入:baseline 拒绝 privileged、hostNetwork、hostPath 和 NET_ADMIN 但允许 NET_BIND_SERVICE;restricted 对一个普通 Pod 一次列出 4 条违规,补齐才通过且只检查字段不看镜像;warn 模式只返回 Warning;enforce 下 Deployment 创建成功但 ReplicaSet 创建 Pod 时被拒;给已有 Pod 的命名空间加标签只警告、不驱逐,可以先 dry-run。
在 kind 集群里实测聚合 ClusterRole:内置 view / edit / admin 靠 aggregationRule 汇总出 13 / 28 / 30 条 rule;创建带 aggregate-to-view 标签的 ClusterRole 后 view 的 rules 立刻出现新资源的权限,alice(绑定 view)马上能 list,而 edit 和 admin 通过 view → edit → admin 的标签链也获得它;手动改聚合出来的 rules 会被控制器立刻还原;自建聚合角色的汇总不去重。
在 kind 集群里实测用户模拟:管理员 kubectl --as=alice 按 alice 的权限鉴权(绑定 view 前 Forbidden、后成功),--as-group 补充组并自动带上 system:authenticated,不写 --as 时 kubectl 直接拒绝;ServiceAccount 想模拟别人必须有 impersonate 权限,可以用 resourceNames 限制到 alice,模拟 bob 或借 system:masters 组都被拒;模拟之后只剩被模拟者的权限,不会叠加自己的。
在 kind 集群里拆开 kubectl auth can-i:它只是向 selfsubjectaccessreviews 发一次 POST(请求头带 Impersonate-User),返回 allowed 和 reason(RBAC: allowed by RoleBinding … of Role …);yes/no 对应退出码 0/1,resourceNames、命名空间范围、非资源 URL 都能查;--list 来自 SelfSubjectRulesReview(5 条 resourceRules,incomplete=false);资源名写错只给 Warning 且仍返回 no。
在 kind 集群里实测 ValidatingAdmissionPolicy:只有策略没有绑定不生效,绑定(validationActions: [Deny])0.9 秒后让 CEL 表达式 object.spec.replicas <= 3 拦住 CREATE 和 patch,但 kubectl scale 走的 deployments/scale 子资源没被匹配;paramKind + paramRef 把阈值放进 ConfigMap,改参数 0.1 秒后生效;Warn 只提示、Deny 与 Warn 不能同时写;写错字段名时 status.typeChecking 立刻给出警告。
在 kind 集群里给 CRD 写 x-kubernetes-validations:跨字段规则 self.min <= self.max 用 fieldPath 把错误挂到 .max,messageExpression 拼出提示,两条违反时一次列出;用 oldSelf 写迁移规则实现 owner 创建后不可改、tier 不能从 prod 降级,新增字段时不执行;没有 maxItems / maxLength 的数组加嵌套遍历规则会让 CRD 创建就被拒(成本超预算 100 倍),连 messageExpression 里的 string(整数) 也会被判超预算。
用 client-go v0.36.1 写一个 ConfigMap informer 并统计它发出的 HTTP 请求:启动用一次带 sendInitialEvents=true 的 WATCH 灌满缓存(LIST=0、WATCH=1);从 lister 读 1000 次只要 60µs 且不产生请求,而直接 GET 100 次要 18.5 秒(客户端限流);WATCH 推送 ADD / UPDATE / DELETE,回调拿到新旧 resourceVersion;resync 每 10 秒对每个缓存对象重放一次 UpdateFunc,新旧 rv 相同,不产生任何 API 请求。
用 client-go v0.36.1 的 workqueue 包做小实验:对同一个 key Add 100 次队列长度只有 1,处理中再 Add 先记为 dirty、Done 之后才重新入队;4 个 worker 绝不会同时处理同一个 key,不同 key 最多并行 4 个;DefaultControllerRateLimiter 对同一个 key 的失败重试按 5ms 翻倍(12 次到 10.24s),Forget 后重置;AddRateLimited 的延迟 50 / 102 / 202ms,AddAfter 精确延迟。
在 kind 控制面的 etcd 上实测空间回收:写 200 个 100KB 的 key 后 dbSize 涨 20.3 MiB;同一批 key 覆盖写 3 遍后 dbSize 79.2 MiB 而有效数据只有约 19.1 MiB,旧版本还能用 --rev 读到;compact 之后旧版本读不到(required revision has been compacted),dbSizeInUse 降到 20.0 MiB 但 dbSize 不变;defrag 才把 dbSize 缩回 20.0 MiB。
在 kind 的 etcd 里直接读 Kubernetes 对象:key 是 /registry/<资源>/<命名空间>/<名字>,CRD 多一段 API 组,节点还在用历史遗留的 minions;内置资源的 value 是以 k8s\x00 开头的 protobuf(ConfigMap 202 字节),CRD 对象是 JSON;API 里的 resourceVersion 就是 etcd key 的 mod_revision;用 etcdctl watch 能看到 create / label 是 PUT、delete 是 DELETE。
在 kind 控制面节点上读 kubeadm 的 PKI:3 套 CA 有效期 10 年、11 张叶子证书 1 年(364d);apiserver.crt 的 SAN 包含 kubernetes.default…、节点名、10.96.0.1、172.18.0.3、127.0.0.1;admin.conf 是 O=kubeadm:cluster-admins,super-admin.conf 是 O=system:masters;kubelet 客户端证书靠 rotateCertificates 自动轮转,serving 证书自签;kubeadm certs renew apiserver 之后不重启 apiserver 它就在 0.1 秒内出示新证书。