Git克隆报错权限拒绝,K8s+Posit Workbench环境下求排查思路
问题详情
执行git clone时触发权限错误,报错信息如下:
fatal: could not open '/home/myusername/reponame/.git/objects/pack/tmp_pack_uSnA9n' for reading: Permission denied fatal: fetch-pack: invalid index-pack output
且报错中提到的路径.git/objects/pack/tmp_pack_uSnA9n并未实际创建。
环境背景
- 在Posit Workbench(原RStudio)的在线VS Code实例中执行命令
- 目标仓库部署在Kubernetes上的Gitea服务中
- Posit Workbench的独立主目录由Longhorn提供持久化存储,Longhorn卷通过NFS4服务器管理(多用户场景)
已完成排查动作
重启所有服务、Posit官方技术支持确认配置无异常、用户具备文件/文件夹创建权限、NFS已启用no_root_squash、nfs-ganesha运行正常、Longhorn Share Manager日志无异常、Posit Pod的UID/GID与本地一致、securityContext的fsGroup配置正确、SElinux已禁用(epand-check=0)、Gitea Pod无报错。
进一步排查方向
1. 临时绕开NFS存储验证
在Posit Workbench Pod的本地临时目录(非NFS挂载路径,如/tmp)执行克隆操作:
cd /tmp git clone <你的Gitea仓库地址>
若克隆成功,说明问题聚焦在NFS存储层的读写时序或权限细节;若失败,再排查Git客户端或Gitea连接逻辑。
2. 跟踪Git克隆的系统调用
用strace捕获git clone的文件操作细节,重点关注权限相关调用:
strace -f -e trace=file git clone <你的Gitea仓库地址> > strace_log.txt 2>&1
查看strace_log.txt中涉及.git/objects/pack/路径的操作,确认是open调用失败,还是其他阶段的权限拦截(比如NFS的ACL限制)。
3. 检查NFS4的文件系统属性
在Posit Workbench中执行以下命令,确认挂载配置与目录权限:
# 查看NFS挂载选项 mount | grep /home/myusername # 检查目录ACL设置 getfacl /home/myusername/reponame/.git/objects/pack
确认挂载选项中是否存在noacl等限制权限的配置,以及目录ACL是否存在常规权限之外的拦截规则。
4. 模拟Git的临时文件读写逻辑
手动模拟Git克隆时的临时文件创建、写入、读取流程:
mkdir -p /home/myusername/test_pack cd /home/myusername/test_pack # 创建临时文件并写入内容 touch tmp_pack_test echo "test content" > tmp_pack_test # 读取临时文件 cat tmp_pack_test # 删除临时文件 rm tmp_pack_test
若上述操作失败,说明NFS存储的基础临时文件读写存在问题;若成功,再测试大文件读写(Git克隆会生成较大的pack文件):
dd if=/dev/zero of=/home/myusername/test_pack/large_tmp_file bs=1M count=100 cat large_tmp_file rm large_tmp_file
大文件操作失败可能指向NFS块大小、缓存策略或Longhorn存储层的性能问题。
5. 修改Git临时文件存储路径
Git克隆时会先创建临时pack文件再重命名为正式文件,可将临时目录切换到Pod本地路径:
git config --global core.tempdir /tmp/git_temp mkdir -p /tmp/git_temp chmod 700 /tmp/git_temp git clone <你的Gitea仓库地址>
若克隆成功,说明NFS存储对临时文件的重命名/读取存在时序兼容问题。
6. 检查Kubernetes存储挂载日志
查看Posit Workbench Pod的启动日志,确认NFS卷挂载是否有隐藏警告:
kubectl logs <你的Posit Pod名称> | grep -i nfs
同时测试Pod与NFS服务器的网络连通性,排查是否存在丢包或延迟:
ping <NFS服务器IP> -c 10
内容的提问来源于stack exchange,提问作者Dorian

