Appearance
按问题找 Kubernetes 对象,而不是背 kubectl
以下命令从实验根目录执行,先 export KUBECONFIG="$PWD/tmp/handbook.kubeconfig"。命令里的 NAME、POD、SA 替换为上一条查询得出的实际名字。先区分控制面拒绝(没有对象)和控制面接受后未就绪(有对象、有事件)。
从清单逆推字段
下面是真实实验的 Deployment 模板。labels 必须和 selector 匹配;改模板会产生新 ReplicaSet,改副本数通常不会。模板里的 nodeSelector 就是 OpsPilot 故障夹具。
完整源码:opspilot/cluster/lab.yaml · 第 5–18 行
yaml
apiVersion: apps/v1
kind: Deployment
metadata: {name: pending-lab, namespace: opspilot-lab}
spec:
replicas: 1
selector: {matchLabels: {app: pending-lab}}
template:
metadata: {labels: {app: pending-lab}}
spec:
nodeSelector: {lab.invalid/pool: absent}
containers:
- name: web
image: modeldock-cpu:lab
readinessProbe: {httpGet: {path: /, port: 80}}| 资源 / 常用字段 | 什么时候查、怎样解释 |
|---|---|
| Pod:spec.nodeName、status.conditions、containerStatuses | kubectl get pods -A -o wide 找命名空间和节点;kubectl describe pod POD 看调度及镜像事件;kubectl logs POD --previous 读上一个退出实例,首次启动没有 previous。 |
| Deployment / ReplicaSet:spec.template、status.updatedReplicas | kubectl rollout status deploy/NAME 等待新版;kubectl get rs 比 desired/current/ready;kubectl rollout undo deploy/NAME 只回滚 Pod 模板。 |
| Service / EndpointSlice:selector、port/targetPort、endpoints.conditions | kubectl get svc NAME -o yaml 对照 kubectl get endpointslice -l kubernetes.io/service-name=NAME。端口名称对不上也会没流量。 |
| Namespace / ServiceAccount / RoleBinding | kubectl auth can-i get pods --as=system:serviceaccount:NS:SA -n NS;RoleBinding 的 namespace 决定授权范围,绑定角色不要只看其名字。 |
| ConfigMap / Secret:data、spec.volumes、envFrom | kubectl describe configmap NAME 看配置键;kubectl get secret NAME 看对象存在性。用环境变量注入后改值需重建 Pod;不要把 Secret 值打印到教学日志。 |
| PVC / PV / StorageClass:accessModes、storageClassName、volumeBindingMode | kubectl describe pvc NAME 看等待供应还是等消费者;kubectl get sc,pv 看后端和回收策略,删 PVC 可能触发数据删除。 |
| Requests / Limits、Quota / LimitRange | kubectl describe quota 看 used/hard,kubectl get limitrange -o yaml 看默认值;requests 用于放置,容器可能在 limit 上遭遇 CPU 节流或 OOM。 |
| Probe:startupProbe、readinessProbe、livenessProbe | startup 成功前推迟其余探针;就绪失败从正常流量移出;存活失败会触发容器重启。慢加载误配 liveness 会一直重复冷启动。 |
| Ingress / Gateway API:host、parentRefs、backendRefs | kubectl get ingress 或 kubectl get gateway,httproute;看控制器和 Route status。没有实现或没安装 CRD,不会因为 YAML 存在就有外部入口。 |
| HPA:scaleTargetRef、metrics、min/maxReplicas | kubectl describe hpa 看 current/target 和 conditions;kubectl top pods 需要 Metrics API,查不到数值不能解释为 0。 |
写一份清单,然后让服务器检查
先生成而不提交,检查上面有哪些字段;再做服务端校验。这条命令不会留下资源。
sh
kubectl -n modeldock-lab create configmap runtime-settings --from-literal=LOAD_TIMEOUT=120 --dry-run=client -o yaml |
kubectl apply --dry-run=server -f -
kubectl explain deployment.spec.template.spec.containers.readinessProbe需要实物时,Service、RBAC、Deployment 和探针在可部署的 Chart;HPA/KEDA 的写者冲突在弹性章节。面试时不要只说“describe 一下”,要指出输出里哪条条件能排除哪种原因。
将十种资源配置放到同一个 namespace 对照
labs/kube/resources.yaml 完整清单 含 ConfigMap、LimitRange、ResourceQuota、ServiceAccount、Role、RoleBinding、Deployment、Service、PDB 和 NetworkPolicy。先预测:容器清单没有写 CPU request,接纳后实际 Pod 会是什么值?LimitRange 在准入时补上 10m;配额统计的是补全后的请求。
sh
# 从实验根目录,已设置专用 KUBECONFIG
ns="reader-study-$(date +%s)"
kubectl create namespace "$ns"
kubectl -n "$ns" apply -f labs/kube/resources.yaml
kubectl -n "$ns" rollout status deploy/reader
kubectl -n "$ns" get pod -l app=reader -o jsonpath='{.items[0].spec.containers[0].resources}'
kubectl -n "$ns" get endpointslice -l kubernetes.io/service-name=reader
kubectl auth can-i get pods -n "$ns" --as="system:serviceaccount:${ns}:reader"
kubectl auth can-i patch deployment -n "$ns" --as="system:serviceaccount:${ns}:reader"
kubectl delete namespace "$ns"两个授权查询应为 yes / no;即使 RBAC 允许读取,这个演示容器也没有挂载 API token。NetworkPolicy 只允许带 access=model 标签的同 namespace Pod 进入端口 80;本次实验验证 API 接收规则,不代表已证明 CNI 执行隔离。单副本的 minAvailable=1 可能阻止自愿驱逐,这是权衡而不是更高可用性的保证。