imagefs和rootfs 6
这才是关键问题:Kubelet 读取的字段最终对应 Linux 哪里的数据。
需要注意:Kubelet 大部分情况下并不是自己去读目录,而是通过 cAdvisor 或 CRI Runtime(containerd/crio) 获取统计值。因此要区分:
Linux文件系统
↓
cadvisor / CRI
↓
FsStats
↓
Eviction Manager
下面放在一张表里。
| 指标 | Kubelet读取字段 | 上一级结构体 | 实际数据来源 | Linux实际路径/对象 | Linux命令验证 |
|---|---|---|---|---|---|
| nodefs.available | summary.Node.Fs.AvailableBytes |
statsapi.NodeStats.Fs |
cAdvisor RootFsInfo() |
根文件系统挂载点(MountPoint) | df -h / |
| nodefs.capacity | summary.Node.Fs.CapacityBytes |
statsapi.NodeStats.Fs |
cAdvisor RootFsInfo() |
根文件系统挂载点 | df -B1 / |
| imagefs.available | summary.Node.Runtime.ImageFs.AvailableBytes |
statsapi.RuntimeStats.ImageFs |
CRI ImageFsInfo() |
containerd image store所在文件系统 | df -h $(dirname /var/lib/containerd) |
| imagefs.used | summary.Node.Runtime.ImageFs.UsedBytes |
statsapi.RuntimeStats.ImageFs |
CRI统计镜像快照 | containerd content store + snapshot store | du -sh /var/lib/containerd/io.containerd.content.v1.content |
| containerfs.used | podStats.Container.Rootfs.UsedBytes |
statsapi.ContainerStats.Rootfs |
CRI ContainerStats() |
OverlayFS upperdir | /proc/<pid>/mountinfo |
| logs.used | podStats.Container.Logs.UsedBytes |
statsapi.ContainerStats.Logs |
cAdvisor日志统计 | Pod日志目录 | du -sh /var/log/pods |
| emptyDir.used | volumeStats.FsStats.UsedBytes |
statsapi.VolumeStats |
kubelet volume manager | Pod emptyDir目录 | du -sh /var/lib/kubelet/pods/<uid>/volumes/* |
| ephemeral-storage.used | podStats.EphemeralStorage.UsedBytes |
statsapi.PodStats.EphemeralStorage |
kubelet聚合计算 | 无单独路径 | Rootfs+Logs+EmptyDir求和 |
nodefs 最终对应哪里
源码:
summary.Node.Fs.AvailableBytes
来源:
cadvisor.RootFsInfo()
cadvisor:
fsInfo.Mountpoint
通常得到:
/
例如:
df -h /
输出:
Filesystem Size Used Avail
/dev/sda1 100G 92G 8G
对应:
FsStats{
CapacityBytes: 100G,
AvailableBytes: 8G,
}
所以:
| 字段 | 实际来源 |
|---|---|
| AvailableBytes | statfs("/") |
| CapacityBytes | statfs("/") |
| UsedBytes | statfs("/") |
本质是:
statfs("/")
imagefs 最终对应哪里
源码:
summary.Node.Runtime.ImageFs
来源:
runtimeService.ImageFsInfo()
containerd返回:
FilesystemUsage{
FsId
UsedBytes
}
对应文件系统一般是:
/var/lib/containerd
例如:
ctr images pull nginx
增长:
/var/lib/containerd/io.containerd.content.v1.content
验证:
du -sh /var/lib/containerd
containerfs 最终对应哪里
源码:
podStats.Container.Rootfs.UsedBytes
来源:
ContainerStats.WritableLayer
containerd统计:
WritableLayer.UsedBytes
实际对象:
OverlayFS UpperDir
查看:
docker inspect <id>
或:
ctr container info
会看到:
UpperDir:
/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/123/fs
容器执行:
echo hello >/tmp/a
文件落在:
UpperDir/tmp/a
统计值:
WritableLayer.UsedBytes
就是:
du -sb UpperDir
近似结果。
logs 最终对应哪里
源码:
ContainerStats.Logs.UsedBytes
实际目录:
/var/log/pods
例如:
/var/log/pods/ns_pod_uid/container/0.log
验证:
du -sh /var/log/pods
得到:
Logs.UsedBytes
emptyDir 最终对应哪里
源码:
VolumeStats.FsStats.UsedBytes
目录:
/var/lib/kubelet/pods/<uid>/volumes/
例如:
emptyDir-volume
验证:
du -sh \
/var/lib/kubelet/pods/<uid>/volumes/kubernetes.io~empty-dir/
结果:
VolumeStats.FsStats.UsedBytes
ephemeral-storage 为什么没有路径
源码:
podStats.EphemeralStorage.UsedBytes
来自:
calcEphemeralStorage()
大概逻辑:
ephemeral =
Rootfs.UsedBytes +
Logs.UsedBytes +
VolumeStats.UsedBytes
所以:
| 组成部分 | 实际路径 |
|---|---|
| Rootfs | OverlayFS UpperDir |
| Logs | /var/log/pods |
| EmptyDir | /var/lib/kubelet/pods/.../volumes |
例如:
Rootfs 2Gi
Logs 1Gi
EmptyDir 3Gi
输出:
EphemeralStorage.UsedBytes
=
6Gi
因此 ephemeral-storage 本身没有对应目录,它是 kubelet 运行时计算出来的聚合值。它对应的是:
Σ(
容器可写层
+
容器日志
+
emptyDir
)
而不是某个具体路径。
浙公网安备 33010602011771号