Docker Apache:'chmod:“file”的权限更改不允许操作'

3
我在 Azure Kubernetes 上使用 Docker 部署了一个 Laravel 应用程序。当我尝试上传文件时,我的应用程序出现了问题,并显示以下 Laravel 错误(仅显示部分堆栈跟踪):

chmod(): 拒绝操作{"userId":1,"exception":"[object] (ErrorException(code: 0): chmod(): Operation not permitted at /var/www/my-app/vendor/league/flysystem/src/Adapter/Local.php:367) [stacktrace]

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'chmod(): Operat...', '/var/www/my-app...', 367, Array)

#1 /var/www/my-app/vendor/league/flysystem/src/Adapter/Local.php(367): chmod('/var/www/my-app...', 420)

然而,在我的 Dockerfile 中,我已经对存储文件夹进行了 "chowned" 的操作:
RUN chown -R www-data:www-data \
    /var/www/my-app/storage \
    /var/www/my-app/bootstrap/cache

我应该提到的是,文件已上传但由于chmod异常而无法继续执行代码。
为了调试这个问题,我尝试使用kubectl exec进入pod中获取一个shell,它默认以root用户登录。我cd到上传的文件并尝试使用root身份更改权限,通过运行chmod 420 nameOfFile.ext实现,然后将其更改回权限777。然而,由于Laravel正在使用apache用户“www-data”,因此我运行su www-data -s /bin/bash,然后尝试运行chmod 420 nameOfFile.ext更改相同文件的权限,但是我收到以下错误:

chmod: changing permissions of "nameOfFile.ext" Operation not permitted

所以我开始怀疑chown中的'-R'是否只适用于直接是子文件或文件夹的文件和文件夹。因此,我切换回root用户,“chowned”文件直接存在的文件夹,然后切换回www-data用户并尝试在文件上运行chmod,但仍然收到相同的错误。
[编辑] 我还应该提到应用程序正在使用Azure文件服务作为持久卷。改为Blob服务是否有帮助?
[编辑] 这是我的完整Dockerfile:https://pastebin.com/zLSyfqK8 我已经在处理这个问题一段时间了,任何帮助都将不胜感激。如果您需要其他必要信息,请告诉我。
1个回答

4
我还应该提到,该应用程序使用Azure文件服务作为持久卷。问题在于,Azure Files提供了CIFS共享,在Linux下作为cifs挂载。CIFS共享不提供UNIX类型的文件权限和UNIX类型的uid / gid存储。在挂载CIFS共享时,Linux机器使用用户名/密码在CIFS服务器上进行身份验证。通过此挂载的每个访问实际上都将在CIFS服务器上使用此用户名,而不管哪个UNIX用户启动文件系统操作。根据GitHub问题(此处省略链接),Azure Files不支持UNIX扩展,这意味着Linux客户端必须模拟UNIX uid / gid和权限。服务器不存储或提供这些参数。因此,在挂载时,您必须添加uid、gid、file_mode和dir_mode参数来设置这些数据。
如果您使用操作系统级别的CIFS挂载(通过/etc/fstab),或手动CLI挂载命令,则必须将这些选项添加到挂载命令中(请参见man mount.cifs)。
例如:mount -t cifs -o file_mode=0644,dir_mode=0755,uid=80,gid=80 ... 如果您正在使用Kubernetes卷,则必须将这些选项添加到卷参数中(请参见Azure Files share in Kubernetes)。
例如:
apiVersion: v1
kind: PersistentVolume
metadata:
  name: azurefile
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  storageClassName: azurefile
  azureFile:
    secretName: azure-secret
    shareName: aksshare
    readOnly: false
  mountOptions:
  - dir_mode=0755
  - file_mode=0644
  - uid=80
  - gid=80
  - mfsymlinks

实际上我已经设置了mountOptions。我设置了 dir_mode=0777file_mode=0777。而且在我的pod中,我检查了www-data用户的 uidgid33。我也有mfsymlinks。我还有nobrl,但我不确定这是否会引起问题。 - chinloyal
@chinloyal,你的Apache处理程序是prefork还是worker? Prefork处理程序可能会导致此错误,因为文件的所有者是“root”,而不是用户。 解决方案是(通过ssh控制台作为root):chown -R User:Group。 Apache用户是否被限制?您是否使用类似mod_ruid、cagefs等的东西,以便通过Apache、Cronjobs、SSH执行的任何脚本都受限于特定用户在特定路径/文件夹中? - Marius
@mariusfv,我不确定您所说的预分叉处理程序是什么意思。我已经创建了一个 Dockerfile 的 pastebin,您可以查看完整的配置。 - chinloyal
@chinloyal:找到您的私钥和公钥路径。 chmod 600 /var/www/.../.../oauth-private.key chmod 600 /var/www/.../.../oauth-public.key 重新启动Apache。尝试再次进行chmod。 - Marius
@mariusfv 这些文件会在我的项目文件夹里吗?因为我没有看到它们。 - chinloyal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接