译文:关于Docker数据容器(data only container)

开发 开发工具
数据容器就是本身只创建一个volume供其他容器共享,创建完后即退出,不执行任何任务。比如通过以下方式创建一个postgres容器。

[[186127]]

什么是数据容器?

数据容器就是本身只创建一个volume供其他容器共享,创建完后即退出,不执行任何任务。比如通过以下方式创建一个postgres容器。

  1. docker run --name dbdata postgres echo "Data-only container for postgres" 

该容器运行echo "Data-only container for postgres"即退出,然而只要没有删除该容器,该容器/var/lib/postgresql/data的volume(在Dockerfile使用VOLUME指令定义)就会一直存在。

然后我们可以新建若干容器来共享数据,比如:

  1. docker run -d --volumes-from dbdata --name db1 postgres 

如何创建数据容器?

太简单了,创建任何容器,然后使用-v创建volume即可。但大家一定会想到用最小的镜像吧,比如hello-world,即

  1. docker run -v /data hello-world 

但这样是错误的! 为什么呢?

我们首先创建一个简单的镜像:

  1. FROM debian:jessie 
  2. RUN useradd mickey 
  3. RUN mkdir /foo && touch /foo/bar && chown -R mickey:mickey /foo 
  4. USER mickey 
  5. CMD ls -lh /foo 

构建:

  1. docker build -t mickey_foo -< Dockerfile 

运行下:

  1. docker run --rm -v /foo mickey_foo 

输出:

  1. total 0  
  2. -rw-r--r-- 2 mickey mickey 0 Nov 18 05:58 bar 

运行正常,没有任何问题。

下面我们尝试使用busybox来作为数据容器:

  1. docker run -v /foo --name mickey_data busybox true 
  2. docker run --rm --volumes-from mickey_data mickey_foo 

输出:

  1. total 0  
  2. # Empty WTF?? 
  1. docker run --rm --volumes-from mickey_data mickey_foo ls -lh / 
  1. total 68K 
  2. drwxr-xr-x   2 root root 4.0K Nov 18 06:02 bin 
  3. drwxr-xr-x   2 root root 4.0K Oct  9 18:27 boot 
  4. drwxr-xr-x   5 root root  360 Nov 18 06:05 dev 
  5. drwxr-xr-x   1 root root 4.0K Nov 18 06:05 etc 
  6. drwxr-xr-x   2 root root 4.0K Nov 18 06:02 foo 
  7. drwxr-xr-x   2 root root 4.0K Oct  9 18:27 home 
  8. drwxr-xr-x   9 root root 4.0K Nov 18 06:02 lib 
  9. drwxr-xr-x   2 root root 4.0K Nov 18 06:02 lib64 
  10. drwxr-xr-x   2 root root 4.0K Nov  5 21:40 media 
  11. drwxr-xr-x   2 root root 4.0K Oct  9 18:27 mnt 
  12. drwxr-xr-x   2 root root 4.0K Nov  5 21:40 opt 
  13. dr-xr-xr-x 120 root root    0 Nov 18 06:05 proc 
  14. drwx------   2 root root 4.0K Nov 18 06:02 root 
  15. drwxr-xr-x   3 root root 4.0K Nov 18 06:02 run 
  16. drwxr-xr-x   2 root root 4.0K Nov 18 06:02 sbin 
  17. drwxr-xr-x   2 root root 4.0K Nov  5 21:40 srv 
  18. dr-xr-xr-x  13 root root    0 Nov 18 06:05 sys 
  19. drwxrwxrwt   2 root root 4.0K Nov  5 21:46 tmp 
  20. drwxr-xr-x  10 root root 4.0K Nov 18 06:02 usr 
  21. drwxr-xr-x  11 root root 4.0K Nov 18 06:02 var 

Owened by root? WTF???

  1. docker run --rm --volumes-from mickey_data mickey_foo touch /foo/ba 
  1. touch: cannot touch '/foo/bar': Permission denied 

发生了什么呢?我们的/foo 仍然存在, 但是它是空的并且所有者是root?

