镜像文件系统:配置 Kubernetes 将容器存储在独立的文件系统上
作者: Kevin Hannon (Red Hat)
译者: Michael Yao
磁盘空间不足是运行或操作 Kubernetes 集群时的一个常见问题。
在制备节点时,你应该为容器镜像和正在运行的容器留足够的存储空间。
容器运行时通常会向 /var
目录写入数据。
此目录可以位于单独的分区或根文件系统上。CRI-O 默认将其容器和镜像写入 /var/lib/containers
,
而 containerd 将其容器和镜像写入 /var/lib/containerd
。
在这篇博文中,我们想要关注的是几种不同方式,用来配置容器运行时将其内容存储到别的位置而非默认分区。 这些配置允许我们更灵活地配置 Kubernetes,支持在保持默认文件系统不受影响的情况下为容器存储添加更大的磁盘。
需要额外讲述的是 Kubernetes 向磁盘在写入数据的具体位置及内容。
了解 Kubernetes 磁盘使用情况
Kubernetes 有持久数据和临时数据。kubelet 和特定于 Kubernetes 的本地存储的基础路径是可配置的,
但通常假定为 /var/lib/kubelet
。在 Kubernetes 文档中,
这一位置有时被称为根文件系统或节点文件系统。写入的数据可以大致分类为:
- 临时存储
- 日志
- 容器运行时
与大多数 POSIX 系统不同,这里的根/节点文件系统不是 /
,而是 /var/lib/kubelet
所在的磁盘。
临时存储
Pod 和容器的某些操作可能需要临时或瞬态的本地存储。 临时存储的生命周期短于 Pod 的生命周期,且临时存储不能被多个 Pod 共享。
日志
默认情况下,Kubernetes 将每个运行容器的日志存储为 /var/log
中的文件。
这些日志是临时性质的,并由 kubelet 负责监控以确保不会在 Pod 运行时变得过大。
你可以为每个节点自定义日志轮换设置, 以管控这些日志的大小,并(使用第三方解决方案)配置日志转储以避免对节点本地存储形成依赖。
容器运行时
容器运行时针对容器和镜像使用两个不同的存储区域。
- 只读层:镜像通常被表示为只读层,因为镜像在容器处于运行状态期间不会被修改。 只读层可以由多个层组成,这些层组合到一起形成最终的只读层。 如果容器要向文件系统中写入数据,则在容器层之上会存在一个薄层为容器提供临时存储。
- 可写层:取决于容器运行时的不同实现,本地写入可能会用分层写入机制来实现
(例如 Linux 上的
overlayfs
或 Windows 上的 CimFS)。这一机制被称为可写层。 本地写入也可以使用一个可写文件系统来实现,该文件系统使用容器镜像的完整克隆来初始化; 这种方式适用于某些基于 Hypervisor 虚拟化的运行时。
容器运行时文件系统包含只读层和可写层。在 Kubernetes 文档中,这一文件系统被称为 imagefs
。
容器运行时配置
CRI-O
CRI-O 使用 TOML 格式的存储配置文件,让你控制容器运行时如何存储持久数据和临时数据。
CRI-O 使用了 containers-storage 库。
某些 Linux 发行版为 containers-storage 提供了帮助手册条目(man 5 containers-storage.conf
)。
存储的主要配置位于 /etc/containers/storage.conf
中,你可以控制临时数据和根目录的位置。
根目录是 CRI-O 存储持久数据的位置。
[storage]
1. 默认存储驱动
driver = "overlay"
1. 临时存储位置
runroot = "/var/run/containers/storage"
1. 容器存储的主要读/写位置
graphroot = "/var/lib/containers/storage"
graphroot
- 存储来自容器运行时的持久数据
- 如果 SELinux 被启用,则此项必须是
/var/lib/containers/storage
runroot
- 容器的临时读/写访问
- 建议将其放在某个临时文件系统上