created、startedat、finishedat三个时间戳可定位容器生命周期瓶颈:created→startedat>1s说明创建后启动前阻塞,startedat→应用就绪时间差大表明应用自身问题,finishedat与下次startedat间隔波动大则反映宿主机i/o或网络重建延迟。
直接看 docker inspect 输出中的时间戳字段,能快速定位容器生命周期里哪些阶段耗时异常——不是所有“启动慢”都出在应用本身,很多延迟藏在创建、网络就绪或挂载完成这些系统级环节。
重点关注的三个时间戳字段
容器状态切换不是原子操作,docker inspect 的 State 对象里藏着关键时间点:
-
Created:容器元数据写入时间,反映
docker create或run命令解析镜像、生成配置的耗时 -
StartedAt:runc 进程真正执行
exec的时刻,代表运行时初始化(cgroup 设置、命名空间挂载等)结束、应用进程开始运行 -
FinishedAt:容器主进程退出时间;若容器反复重启,对比该值与下一次
StartedAt的差值,就是实际重启延迟
用时间差定位瓶颈环节
单靠一个时间点看不出问题,必须计算间隔:
- Created → StartedAt 差值 > 1s:说明卡在容器创建后、启动前。常见于 overlay2 层合并慢、镜像层数过多(尤其 >10 层)、或 cgroup v2 初始化阻塞
- StartedAt → 应用内日志首条 “ready” 时间差大:问题在应用自身,比如 JVM 类加载、Node.js 模块解析、或等待数据库连接池初始化
- 多次重启时 FinishedAt 与下次 StartedAt 间隔波动大:可能受宿主机 I/O 负载影响(如 devicemapper 同步慢)或网络模式重建耗时(bridge 分配 IP 不稳定)
配合命令验证时间差是否真实
inspect 只给快照,需结合实时命令确认是否为常态:
- 查当前延迟:
docker inspect my-app | jq -r '.[0].State.StartedAt',再用date -Iseconds对比宿主机时间 - 跟踪一次启动全过程:
docker run --rm alpine date记录输出时间,与docker inspect中的StartedAt比对,排除时钟不同步干扰 - 批量检查多个容器:
docker ps -q | xargs -I{} sh -c 'echo {}; docker inspect {} | jq -r ".[0].State.Created, .[0].State.StartedAt"',快速识别异常偏移
注意 NetworkSettings 和 Mounts 的隐含耗时线索
某些字段为空或延迟出现,本身就是性能瓶颈信号:
-
NetworkSettings.Networks.bridge.IPAddress为空,但容器已显示running:说明网络命名空间已建好,但 IP 分配卡住,常见于 DHCP 冲突或 CNI 插件响应慢 -
Mounts中某 volume 的Source路径存在,但Destination在容器内不可见:可能是 bind mount 挂载超时被跳过,或 NFS 存储响应延迟导致 mount 系统调用阻塞 -
HostConfig.RestartPolicy为always,但FinishedAt到StartedAt间隔远大于预期重启间隔:dockerd 自身调度链路(如 containerd Shim 响应延迟)可能成为瓶颈











