各种 Docker 容器路径已开始因 Linux Mint 上的权限错误而失败

Various Docker container paths have started failing with permission errors on Linux Mint

我正在 Linux Mint Docker 主机上开发 Node 多容器应用程序,通过 Snapcraft 安装了 Docker 和 Docker Compose。有四个容器,其中两个具有针对主机上项目文件夹的绑定挂载卷。这些都是非常标准的东西。

几天前,一些容器开始因权限错误而失败。这是我的 Docker Compose 命令,以及来自失败容器的日志:

  $ docker-compose -f docker-compose.yml -f docker-compose-dev.yml  up --no-build
  Creating network "frontend_default" with the default driver
  Creating frontend_mysql_1         ... done
  Creating frontend_reverse-proxy_1 ... done
  Creating frontend_api_1           ... done
  Creating frontend_frontend_1      ... done
  Attaching to frontend_reverse-proxy_1, frontend_mysql_1, frontend_api_1, frontend_frontend_1
  api_1            | npm ERR! code EACCES
  api_1            | npm ERR! syscall open
  api_1            | npm ERR! path /root/.config/configstore/update-notifier-npm.json
  api_1            | npm ERR! errno -13
  api_1            | npm ERR! Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'
  api_1            | npm ERR! You don't have access to this file.
  api_1            | npm ERR! 
  api_1            | npm ERR!     at Object.openSync (fs.js:440:3)
  api_1            | npm ERR!     at Object.readFileSync (fs.js:342:35)
  api_1            | npm ERR!     at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)
  api_1            | npm ERR!     at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)
  api_1            | npm ERR!     at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)
  api_1            | npm ERR!     at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)
  api_1            | npm ERR!     at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)
  api_1            | npm ERR!     at processTicksAndRejections (internal/process/task_queues.js:76:11)
  api_1            | npm ERR!  Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'
  api_1            | npm ERR! You don't have access to this file.
  api_1            | npm ERR! 
  api_1            | npm ERR!     at Object.openSync (fs.js:440:3)
  api_1            | npm ERR!     at Object.readFileSync (fs.js:342:35)
  api_1            | npm ERR!     at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)
  api_1            | npm ERR!     at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)
  api_1            | npm ERR!     at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)
  api_1            | npm ERR!     at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)
  api_1            | npm ERR!     at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)
  api_1            | npm ERR!     at processTicksAndRejections (internal/process/task_queues.js:76:11) {
  api_1            | npm ERR!   stack: "Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'\n" +
  api_1            | npm ERR!     "You don't have access to this file.\n" +
  api_1            | npm ERR!     '\n' +
  api_1            | npm ERR!     '    at Object.openSync (fs.js:440:3)\n' +
  api_1            | npm ERR!     '    at Object.readFileSync (fs.js:342:35)\n' +
  api_1            | npm ERR!     '    at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)\n' +
  api_1            | npm ERR!     '    at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)\n' +
  api_1            | npm ERR!     '    at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)\n' +
  api_1            | npm ERR!     '    at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)\n' +
  api_1            | npm ERR!     '    at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)\n' +
  api_1            | npm ERR!     '    at processTicksAndRejections (internal/process/task_queues.js:76:11)',
  api_1            | npm ERR!   errno: -13,
  api_1            | npm ERR!   syscall: 'open',
  api_1            | npm ERR!   code: 'EACCES',
  api_1            | npm ERR!   path: '/root/.config/configstore/update-notifier-npm.json'
  api_1            | npm ERR! }
  api_1            | npm ERR! 
  api_1            | npm ERR! The operation was rejected by your operating system.
  api_1            | npm ERR! It is likely you do not have the permissions to access this file as the current user
  api_1            | npm ERR! 
  api_1            | npm ERR! If you believe this might be a permissions issue, please double-check the
  api_1            | npm ERR! permissions of the file and its containing directories, or try running
  api_1            | npm ERR! the command again as root/Administrator.
  api_1            | 
  api_1            | npm ERR! A complete log of this run can be found in:
  api_1            | npm ERR!     /root/.npm/_logs/2020-05-26T12_31_11_538Z-debug.log
  api_1            | mysql_1          | /bin/bash: /usr/local/bin/docker-entrypoint.sh: Permission denied
  reverse-proxy_1  | /bin/sh: can't open '/entrypoint.sh': Permission denied
  frontend_reverse-proxy_1 exited with code 2
  frontend_1       | npm ERR! code EACCES
  frontend_1       | npm ERR! syscall open
  frontend_1       | npm ERR! path /root/.config/configstore/update-notifier-npm.json
  frontend_1       | npm ERR! errno -13
  frontend_1       | npm ERR! Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'
  frontend_1       | npm ERR! You don't have access to this file.
  frontend_1       | npm ERR! 
  frontend_1       | npm ERR!     at Object.openSync (fs.js:440:3)
  frontend_1       | npm ERR!     at Object.readFileSync (fs.js:342:35)
  frontend_1       | npm ERR!     at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)
  frontend_1       | npm ERR!     at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)
  frontend_1       | npm ERR!     at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)
  frontend_1       | npm ERR!     at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)
  frontend_1       | npm ERR!     at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)
  frontend_1       | npm ERR!     at processTicksAndRejections (internal/process/task_queues.js:76:11)
  frontend_1       | npm ERR!  Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'
  frontend_1       | npm ERR! You don't have access to this file.
  frontend_1       | npm ERR! 
  frontend_1       | npm ERR!     at Object.openSync (fs.js:440:3)
  frontend_1       | npm ERR!     at Object.readFileSync (fs.js:342:35)
  frontend_1       | npm ERR!     at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)
  frontend_1       | npm ERR!     at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)
  frontend_1       | npm ERR!     at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)
  frontend_1       | npm ERR!     at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)
  frontend_1       | npm ERR!     at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)
  frontend_1       | npm ERR!     at processTicksAndRejections (internal/process/task_queues.js:76:11) {
  frontend_1       | npm ERR!   stack: "Error: EACCES: permission denied, open '/root/.config/configstore/update-notifier-npm.json'\n" +
  frontend_1       | npm ERR!     "You don't have access to this file.\n" +
  frontend_1       | npm ERR!     '\n' +
  frontend_1       | npm ERR!     '    at Object.openSync (fs.js:440:3)\n' +
  frontend_1       | npm ERR!     '    at Object.readFileSync (fs.js:342:35)\n' +
  frontend_1       | npm ERR!     '    at Configstore.get all [as all] (/usr/lib/node_modules/npm/node_modules/configstore/index.js:30:25)\n' +
  frontend_1       | npm ERR!     '    at Configstore.get (/usr/lib/node_modules/npm/node_modules/configstore/index.js:74:27)\n' +
  frontend_1       | npm ERR!     '    at UpdateNotifier.check (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:78:16)\n' +
  frontend_1       | npm ERR!     '    at module.exports (/usr/lib/node_modules/npm/node_modules/update-notifier/index.js:151:17)\n' +
  frontend_1       | npm ERR!     '    at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/bin/npm-cli.js:85:48)\n' +
  frontend_1       | npm ERR!     '    at processTicksAndRejections (internal/process/task_queues.js:76:11)',
  frontend_1       | npm ERR!   errno: -13,
  frontend_1       | npm ERR!   syscall: 'open',
  frontend_1       | npm ERR!   code: 'EACCES',
  frontend_1       | npm ERR!   path: '/root/.config/configstore/update-notifier-npm.json'
  frontend_1       | npm ERR! }
  frontend_1       | npm ERR! 
  frontend_1       | npm ERR! The operation was rejected by your operating system.
  frontend_1       | npm ERR! It is likely you do not have the permissions to access this file as the current user
  frontend_1       | npm ERR! 
  frontend_1       | npm ERR! If you believe this might be a permissions issue, please double-check the
  frontend_1       | npm ERR! permissions of the file and its containing directories, or try running
  frontend_1       | npm ERR! the command again as root/Administrator.
  frontend_1       | 
  frontend_1       | npm ERR! A complete log of this run can be found in:
  frontend_1       | npm ERR!     /root/.npm/_logs/2020-05-26T12_31_12_821Z-debug.log
  frontend_1       | frontend_mysql_1 exited with code 126

