Ubuntu 16.04上使用Docker杀掉容器时出错

51

我无法杀死或停止任何Docker容器。我已允许非特权用户运行Docker命令。而docker run hello-world可以正常工作,但我无法停止任何其他容器。

我得到以下信息:

$ docker stop 59e3b815d1dc
Error response from daemon: cannot stop container: 59e3b815d1dc: 
Cannot kill container 59e3b815d1dcf2d8c8bcd3dd641c3c033b83ac68ea2f0257a32a76468af7374c: 
unknown error after kill: docker-runc did not terminate sucessfully: 
container_linux.go:393: signaling init process caused "permission denied"
: unknown

使用sudo时出现相同的错误。同时,所有容器都成功运行,但只有完全重新启动系统才能停止它们。

Docker compose示例: # 使用postgres/example用户/密码凭据 version:'3.1'

services:

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Docker信息:

$ docker info
Containers: 7
 Running: 2
 Paused: 0
 Stopped: 5
Images: 10
Server Version: 17.12.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 9b55aab90508bd389d7654c4baf173a981477d55
runc version: 9f9c96235cc97674e935002fc3d78361b696a69e
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.4.0-116-generic
Operating System: Ubuntu 16.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 11.61GiB
Name: peter-pen
ID: P6FS:C76H:WIAO:LCWC:TCHT:JEYB:6W3M:HXYD:S4E2:KTUZ:2T3Q:3GPI
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support

2
很可能是AppArmor的问题。也许您安装了Ubuntu Docker包,然后安装了Docker,导致配置文件混乱了? - Matt
有docker和docker-engine,但我已经清除了它们。这些软件包也出现了“权限被拒绝”的错误,因此我决定按照官方手册安装docker。 - Peter
@Matt 我稍后会查看AppArmor,谢谢你的指示。 - Peter
1
这是AppArmor。 - Peter
1
@Petr,你是如何解决AppArmor的问题的? - Michal Ciechan
@MichalCiechan 这不是更好的方法,但我为Docker禁用了AppArmor。 - Peter
7个回答

149

对我来说,从AppArmor中删除未知项是有效的:

sudo aa-remove-unknown

7
可以,这个命令确实有效!但我想知道它的魔力究竟在哪里? - Haroun Mohammedi
我在Windows NTFS上挂载了一个Docker服务,但无法停止。使用这个命令可以解决问题,但我仍然需要知道背后的原因。 - Brian Ng
这个链接讨论了关于这个的一些内容:https://docs.docker.com/engine/security/apparmor/ - jersey bean
2
我想了解“sudo aa-remove-unknown”背后的工作原理。是的,它解决了我的问题,但是它是如何做到的呢? - Ajay
2
这似乎搞乱了我安装的多个东西。小心。snap-confine具有提升的权限,但未受限制,应该被限制。为避免权限升级攻击而拒绝继续执行。 - Fishrock123
1
重启似乎解决了我的问题。 - Fishrock123

23

AppArmor(应用程序装甲)是一种Linux安全模块,可保护操作系统及其应用程序免受安全威胁。要使用它,系统管理员将一个AppArmor安全配置文件与每个程序关联。Docker希望找到已加载并执行的AppArmor策略。请使用以下命令检查默认配置文件:

# sudo apparmor_status

要在容器中使用 Docker 的默认配置文件,请运行:

$ docker run --rm -it --name test-container --security-opt apparmor=docker-default image-name

您可以使用以下命令禁用它:

--security-opt apparmor=unconfined
使用docker运行命令。
要禁用apparmor服务,请使用:
# systemctl stop apparmor && systemctl disable apparmor

对于Ubuntu 14,请使用:

# service apparmor stop
# update-rc.d -f apparmor remove

推荐为Docker应用程序设置工作配置文件,而不是禁用它,特别是对于生产环境。

查看此关于使用AppArmor保护容器的精彩Google文档。

https://cloud.google.com/container-optimized-os/docs/how-to/secure-apparmor


在构建镜像时,有没有特定的事情可以做以避免在运行容器时无法停止容器的问题?我之所以问这个问题是因为我注意到某些特定的镜像会导致这个问题,而在同一系统上的其他镜像则不会。 - Tlink

12

这个命令将停止所有的Docker容器。

sudo killall docker-containerd-shim

这个命令将会删除所有的 Docker 容器。

sudo docker-compose down

3
为什么原帖作者要这样做?请解释一下这些命令是做什么的,以及为什么它们可能有帮助。 - laruiss
1
我的脑袋炸了,非常感谢,它太棒了,运行得很好 :) - deeptimancode

7

在终端运行以下命令,所有正在运行的 Docker 容器将被停止:

sudo systemctl restart docker.service

2

按照以下步骤操作,以停止容器:

1. 禁用apparmor服务:

sudo systemctl disable apparmor.service --now

卸载AppArmor配置文件:

sudo service apparmor teardown

检查AppArmor状态:

sudo aa-status

现在您应该能够停止和终止容器了。

来源


1

可能是由Ubuntu的安全性问题引起的,特别是 apparmor。在这种情况下,您当然可以删除系统的安全性,但这似乎过于激烈。此外,似乎正在对Docker进行一些修补,很快就会解决所有问题。

同时,您可以在docker run命令中添加选项--security-opt apparmor:unconfined。这似乎比删除apparmor更可取。

例如,请尝试:

docker run --security-opt apparmor:unconfined -ti ubuntu bash

然后尝试执行docker stop,看看是否一切正常!

不幸的是,除非您重新启动,否则必须手动停止已经运行的 Docker 文件。有一个(极端的)选项可以通过运行以下命令来完成:

sudo killall -9 docker
sudo killall -9 dockerd

为了让事情变得更简单,“别名”docker...你需要确保参数传递到正确的位置,例如。
# in your ~/.bash_profile (~/.profile for ubuntu)
docker()
{
  if [ $# -gt 0 ] && [ "$1" == "run" ] ; then
     shift
     docker run --security-opt apparmor:unconfined "$@"
  else
     command docker "$@"
  fi
}

然后运行以下命令:~/.profile

0

使用以下命令后,我又可以使用docker-compose stop了:

sudo apt-get purge --auto-remove apparmor
sudo service docker restart
docker system prune --all --volumes

3
它会移除所有 snap 安装。 - Noa
这将会对您的系统造成严重后果。在您完全理解您要做什么之前,请不要尝试它。 - Denys Horobchenko

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