如何删除docker中的目录?

use*_*963 6 ubuntu docker

似乎rm -rf在docker容器中只能处理文件.

docker run ubuntu /bin/bash -c 'sudo rm  -rf ./mydir; ls'
Run Code Online (Sandbox Code Playgroud)

它列出mydir目录而不打印任何错误.

我使用ubuntu 14.04作为主机和图像.

编辑:

我认为在我将另一个文件添加到目录后出现了错误,但我错了.最后,更改存储驱动程序有助于解决问题.

Pau*_*aul 7

当你似乎无法删除目录时,有两种可能:

  1. 用户在图像和容器之间的混淆.每个都docker run创建一个新容器,容器中的任何更改(如删除目录或运行修改文件系统的内容)都会与原始映像和所有其他容器隔离.
  2. Aufs分层错误/功能.查看docker info您是否正在使用存储驱动程序aufs或imagemapper.要重新安装docker以使用imagemapper:将任何不可替代的唯一映像备份到tar文件,删除docker.io,按照官方安装文档中的说明从ppa安装lxc-docker并更改/etc/default/docker为包含DOCKER_OPTS="--storage-driver=devicemapper"

它也可能是一个反模式来提交目录然后删除它们,因为那些数据可能仍然存在于某处.即使它从文件系统中消失,它仍然可能在内部浪费空间.

Docker镜像是按层构建的,每个提交都是一个层.
要查看此内容,请尝试docker history <image>查看图片中的内容.

第一种情况是值得一个简短的例子,但看起来你可能正在经历第二种情况.

图像与容器和删除目录

让我们创建一个名为mystufffrom 的私有图像ubuntu:14.04,稍后,尝试rm -rf/opt:

$ docker run -it ubuntu:14.04 /bin/bash
root@435e68479c5b:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@435e68479c5b:/# exit
$ docker commit 435e6 mystuff
Run Code Online (Sandbox Code Playgroud)

让我们看一下(-t这里仅用于在一行上进行漂亮打印):

docker run -t mystuff ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试删除/opt(通常这是可选的东西,可以安全删除):

docker run -t mystuff rm -rf /opt
Run Code Online (Sandbox Code Playgroud)

然后在里面寻找它,它仍然存在!(好像报道的问题):

docker run -t mystuff ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)

发生了什么?

  • 每次docker run mystuff使用时,它都会从图像中创建一个新容器mystuff
  • 除非您使用docker commit,否则不会提交对映像的更改

如果您查看容器,则会发生以下更改:

docker ps -a
... lots of stuff...
e9e8be13d928        mystuff:latest              "rm -rf /opt"          2 minutes ago        Exited (0) 2 minutes ago                                  nostalgic_archimedes    
Run Code Online (Sandbox Code Playgroud)

得到一个tarball并寻找选择,grep it for dir以opt开头,它不存在!:

docker export e9e8 | tar tv | grep ^opt
Run Code Online (Sandbox Code Playgroud)

注意: e9e8特别是我运行这个例子.要引用容器,可以使用docker ps第一个col中的部分十六进制字符串.

现在我将具有rm -rf更改的容器提交到新映像noopt:

docker commit e9e8 noopt
Run Code Online (Sandbox Code Playgroud)

并查看从noopt创建的容器:

docker run -t noopt ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)

果然,选择已经消失了!

但是因为docker图像是分层的,所以分发noopt会包含/ opt in一个早期的历史图像,所以你不能阻止其他人取回它:

docker history noopt
IMAGE               CREATED             CREATED BY                                      SIZE
bc4e69f9e871        59 minutes ago      rm -rf /opt                                     0 B
d198d23dab38        About an hour ago   /bin/bash                                       3 B
04c5d3b7b065        9 days ago          /bin/sh -c #(nop) CMD [/bin/bash]               0 B
d735006ad9c1        9 days ago          /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB
70c8faa62a44        9 days ago          /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
c7b7c6419568        9 days ago          /bin/sh -c #(nop) ADD file:d4aab24fc178303dc0   192.5 MB
511136ea3c5a        18 months ago                                                       0 B
Run Code Online (Sandbox Code Playgroud)

要在删除/ opt之前返回到图层,我们只需要选择d198d ...并运行它

docker run -t d198d23dab38 ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)

摘要:

  • Docker有容器和图像.
    • 图像旨在更持久.
    • 图像是在称为提交的层中创建的,在概念上类似于git存储库
    • 容器是根据图像创建的,容器中的更改不会保留在映像中(除非显式提交)

Docker还有一个很棒的构建系统,应该在这里使用.编写该脚本的人应该学习docker build并编写适当的Dockerfile