天天看点

Docker 数据共享

Docker 数据共享
数据共享是volume的关键特性,我们将详细讨论通过volume如何在容器与host之间,容器与容器之间共享数据

1.容器与host共享数据
有两种类型的data volume 它们均可实现容器与host之间共享数据,但方式有别
对于bind mount 是非常明确:直接将要共享的目录mount到容器(具体参考之前讲的httpd的例子)
docker managed volume就要麻烦点,由于volume位于host中的目录,是在容器中启动才生成的,所以需要将共享数据复制到volumezhong

[[email protected] htdocs]# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
f5d23c7fed46: Pull complete 
b083c5fd185b: Pull complete 
bf5100a89e78: Pull complete 
98f47fcaa52f: Pull complete 
622a9dd8cfed: Pull complete 
Digest: sha256:dc4c86bc90593c6e4c5b06872a7a363fc7d4eec99c5d6bfac881f7371adcb2c4
Status: Downloaded newer image for httpd:latest
70f0c75396a90971d2da44ab2d1f22392ea105f99f5ed01aa78c720572fd2b40
[[email protected] htdocs]# curl 127.0.0.1:80
<html><body><h1>It works!</h1></body></html>
[[email protected] htdocs]# vim /mnt/index.html
[[email protected] htdocs]# docker ps 
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
70f0c75396a9        httpd               "httpd-foreground"   3 minutes ago       Up 3 minutes        0.0.0.0:80->80/tcp   quirky_northcutt
[[email protected] htdocs]# docker cp /mnt/index.html 70f0c75396a9:/usr/local/apache2/htdocs/
[[email protected] htdocs]# curl 127.0.0.1:80
redhat7 index page!

#docker cp 可以在容器和host之间复制数据,当然我们也可以直接通过linux的cp命令将数据复制到/var/lib/docker/volumes/xxx


2.容器之间共享数据
第一种方法是将共享数据放在bind mount中,然后将其mount到多个容器 还是以httpd为例,不过这次的场景更加复杂一些,我们要创建由三个httpd容器组成的web server集群 它们使用相同的html文件

[[email protected] htdocs]# docker run --name web1 -d -p 80 -v /root/htdocs:/usr/local/apache2/htdocs httpd
1c2db45e04786e4cb36e5ae66846c02e105ad76a5e4b0f4edf40c654d5266d5e
[[email protected] htdocs]# docker run --name web2 -d -p 80 -v /root/htdocs:/usr/local/apache2/htdocs httpd
8d33516133fbcb7e23bfa20f0a1204686cfdb2fa6fa245654df2dbf18e681e62
[root[email protected] htdocs]# docker run --name web3 -d -p 80 -v /root/htdocs:/usr/local/apache2/htdocs httpd
71b725630727522dbaf6eadd400bc15c7394045292a85c762a51bc44b6755f20
[[email protected] htdocs]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
71b725630727        httpd               "httpd-foreground"   5 seconds ago       Up 5 seconds        0.0.0.0:32770->80/tcp   web3
8d33516133fb        httpd               "httpd-foreground"   13 seconds ago      Up 12 seconds       0.0.0.0:32769->80/tcp   web2
1c2db45e0478        httpd               "httpd-foreground"   32 seconds ago      Up 31 seconds       0.0.0.0:32768->80/tcp   web1
[[email protected] htdocs]# curl 127.0.0.1:32770
hahahaha~
[[email protected] htdocs]# curl 127.0.0.1:32769
hahahaha~
[[email protected] htdocs]# curl 127.0.0.1:32768
hahahaha~
[[email protected] htdocs]# echo "This is a new hahaha" >/root/htdocs/index.html 
[[email protected] htdocs]# curl 127.0.0.1:32770This is a new hahaha
[[email protected] htdocs]# curl 127.0.0.1:32769This is a new hahaha
[[email protected] htdocs]# 


另一种在容器之间共享数据的方式是使用volume container

volume container是专门为其他容器提供volume的容器 它提供的卷可以是bind mount 也可以是docker managed volume 

创建一个volume container

# 我们将容器命名为vc_data 注意这里执行的是create命令 因为volume container 的作用只是提供数据 它本身不需要处于运行状态
[[email protected] htdocs]# docker create --name vc_data -v /root/htdocs:/usr/local/apache2/htdocs busybox
4f9e9b99f9908307a8a8db28a705f07061384081ed7ff113574644f9719f586f

# 其他容器可以通过--volumes-from使用vc_data这个volume container
[[email protected] htdocs]# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
5b7cd15d6a54e379f4be94bb3ae965626f4ace0edaf1b260aca8f56b7a844638
[[email protected] htdocs]# docker run --name web2 -d -p 80 --volumes-from vc_data httpd
e4cfd1091b8b82697c61195436a3ce5373484f584cf6f3561f250b450dfd922a
[[email protected] htdocs]# docker run --name web3 -d -p 80 --volumes-from vc_data httpd
2a193e9d32008457a7d2af65b482550ef45d751aa34d245b78338a855c764da
1

三个容器已经成功共享了 volume container 中volume
[[email protected] htdocs]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
2a193e9d3200        httpd               "httpd-foreground"   7 seconds ago       Up 6 seconds        0.0.0.0:32776->80/tcp   web3
e4cfd1091b8b        httpd               "httpd-foreground"   12 seconds ago      Up 12 seconds       0.0.0.0:32775->80/tcp   web2
5b7cd15d6a54        httpd               "httpd-foreground"   16 seconds ago      Up 16 seconds       0.0.0.0:32774->80/tcp   web1
[[email protected] htdocs]# echo "This content is from a volume container" >/root/htdocs/index.html 
[[email protected] htdocs]# curl 127.0.0.1:32776
This content is from a volume container
[[email protected] htdocs]# curl 127.0.0.1:32775
This content is from a volume container
[[email protected] htdocs]# curl 127.0.0.1:32774
This content is from a volume container

# 我们讨论以下volume container的特定
1.与bind mount 相比 不别为每一个容器指定host path 所有path都在volume container中定义好,容器只需要与volume container关联 实现了容器与host的解耦
2.使用volume container的容器,其mount point 是一致的,有利于配置的规范化 但也带来一定的局限 使用时需要综合考虑



data-packed volume container
上面的例子中 volume container的数据归根到底还是在host里,有没有办法将数据完全放到volume container中,同时又能与其他容器共享呢

当然可以,通常我们称这种容器为data-packed volume container 其原理是将数据打包到镜像中,然后通过docker managed volume共享


"""
小结
1.docker 为容器提供了两种存储资源:数据层和data volume
2.数据层包括镜像层和容器层,由storage driver管理
3.data volume有两种类型:bind mount 和docker managed volume
4.bind mount 可实现容器与host之间,容器与容器之间共享数据
5.volume container 是一种具有更好移植性的容器间数据共享方案,特别是volume container
"""