问题描述
我在Google Cloud中有一个存储桶文件夹,其中包含约StatefulSet
的数据。我在我的Google Cloud Kubernetes集群中启动了一个新的Kubernetes StatefulSet
。 gsutil -m rsync -r gs://<BUCKET_PATH> <LOCAL_MOUNT_PATH>
内的容器要做的第一件事是使用StatefulSet
将存储桶文件夹的内容同步到本地安装的文件夹,该文件夹与Kubernetes持久卷相对应。对此125Gi
的持久卷声明请求存储rsync
,并且仅用于此gsutil
。但是gsutil
同步最终碰到了pod耗尽了磁盘空间(持久卷中的空间)的墙壁,并且[Errno 28] No space left on device
引发了错误:47GB
。这很奇怪,因为我只需要从存储桶中复制125Gi
数据,但是持久卷应该具有kubectl get pvc
可用的存储空间。
我可以使用kubectl get pv
和df -h
确认“持久卷声明”和“持久卷”已设置了适当的大小。如果我在容器(kubectl exec -it <POD_NAME> -- df -h
)内运行125Gi
,则可以看到已安装的路径存在并且它具有预期的大小(df -h
)。在同步过程中使用No space left on device
时,我看到它确实占据了持久卷中的所有可用空间,直到它最终命中200Gi
。
此外,如果我提供了df -h
的持久卷并重试同步,则同步成功完成,并且47GB
显示持久卷中的已使用空间为gsutil rsync
,如预期的那样( gsutil rsync
完成之后。
所以看来gsutil rsync
在同步时使用的空间 比我期望的要多得多。为什么是这样?是否有一种方法可以更改{{1}}的完成方式,以使它不需要的持久卷比必要的大?
应该注意的是,有很多单独的文件,并且在同步过程中pod大约重新启动了8次。
解决方法
rsync
首先将内容传输到目标文件夹中的临时文件中。如果成功,则它将重命名该文件以成为目标文件。如果传输失败,该临时文件将被删除。根据{{3}},您可以尝试在命令中添加--inplace
标志:“此选项更改了rsync在需要更新数据时传输文件的方式:而不是创建新副本的默认方法并在完成后将其移动到位,rsync而是将更新的数据直接写入目标文件。”