我不确定是什么原因导致的,因为开发机器上没有发生重大变化。我四处寻找,发现 AppArmor 开始出现故障。这是主机上 dmesg 的一些日志:

May 26 13:31:15 dev-VirtualBox kernel: [  136.787188] audit: type=1400 audit(1590496275.941:68): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-nodemon.json" pid=6516 comm="node" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:16 dev-VirtualBox kernel: [  137.403740] audit: type=1400 audit(1590496276.557:69): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-npm.json" pid=6252 comm="npm" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:17 dev-VirtualBox kernel: [  137.959766] audit: type=1400 audit(1590496277.113:70): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-nodemon.json" pid=6683 comm="node" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:17 dev-VirtualBox kernel: [  138.388630] audit: type=1400 audit(1590496277.541:71): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=6561 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:19 dev-VirtualBox kernel: [  140.765452] audit: type=1400 audit(1590496279.917:72): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-npm.json" pid=6861 comm="npm" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:20 dev-VirtualBox kernel: [  140.975698] audit: type=1400 audit(1590496280.129:73): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-npm.json" pid=6942 comm="npm" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:20 dev-VirtualBox kernel: [  140.996244] audit: type=1400 audit(1590496280.149:74): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=7082 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:20 dev-VirtualBox kernel: [  141.399142] audit: type=1400 audit(1590496280.553:75): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-nodemon.json" pid=7162 comm="node" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:20 dev-VirtualBox kernel: [  141.521377] audit: type=1400 audit(1590496280.673:76): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/root/.config/configstore/update-notifier-nodemon.json" pid=7185 comm="node" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:24 dev-VirtualBox kernel: [  145.403602] audit: type=1400 audit(1590496284.557:77): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=7312 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:32 dev-VirtualBox kernel: [  153.298729] audit: type=1400 audit(1590496292.453:78): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=7452 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:31:46 dev-VirtualBox kernel: [  166.995319] audit: type=1400 audit(1590496306.149:79): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=7610 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:32:12 dev-VirtualBox kernel: [  193.228513] audit: type=1400 audit(1590496332.381:80): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/usr/local/bin/docker-entrypoint.sh" pid=7788 comm="docker-entrypoi" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
May 26 13:32:55 dev-VirtualBox kernel: [  236.569562] audit: type=1400 audit(1590496375.721:81): apparmor="DENIED" operation="open" profile="snap.docker.compose" name="/proc/7907/mounts" pid=7907 comm="python3" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000

