docker.sock权限被拒绝

164

当我尝试运行简单的Docker命令时,例如:

$ docker ps -a

我收到了一个错误信息:

权限被拒绝.../var/run/docker.sock: 连接:权限被拒绝

当我使用以下命令检查权限时:

$ ls -al /var/run/

我看到这行代码:

srw-rw---- root docker docker.sock

所以,我遵循许多论坛上的建议,并将本地用户添加到 docker 组中:
$ sudo usermod -aG docker $USER

但是这并没有帮助。我仍然收到完全相同的错误信息。我该如何解决?


7
你在做出修改后是否重新登录了?该修改在同一会话中不可用。sudo docker ps 命令是否可用? - Tarun Lalwani
我打开了一个新的终端,仍然收到这些错误信息。 - Jacobian
1
你必须重新启动Docker守护进程,否则它不会允许docker组的成员控制Docker守护进程。 - Murmel
但请记住,您基本上是将$USER赋予root权限,请参见:以非root用户身份管理Docker - Murmel
3
改变用户/组之后,您需要重新登录,而不仅仅是打开新终端。 - Sergius
显示剩余5条评论
12个回答

292

对于不熟悉shell的人,以下命令:

$ sudo usermod -aG docker $USER

在您的 shell 中需要定义 $USER 变量。通常情况下这个变量会被默认设置好,但有时候您可能需要将其设置为您的登录 ID。


更改用户所属群组并不会影响用户已经登录、打开的终端和 shell 等。为了避免重新登录,您可以简单地运行:

$ newgrp docker

要在当前的 shell 中获取访问该组的权限。


完成此操作后,用户在服务器上有效地拥有 root 访问权限,因此只能为可信赖且具备不受限制的 sudo 访问权限的用户执行此操作。


1
这对我没有用,但是我正在使用命名空间。我必须使用--userns=host - Mr00Anderson
我尝试了这个线程中的所有其他技巧,遵循了文档,重新安装了更新版本的Docker,重启了很多次,我想到的一切都试过了。我确实在docker组中,但默认shell不会承认它(也许是我的.profile文件中的脚本问题?)。除了使用sudo切换到root用户之外,只有newgrp命令起作用。 - Bruno Laturner
4
如果你正在使用Ubuntu系统,我听说LightDM可能会导致一个问题,即在登录用户时会丢失其次要的用户组。 - BMitch
3
@BMitch,你是不是在监视我的活动?那是我的确切配置和错误。谢谢!按照https://askubuntu.com/q/1057258/259660 解决了问题。 - Bruno Laturner
4
运行 newgrp docker 命令是激活组更改所必需的。 - Jay Modi
显示剩余2条评论

86

原因:该错误消息意味着当前用户无法访问docker引擎,因为用户没有足够的权限来访问UNIX套接字以与引擎通信。

快速解决:

  1. 使用sudo以root身份运行命令。

