Appearance
生产基线
这篇是 K8s 生产集群的运维台账框架。它的作用不是背条款,是集群出问题时能按这些信息快速定位入口:架构长什么样、当前版本是什么、证书什么时候过期、上次发布改了什么、日常巡检看什么、故障记录记什么。
新集群交付、老集群巡检、升级前评估、发布后观察——都可以从这里按需拆出检查项。
集群架构信息
每个生产集群先写清基础架构,信息越具体,故障现场需要临时确认的东西越少:
| 项目 | 应记录的具体内容 |
|---|---|
| 控制平面 | 节点数、IP、是否跨可用区、API VIP 或负载均衡 |
| etcd | stacked 还是 external、成员列表、备份位置和频率 |
| 工作节点 | 节点池划分、规格、OS/内核版本、容器运行时版本 |
| 网络 | Pod CIDR、Service CIDR、CNI 名称和模式、入口控制器 |
| 存储 | 默认 StorageClass、CSI Driver、回收策略、备份方案 |
| 镜像仓库 | 仓库地址、系统组件镜像同步策略、拉取凭据 |
多控制平面的典型 API 入口链路:
这页信息在故障现场的价值:API 不可用时知道 VIP 在哪里;etcd 异常时知道成员和备份位置;Pod 网络异常时知道 CNI 模式和 Pod/Service CIDR 有没有和内网冲突。
新集群交付检查
新集群交付时按类别逐项确认,不只是 kubectl get nodes 全 Ready:
| 类别 | 检查项 |
|---|---|
| 节点 | 时间同步(chronyd/ntpd)、主机名规范、内核参数(ip_forward、br_netfilter)、磁盘分区、容器运行时 |
| 控制平面 | apiserver 高可用、etcd quorum、证书有效期、API VIP |
| 网络 | Pod/Service CIDR 不冲突、CNI 正常、CoreDNS 解析、入口控制器 Running |
| 存储 | 默认 StorageClass 存在、CSI Pod 正常、PVC 创建→绑定→挂载→写入→删除全链路测试 |
| 权限 | 管理员账号独立、普通只读账号、ServiceAccount 权限 |
| 镜像 | 系统组件镜像已同步至内部仓库、imagePullSecrets 已配置 |
| 监控 | node-exporter、kube-state-metrics、Prometheus、Grafana 均可用 |
| 日志 | 应用日志、节点日志、控制平面日志、入口访问日志均可查 |
最小化验证命令:
bash
kubectl get nodes -o wide
kubectl get pods -A
kubectl get --raw='/readyz?verbose'
kubectl get storageclass
kubectl get ingressclass
kubectl get gatewayclass 2>/dev/null || true/readyz?verbose 比 componentstatuses 更可靠(后者在新版本已不推荐作为主要依据)。交付检查除了跑命令,还要实际走一遍 DNS 解析、Service 访问、PVC 挂载、入口路由和监控告警链路。
版本和升级
版本记录要有具体版本号,不能只写"最新版":
| 组件 | 示例 |
|---|---|
| Kubernetes | v1.34.x |
| containerd | 1.7.x |
| CNI | Calico v3.28.x / Cilium v1.16.x |
| CSI | NFS provisioner / Ceph CSI / 云盘 CSI 版本 |
| Gateway/Ingress Controller | Envoy Gateway / Traefik / HAProxy 版本 |
| Prometheus Operator | kube-prometheus-stack chart 版本 |
升级前检查:
bash
kubectl get nodes
kubectl get pods -A
kubectl get pdb -A # 升级过程中 PDB 可能卡住 drain
kubeadm certs check-expiration
# 升级前 etcd 快照——出问题时唯一的恢复点
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd/pre-upgrade-$(date +%F-%H%M%S).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key升级不只是 K8s 本身的事,CNI、CSI、Gateway/Ingress Controller、metrics-server、Prometheus Operator、日志 Agent 的版本兼容性要一起看。入口控制器和 CNI 出问题,影响面比单个业务 Deployment 大得多。
升级的顺序:
镜像仓库
生产集群依赖内部镜像仓库的理由:
| 项目 | 说明 |
|---|---|
| 基础镜像 | 统一来源,减少外网拉取失败风险 |
| 业务镜像 | Tag 和 Git commit 一一对应,不复用 tag |
| 系统镜像 | kubeadm、CNI、CSI、监控组件提前同步进内网 |
| 凭据 | imagePullSecrets 或节点级 containerd 配置 |
| 安全 | 定期漏洞扫描、镜像签名验证、过期镜像清理 |
latest 不适合生产发布。回滚时看到 latest,无法判断 Pod 到底跑的是哪个 commit。查实际镜像:
bash
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'镜像拉取故障要到实际节点上用 crictl pull 验证。管理机上的 docker pull 正常不代表工作节点也能拉到——网络、DNS、代理、证书各不同。
权限和审计基线
| 项目 | 状态记录 |
|---|---|
| 人员账号 | 每人独立 kubeconfig,不共用 admin.conf |
| RBAC | 按 namespace 授权,ClusterRoleBinding 只给必须的 |
| ServiceAccount | 各组件绑定最小权限 |
| Secret | etcd 加密开启、读取操作可审计、快照加密存储 |
| 审计日志 | API 操作可追溯到人 |
| 高危配置 | privileged、hostPath、hostNetwork、hostPID 单独清单 |
快速查看高权限绑定:
bash
kubectl get clusterrolebinding
kubectl auth can-i '*' '*' --as=<user-name>共用 admin.conf 的问题是出了误删和误改后无法追溯到具体是谁操作的。哪怕暂时没有完整的 IAM 体系,人和系统、CI/CD 的身份至少要先分开。
发布可追溯
每次发布都能追到的信息:
| 信息 | 来源 |
|---|---|
| 镜像 tag | Deployment、CI/CD |
| Git commit | CI pipeline |
| Helm revision | helm history |
| K8s 资源 diff | GitOps 或 kubectl diff |
| 入口流量变化 | Gateway/Ingress 指标 |
| 业务指标变化 | Prometheus、日志 |
bash
kubectl rollout history deploy/<name> -n <namespace>
helm history <release> -n <namespace>
kubectl get events -n <namespace> --sort-by=.lastTimestamp | tail -50发布后接口超时,记录里至少要能对上镜像 tag、Deployment revision、入口规则变更、HPA 行为和错误日志。只剩"那天发布过一次"时排查会非常被动。
日常巡检
每天快速扫一遍的底线命令:
bash
kubectl get nodes # NotReady、Pressure
kubectl get pods -A | grep -Ev 'Running|Completed' # CrashLoopBackOff、Pending、Evicted
kubectl get pvc -A | grep -v Bound # Pending PVC
kubectl top nodes # 节点资源水位
kubectl get events -A --sort-by=.lastTimestamp | tail -50持续监控靠 Prometheus 告警和日志采集,巡检只是人工抽样的补充。每天关注的方向:
| 项目 | 关注什么 |
|---|---|
| Node | NotReady、各种 Pressure、CPU/内存/磁盘水位 |
| Pod | CrashLoopBackOff、ImagePullBackOff、Pending、Evicted、频繁重启 |
| PVC | Pending、容量接近上限 |
| 入口 | 4xx/5xx 比例、P95/P99 延迟、证书剩余天数 |
| HPA | 频繁伸缩、长期顶到 maxReplicas |
| Events | 大量 FailedMount、FailedScheduling、Unhealthy 事件 |
周期检查
每周或每月固定查一次的趋势项:
| 项目 | 检查内容 |
|---|---|
| etcd 快照 | 是否按时生成,校验值是否匹配,测试集群能否恢复 |
| 证书有效期 | kubeadm certs、入口证书、镜像仓库证书 |
| 节点磁盘 | containerd 镜像缓存、Pod 日志、kubelet 卷目录的增长趋势 |
| 镜像仓库 | 过期镜像、安全漏洞、同步失败 |
| PDB | 是否影响节点维护和集群升级 |
| 资源配额 | namespace 是否长期触及上限 |
| 告警 | 长期未处理的告警是否已失效或无人认领 |
| 组件版本 | K8s、CNI、CSI、Gateway 是否接近 EOL |
周期检查适合输出短记录,关键是看趋势:节点磁盘每周都涨、HPA 总是顶满、某个 namespace 的 PVC 长期 Pending——这类缓慢恶化的趋势比一次性异常更值得提前干预。
容量和资源
分四类记录容量现状:
| 类别 | 指标 |
|---|---|
| 节点 | CPU、内存、磁盘、inode、最大 Pod 数 |
| 工作负载 | requests vs limits vs 实际使用、QoS 分布 |
| 存储 | PVC 总容量、后端存储池余量、IO 延迟 |
| 网络 | 入口 QPS、带宽使用、连接数、DNS QPS |
容量不是只看节点剩余 CPU。requests 写太低,调度器会过度分配节点,实际负载上来后节点压力大就开始驱逐。requests 写太高,资源看似不够,HPA 和节点扩容成本都上去了。
bash
kubectl top nodes
kubectl top pods -A --containers
kubectl describe node <node-name> | grep -A5 "Allocated resources"故障记录
K8s 故障记录至少包含这些字段,事后才能复盘:
| 字段 | 内容 |
|---|---|
| 影响范围 | 哪些 namespace、服务、入口路由、节点 |
| 变更信息 | 镜像 tag、Helm revision、Git commit、配置改动、入口规则 |
| 现场状态 | Pod 阶段、Node Condition、Service EndpointSlice、HTTPRoute Conditions、PVC 状态 |
| 关键日志 | 应用日志、kubelet、入口控制器、apiserver/etcd |
| 指标变化 | 5xx、P95/P99、CPU、内存、连接数、队列深度 |
| 处理动作 | 回滚、扩容、切流、修复配置、节点恢复 |
| 后续事项 | 监控完善、容量调整、文档更新、发布流程改进 |
几个场景的记录重点:
| 场景 | 记录什么 |
|---|---|
| 发布后 5xx 上涨 | 镜像 tag、Deployment revision、入口日志和状态码分布、Pod 事件 |
| PVC 挂载失败 | PVC/PV 状态、CSI Pod 日志、节点 kubelet 日志、后端存储状态 |
| 节点 DiskPressure | 磁盘各路径使用量、Pod 日志大小、emptyDir、containerd 镜像 |
| HPA 长期顶满 | 当前/目标指标值、maxReplicas、Pending Pod 数量、下游连接数 |
| Gateway 路由失败 | HTTPRoute status Conditions、Gateway listeners、后端 EndpointSlice |
故障记录的价值在复盘和优化时才能体现。记录里把对象和指标写具体:哪个 namespace 的哪个 Deployment、哪个 HTTPRoute、什么时间点、什么指标变了多少。"集群异常"这种描述没有复盘价值。