让我们再试试使用我们刚刚构建的mickey_foo作为数据容器:

  1. ~: docker rm -v mickey_data # remove the old one 
  2. mickey_data 
  3. ~: docker run --name mickey_data -v /foo mickey_foo true 
  4. ~: docker run --rm --volumes-from mickey_data mickey_foo 
  5. total 0 
  6. -rw-r--r-- 1 mickey mickey 0 Nov 18 05:58 bar 
  7. # Yes! 
  8. ~: docker run --rm --volumes-from mickey_data mickey_foo ls -lh / 
  9. total 68K 
  10. drwxr-xr-x   2 root   root   4.0K Nov 18 06:02 bin 
  11. drwxr-xr-x   2 root   root   4.0K Oct  9 18:27 boot 
  12. drwxr-xr-x   5 root   root    360 Nov 18 06:11 dev 
  13. drwxr-xr-x   1 root   root   4.0K Nov 18 06:11 etc 
  14. drwxr-xr-x   2 mickey mickey 4.0K Nov 18 06:10 foo 
  15. drwxr-xr-x   2 root   root   4.0K Oct  9 18:27 home 
  16. drwxr-xr-x   9 root   root   4.0K Nov 18 06:02 lib 
  17. drwxr-xr-x   2 root   root   4.0K Nov 18 06:02 lib64 
  18. drwxr-xr-x   2 root   root   4.0K Nov  5 21:40 media 
  19. drwxr-xr-x   2 root   root   4.0K Oct  9 18:27 mnt 
  20. drwxr-xr-x   2 root   root   4.0K Nov  5 21:40 opt 
  21. dr-xr-xr-x 121 root   root      0 Nov 18 06:11 proc 
  22. drwx------   2 root   root   4.0K Nov 18 06:02 root 
  23. drwxr-xr-x   3 root   root   4.0K Nov 18 06:02 run 
  24. drwxr-xr-x   2 root   root   4.0K Nov 18 06:02 sbin 
  25. drwxr-xr-x   2 root   root   4.0K Nov  5 21:40 srv 
  26. dr-xr-xr-x  13 root   root      0 Nov 18 06:05 sys 
  27. drwxrwxrwt   2 root   root   4.0K Nov  5 21:46 tmp 
  28. drwxr-xr-x  10 root   root   4.0K Nov 18 06:02 usr 
  29. drwxr-xr-x  11 root   root   4.0K Nov 18 06:02 var 
  30. # YES!! 
  31. ~: docker run --rm --volumes-from mickey_data mickey_foo touch /foo/baz 
  32. ~: docker run --rm --volumes-from mickey_data mickey_foo ls -lh /foo 
  33. total 0 
  34. -rw-r--r-- 1 mickey mickey 0 Nov 18 06:11 bar 
  35. -rw-r--r-- 1 mickey mickey 0 Nov 18 06:12 baz 
  36. # YES!!! 

由于我们刚刚使用了相同的镜像作为数据容器镜像,共享的容器能够找到共享数据。为什么使用busybox不可以呢?由于busybox没有/foo这个目录,当我们使用-v创建/foo这个数据卷时,docker会以默认用户自动创建对应的目录(这里是root),而--volumes-from仅仅是重用存在的卷,而不会对卷自动做任何事情。因此当我们尝试去写/foo时由于没有权限(root所有,mickey用户).

因此我们应该使用和共享的容器相同的镜像做数据容器镜像?是的!

那我们使用这么大的镜像不会浪费空间么?

为什么不使用小镜像作为数据容器?

其中一个原因,在上一节已经解释。遗留的一个问题是使用这么大的镜像(因为一般的镜像都会比较大)会不会浪费空间呢?

首先我们需要知道Docker的文件系统是如何工作的。Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。

因此当我们创建了一个debian容器实例时(大约150MB),根据以上的原理,我们再创建1000个debian镜像能够重用原来的只读层,需要的空间还是150MB.

容器本身并不会占任何空间,除非你修改了内容。

因此Docker无论创建一个镜像的多少实例,都不会占据更多的空间。

因此实际上,我们为了创建数据容器而使用busybox反而会占用更多的空间,这个空间就是busybox的镜像大小。

实际上我们经常这样使用:

  1. ~: docker run --name mydb-data --entrypoint /bin/echo mysql Data-only container for mydb 
  2. ~: docker run -d --name mydb --volumes-from mydb-data mysql 

上面的实例指行/bin/echo mysql Data-only container for mydb,能够更容易知道这是一个数据容器,利于使用grep查找.

【本文是51CTO专栏作者“付广平”的原创文章,如需转载请通过51CTO获得联系】

戳这里,看该作者更多好文

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2014-06-03 09:55:34

DockerLinux容器Ubuntu

2021-09-16 10:21:58

topic容器容器信息

2014-09-17 15:44:42

DockerContainer虚拟化

2014-09-16 10:34:59

Docker达龙云

2019-10-21 08:31:34

容器微服务docker

2014-11-11 15:25:00

Dockerambassador云计算

2014-09-18 14:13:54

Docker

2018-01-19 10:54:00

容器Kubernetes微服务

2014-12-23 13:33:35

Dockercontainerimage

2009-11-23 19:55:20

ibmdwDB2

2022-03-10 08:24:17

Docker容器SaaS

2019-07-08 08:59:41

Docker容器主机

2015-07-20 14:51:41

Container+联腾讯云

2009-02-20 17:46:34

计算机英语数据库管理系统简介

2019-12-10 08:00:46

Kata容器Linux

2020-08-11 08:59:20

容器虚拟化技术

2019-07-16 14:44:52

DockerMySQL操作系统

2022-07-25 14:24:53

Docker容器安全

2022-07-18 11:13:07

容器安全Docker

2018-11-22 10:47:36

Docker数据备份
点赞
收藏

51CTO技术栈公众号