Docker容器无法停止或删除 - 权限被拒绝错误

Par*_*odi 35 ruby-on-rails docker docker-compose docker-swarm

问题:无法停止docker容器,每当我尝试停止容器时,我收到以下错误消息,

ERROR: for yattyadocker_web_1  cannot stop container: 1f04148910c5bac38983e6beb3f6da4c8be3f46ceeccdc8d7de0da9d2d76edd8: Cannot kill container 1f04148910c5bac38983e6beb3f6da4c8be3f46ceeccdc8d7de0da9d2d76edd8: rpc error: code = PermissionDenied desc = permission denied
Run Code Online (Sandbox Code Playgroud)

操作系统版本/版本: Ubuntu 16.04 | Docker版本17.09.0-ce,构建afdb6d4 | Docker Compose版本1.17.1,build 6d101fb

重现步骤:

  • 使用Dockerfile和docker-compose.yml创建了一个rails项目.docker-compose.yml是版本3.
  • 图像与成功构建要么docker build -t <project name> .docker-compose up --build
  • 容器启动并成功运行.
  • 尝试使用docker-compose停止docker compose.

我试过的:

  • 我必须跑sudo service docker restart,然后可以删除容器.
  • 卸载docker,删除docker目录,然后重新安装所有内容.仍面临同样的问题.

注意:此配置之前工作正常,但文件权限可能已更改,我看到此错误.我必须跑sudo service docker restart,然后可以删除容器.但这非常不方便,我不知道如何解决这个问题.

参考文件:

# docker-compose.yml
version: '3'
volumes:
  db-data:
    driver: local
  redis-data:
    driver: local  
services:
  db:
    image: postgres:9.4.1
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    env_file: local_envs.env
  web:
    image: yattya_docker:latest
    command: bundle exec puma -C config/puma.rb
    tty: true
    stdin_open: true
    ports:
      - "3000:3000"
    links:
      - db
      - redis
      - memcached
    depends_on:
      - db
      - redis
      - memcached
    env_file: local_envs.env
  redis:
    image: redis:3.2.4-alpine
    ports:
      # We'll bind our host's port 6379 to redis's port 6379, so we can use
      # Redis Desktop Manager (or other tools) with it:
      - 6379:6379
    volumes:
      # We'll mount the 'redis-data' volume into the location redis stores it's data:
      - redis-data:/var/lib/redis
    command: redis-server --appendonly yes
  memcached:
    image: memcached:1.5-alpine
    ports:
      - "11211:11211"
  clock:
    image: yattya_docker:latest
    command: bundle exec clockwork lib/clock.rb
    links:
      - db
    depends_on:
      - db
    env_file: local_envs.env
  worker:
    image: yattya_docker:latest
    command: bundle exec rake jobs:work
    links: 
      - db
    depends_on: 
      - db
    env_file: local_envs.env
Run Code Online (Sandbox Code Playgroud)

和Dockerfile:

# Dockerfile
FROM ruby:2.4.1

RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*

ENV APP_HOME /app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN bundle install

ADD . $APP_HOME

RUN mkdir -p ${APP_HOME}/log
RUN cat /dev/null > "$APP_HOME/log/development.log"

RUN mkdir -p ${APP_HOME}/tmp/cache \
    && mkdir -p ${APP_HOME}/tmp/pids \
    && mkdir -p ${APP_HOME}/tmp/sockets

EXPOSE 3000
Run Code Online (Sandbox Code Playgroud)

小智 93

对于任何不想完全清除AppArmor的人.

检查状态: sudo aa-status

关闭并阻止它重新启动: sudo systemctl disable apparmor.service --now

卸载AppArmor配置文件: sudo service apparmor teardown

检查状态: sudo aa-status

你现在应该能够停止/杀死容器了.

  • 注意!之后,某些应用将无法启动 (5认同)
  • 请注意,任何包含“apparmor”的解决方案都会破坏 snap 以及通过 snap 安装的所有软件包,甚至在这之后我在 kubernetes 上运行和杀死 pod 时仍然遇到问题。 (2认同)
  • 如果我没记错的话,我按照上面的解决方案中的描述禁用了 AppArmor,然后重新安装了 Docker,然后使用“sudo systemctlenabled apparmor”和“sudo systemctl start apparmor”重新启用了 AppArmor。 (2认同)

小智 51

我从snap软件包安装了Docker,过了一会儿我决定转向apt仓库安装。

我面临着同样的问题,使用sudo aa-remove-unknown它对我有用。

因此,无需重新安装Apparmor。

  • 这是正确的无核答案。将Docker安装为“快照”会添加大量AppArmor配置文件,这些配置文件与apt安装会冲突。这是我偶然发生的,因为我正在寻找一种安装所有Docker的便捷方法。最后选择了“ apt”安装,因为它可以给我更多控制权,并且是最新的。 (7认同)
  • 完美的答案! (6认同)

Par*_*odi 13

我能够解决这个问题.由于一些未知问题,ubuntu中的Apparmor服务无法正常工作.问题类似于moby项目https://github.com/moby/moby/issues/20554中报告的问题.

/etc/apparmor.d/tunables文件夹是空的,并且https://github.com/mlaventure建议清除/重新安装apparmor以使其进入初始状态.

所以我重新安装了apparmor,重启后问题解决了.

希望这可以帮助.


Oli*_*ndu 12

就我而言,问题是我的 docker 安装存在冲突:docker本身来自官方docker-ce,但docker-compose来自 Ubuntu snap 包。

docker-compose从官方 github正确安装(这里的说明)就成功了。我还遵循了Linux 安装后说明,它可能也有帮助(以非 root 用户身份运行 docker)

我只是把 AppArmor 单独留在这里 - 我没有碰它。

  • 有同样的问题。我看到Docker是通过snap:`snap list`安装的,并使用`sudo snap remove docker`先将其删除 (8认同)

Mor*_*itz 6

解决该问题的直接方法是在要杀死的容器中执行bash并直接在其中调用kill。一个例子:

host$ docker exec -it <container-name> sh
container$ ps
PID   USER     TIME  COMMAND
    1 root      0:00 {entrypoint.sh} /bin/sh /entrypoint.sh
   16 root      0:00 {entrypoint.sh} /bin/sh /entrypoint.sh
   24 root      0:00 sh
   31 root      0:00 ps
container$ kill 1
Run Code Online (Sandbox Code Playgroud)

要检查容器是否被杀死,请运行docker ps。这是重新安装apparmor的解决方案的有用替代方法,因为这也会删除snapd

  • 我可以确认这有效。我还相信这应该是公认的答案,因为这对您的主机系统没有任何风险。 (3认同)
  • 这不起作用,在我的情况下它只是列出 `sh` 和 `ps` 进程(来自 docker-compose 文件) (2认同)