看来是 AppArmor 的问题。 AppArmor 可能有系统更新,但据我所知,我并没有具体更改它。我该怎么做才能恢复正常的 Docker 操作?

这个问题很难找到,因为似乎没有太多关于它的信息。我的感觉是它只影响 Snap 中的 Docker,而不影响以其他方式安装的 Docker。问题已讨论 in this forum thread.

这个问题源于一个有问题的内核,在我的例子中 5.3.0-53,回到以前安装的版本解决了这个问题。对我来说就是 5.3.0-51This bug report 表示问题也出现在 5.4.0-31 中,可以通过返回 5.4.0-29 来解决。这解释了问题是如何独立出现的——通过系统更新提供了一个新内核。

我用 this answer 修改了 Grub,因此它可以引导到较旧的内核。以下是遇到相同问题的读者可以采取的步骤:

列出您当前的内核,这样您就可以识别以前安装的内核:

dpkg -l linux-{image,headers}-"[0-9]*" | awk '/ii/{print }'

确认哪个内核有问题:

uname -r

您需要更改 /etc/default/grub 中的启动选项,特别是一个名为 GRUB_DEFAULT 的值。这通常是 0 表示 "boot latest kernel":

GRUB_DEFAULT=0

您需要更改它以使其指向特定的内核。因此,我的价值是:

GRUB_DEFAULT="Advanced options for Linux Mint 19.3 Cinnamon>Linux Mint 19.3 Cinnamon, with Linux 5.3.0-51-generic"

这些是菜单字符串,我们要求 Grub 为我们自动 select。要发现您的元素是什么,请查看 /boot/grub/grub.cfg,然后搜索关键字 submenu 以找到顶级元素,即本例中的 "Advanced options for Linux Mint 19.3 Cinnamon"。从那时起,搜索 menuentry 以找到二级元素,在本例中为 "Linux Mint 19.3 Cinnamon, with Linux 5.3.0-51-generic"。有很多子菜单-你需要内核倒数第二个版本的版本。

将这两个字符串加在一起,在它们之间放一个 >,用引号将它们括起来,然后将其用作您的 GRUB_DEFAULT 值。根据我之前链接到的有用答案,在重新启动之前备份您的 Grub 文件是明智的,以防出现问题:

sudo cp /etc/default/grub /etc/default/grub.bak

最后,您应该在更改后重新生成 Grub 菜单:

sudo update-grub

重新启动后,您应该会发现 Docker 恢复正常。希望发布新内核,届时需要手动切换 Grub 以跟踪最新版本(假设将在下一个 Linux 版本中修复)。