sudo docker ps
  • 更改 /var/run/docker.sock 文件的权限以适应当前用户。

  • sudo chown $USER /var/run/docker.sock
    

    注意:运行sudo chmod 777 /var/run/docker.sock会解决您的问题,但它会向所有人打开docker套接字,这是一个安全漏洞,正如@AaylaSecura所指出的那样。因此,除了在本地系统上进行测试目的之外,不应使用它。

    永久性解决方案:

    将当前用户添加到docker组中。

    sudo usermod -a -G docker $USER
    
    注意:更改生效前您必须注销并重新登录。

    参考此博客,了解如何以非root用户身份管理Docker。

    7
    你可能因为人们在注销后忘记回来给你点赞而错失一些选票。 - John Mee
    3
    我敢打赌他们错过了点赞,因为“快速修复”是一个安全灾难... Docker套接字永远不应该对世界开放... - Aayla Secura
    1
    @AaylaSecura 是的,你说得对。我之前添加了它作为一个快速解决方案,但这是一种不好的做法。我现在已经在答案中进行了更改。如果你认为可以改进,请随意评论。 - Nitish
    1
    这是对我有效的解决方案...谢谢!!! docker.sock文件的所有权属于root,因此无论如何注销都无法修复它。 - Carlos
    1
    我需要重新启动电脑,因为注销和登录似乎无法解决问题,我花了很多时间来排除故障。 - Zura Sekhniashvili

    44
  • 确保您的$USER变量已设置

  • $ echo $USER
    
    $ sudo usermod -aG docker $USER
    
  • 注销

  • 登录后,重新启动Docker服务

  • $ sudo systemctl restart docker
    
    $ docker ps
    

    7
    重启 Docker 守护进程是一件大事。每次将用户添加到 Docker 组后都会忘记做这件事 :\ - Parth Patel
    2
    不应该需要重新启动守护进程,因为它是root,并已经配置了套接字以运行为docker。我能想到的唯一解决方法是如果您修改了套接字权限。 - BMitch
    1
    添加组到操作系统环境后,Docker 服务重启解决了问题。谢谢! - Artfaith
    创建docker组后,我不得不重新启动守护进程。点赞这个答案。 - Ruzihm
    我实际上不得不重新启动电脑,真是麻烦。注销和登录没有帮助。newgrp可以工作,但在我的情况下重新登录或sudo systemctl restart docker无法解决问题。很奇怪,但如果有人想知道的话... - ElectRocnic

    13

    输入命令并在无需sudo命令的情况下探索docker

    sudo chmod 666 /var/run/docker.sock
    

    请记住,任何可以访问Docker套接字的人都可以轻松地控制整个主机;运行此命令允许任何本地进程执行该操作。 - David Maze
    很遗憾,一些操作系统会不断将此文件的权限更改回默认设置 :( - java.is.for.desktop

    4
    如前所述,更改将在重新登录后生效。如果您正在进行SSH并打开新的终端,则会在新终端中工作。
    但由于您使用了GUI并打开了新终端,因此未应用更改。这就是错误没有消失的原因。
    因此,下面的命令确实完成了其工作,只是错过了重新登录。
    sudo usermod -aG docker $USER
    

    4

    您需要以非root用户身份管理docker。 创建docker组并将您的用户添加到其中:

    1. 创建docker组。

      $ sudo groupadd docker

    2. 将您的用户添加到docker组中。

      $ sudo usermod -aG docker $USER

    3. 退出并重新登录,以重新评估您的组成员身份。

    如果在虚拟机上进行测试,则可能需要重新启动虚拟机才能使更改生效。

    在桌面Linux环境(如X Windows)中,请完全注销您的会话,然后重新登录。

    在Linux上,您还可以运行以下命令来激活对组的更改:

    $ newgrp docker

    1. 验证您是否可以无需sudo运行docker命令。

      $ docker run hello-world


    2

    关于这些答案的重要说明:docker组并不总是“docker”,有时它是“dockerroot”,例如在Centos 7安装中的情况。

    sudo yum install -y docker
    

    安装完Docker后,你应该做的第一件事是:
    sudo tail /etc/group
    

    它应该说出类似的话

    ......
    sshd:x:74:
    postdrop:x:90:
    postfix:x:89:
    yourusername:x:1000:yourusername
    cgred:x:996:
    dockerroot:x:995:
    

    在这种情况下,它是“dockerroot”,而不是“docker”。因此,
    sudo usermod -aG dockerroot yourusername
    logout
    

    这是适用于CentOS的正确答案。没有 docker 组。 - Brian Minton

    0

    由于我的用户是AD用户,我必须通过手动编辑/etc/group文件将AD用户添加到本地组中。不幸的是,adduser命令似乎不具备nsswitch感知能力,并且在将某人添加到组时无法识别未在本地定义的用户。

    然后重新启动或刷新/etc/group。现在,您可以在不使用sudo的情况下使用docker。

    此致敬礼。


    0
    当我尝试运行简单的docker命令时,例如:$ docker ps -a,我收到一个错误消息:Got permission denied ... /var/run/docker.sock: connect: permission denied。如何解决这个问题? TL;DR:有两种方法(第一种方法也在问题本身中提到,并且已经得到其他答案的广泛解决,但存在安全问题;因此,我将详细说明这个问题,并开发第二种解决方案,也适用于这个相当敏感的用例)。

    仅为回忆上下文,Docker 守护进程套接字的所有者是 root:docker

    $ ls -l /var/run/docker.sock
    srw-rw---- 1 root docker 0 janv. 28 14:23 /var/run/docker.sock
    

    因此,在这种默认设置下,需要在所有Docker CLI命令之前加上sudo

    为了避免这种情况,可以采取以下任一方法:

    1. 将用户账户($USER)添加到docker组中,但在个人工作站上这样做相当危险,因为这将使得所有由用户运行的程序都具有根权限,而无需任何sudo密码提示或审计

      另请参阅:

    2. 否则可以自动添加sudo而不手动输入sudo docker:为此,一种解决方案是~/.bashrc中添加以下别名(详见例如this thread):

      __docker() {
          if [[ "${BASH_SOURCE[*]}" =~ "bash-completion" ]]; then
              docker "$@"
          else
              sudo docker "$@"
          fi
      }
      alias docker=__docker
      

      然后可以通过打开新终端并键入以下内容来测试:

      docker run --pul〈TAB〉 # → docker run --pull
                             # 自动补全有效
      docker run --pull always --rm -it debian:11  # 请求密码
      \docker run --help  # 绕过别名(感谢\)并不需要密码
      

    @SridharSarnobat,我回滚了你的编辑,因为运行 sudo chmod a+rx /var/run/docker.sock 绝对不是我的答案摘要,也不是一个合适的解决方案... - ErikMD
    我不知道为什么会被踩:我真诚地认为,像我在答案中提出的那样添加一个简单的.bashrc别名比当前接受的解决方案更好,因为(1)从安全角度来看更安全(没有用户进程可以通过Docker的守护程序攻击面偷偷成为root),(2)它实现了相同的目标:我们只需在终端中编写docker run -it ubuntu或类似命令即可... - ErikMD

    0
    通过下面的命令,我能够在不使用sudo的情况下执行docker命令。
    ``` sudo setfacl -m user:$USER:rw /var/run/docker.sock ```

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