一、Docker存储简介
- docker提供数据卷来实现数据共享与持久化,而数据卷的挂载有两种方式:
挂载主机目录(Bind mounts)
数据卷容器(Data Volumes)
- 数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性:
数据卷可以在容器之间共享和重用
数据卷是目录或者文件,而非没有格式化的磁盘(块设备)
对数据卷的修改会立马生效
对数据卷的更新不会影响镜像
卷会一直存在,直到没有容器使用
二、挂载主机目录
******(1)先删除所有容器 [root@docker ~]# docker stop $(docker ps -aq) ebedef7466a8 [root@docker ~]# docker rm $(docker ps -aq) ebedef7466a8 ******(2)创建一个数据卷 [root@docker ~]# docker run -it --name web -v /webapp nginx /bin/bash 选项说明: -d:将容器放入后台运行 -P:将容器中的端口暴露到宿主机的一个随机端口 -v:创建一个数据卷,这个数据卷会自动映射到宿主机的某个目录,一般在/var/lib/docker/volumes下 #在上边命令中-v 选项后边的目录是容器中的目录,此目录无需提前创建,这个-v的意思就是将本地的/var/lib/docker/volumes下的某个目录挂载到容器的/webapp,即便容器删除,/var/lib/docker/volumes下的数据也不会丢失(当没有指定挂载点,默认是这个路径) 复制一个终端 [root@docker ~]# cd /var/lib/docker/volumes/ [root@docker volumes]# ll 总用量 24 drwxr-xr-x 3 root root 19 7月 19 15:10 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a -rw------- 1 root root 32768 7月 19 15:10 metadata.db [root@docker volumes]# cd 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a/ [root@docker 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a]# ll 总用量 0 drwxr-xr-x 2 root root 6 7月 19 15:10 _data [root@docker 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a]# cd _data/ [root@docker _data]# ll 总用量 0 [root@docker _data]# echo "aaa" > aaa.txt #写一个文件 回到之前的终端 root@5b1a58d018ae:/# cd /webapp/ root@5b1a58d018ae:/webapp# ls -l total 4 -rw-r--r-- 1 root root 4 Jul 19 07:12 aaa.txt #发现多了一个文件 root@5b1a58d018ae:/webapp# exit exit [root@docker ~]# docker rm $(docker ps -aq) #删除创建的容器 5b1a58d018ae [root@docker ~]# docker run -it --name web -v /date:/webapp nginx /bin/bash #再次创建容器,这次指定宿主机的date目录挂载到容器的webapp目录 root@4e2392e4b24f:/# cd /webapp/ #先进入webapp目录查看 root@4e2392e4b24f:/webapp# ls -l #现在是没有任何文件的 total 0 切换到复制的终端 [root@docker ~]# mkdir /date mkdir: 无法创建目录"/date": 文件已存在 #只要指定了挂载目录就会自动创建 [root@docker ~]# cd /date/ [root@docker date]# echo "aaaaa" > aaaaa #写一个文件 回到开启容器的终端 root@4e2392e4b24f:/webapp# ls -l total 4 -rw-r--r-- 1 root root 6 Jul 19 07:30 aaaaa #发现多了一个文件
三、数据卷容器
其实就是容器挂容器,挂载主机目录是挂本地
root@4e2392e4b24f:/webapp# exit exit [root@docker ~]# docker rm $(docker ps -aq) 4e2392e4b24f [root@docker ~]# docker run -it -v /data:/data --name data nginx:latest /bin/bash #创建数据卷容器,挂载的目录是data。名称是data 复制一个终端 [root@docker ~]# docker run -it --volumes-from data --name db1 nginx:latest /bin/bash #--volumes-from指定数据卷容器为data,--volumes-from参数可以多次使用,从多个容器挂载多个数据卷 再复制一个终端 [root@docker ~]# docker run -it --volumes-from data --name db2 nginx:latest /bin/bash 回到创建容器的终端 root@3055e3e829da:/# cd /data/ #进入到挂载目录创建文件 root@3055e3e829da:/data# ls -l total 4 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa root@3055e3e829da:/data# echo "bbb" > bbb root@3055e3e829da:/data# ls -l total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb 去另外两个容器上进行验证 #第一台 root@0137efd1b9ba:/# cd /data/ root@0137efd1b9ba:/data# ls -l total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb #第二台 root@006b0ff06ccf:~# cd /data/ root@006b0ff06ccf:/data# ls -l total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb 可以再开启一个终端 [root@docker data]# docker volume ls #查看数据卷,因为有两台容器挂载了数据卷,所以这里有两个 DRIVER VOLUME NAME local 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a local b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 #如果删除了挂载数据卷的容器,数据卷中的数据并不会删除,如果想要删除数据卷,就需要把挂载数据卷的容器全部删除后再删除数据卷,数据卷挂载的目录直接就是挂载数据卷容器的目录,可以通过docker rm -v来直接删除挂载数据卷的容器 ******删除数据卷,删之前需要把容器停止 [root@docker data]# docker volume ls DRIVER VOLUME NAME local 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a local b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 [root@docker data]# docker volume rm 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a [root@docker data]# docker volume rm b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 [root@docker data]# docker volume ls DRIVER VOLUME NAME [root@docker data]# docker ps -a #查看所有容器发现只有数据卷被删除了 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 006b0ff06ccf nginx:latest "/docker-entrypoint.…" 15 minutes ago Exited (0) 6 minutes ago db2 0137efd1b9ba nginx:latest "/docker-entrypoint.…" 15 minutes ago Exited (0) 6 minutes ago db1
(1)备份数据
[root@docker data]# docker rm $(docker ps -a) #删除所有容器 [root@docker ~]# docker run -it -v /data:/data --name data nginx:latest /bin/bash #创建一个data数据卷 root@45842a67190f:/# cd /data/ root@45842a67190f:/data# ls -l #保证data目录有文件 total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb 复制一个终端创建一个容器 [root@docker ~]# docker run -it --volumes-from data -v /backup:/backup --name worker nginx /bin/bash root@6511739bdfe3:/# tar zcf /backup/backup.tar.gz /data/ #把data目录的内容压缩到backup目录中 tar: Removing leading `/' from member names 复制一个终端 [root@docker ~]# cd /backup/ #进入backup目录 [root@docker backup]# ll 总用量 4 -rw-r--r-- 1 root root 174 7月 19 18:30 backup.tar.gz [root@docker backup]# tar xf backup.tar.gz #解压 [root@docker backup]# ll 总用量 4 -rw-r--r-- 1 root root 174 7月 19 18:30 backup.tar.gz drwxr-xr-x 2 root root 29 7月 19 17:06 data [root@docker backup]# cd data/ [root@docker data]# ll #发现是data目录中的内容 总用量 8 -rw-r--r-- 1 root root 6 7月 19 16:02 aaaa -rw-r--r-- 1 root root 4 7月 19 17:06 bbb #这类似于层层挂载,data作为数据卷容器,worker挂载data,同时也挂载了backup到本地目录,进入worker把data数据卷容器的数据进行压缩,压缩到worker自己挂载的backup目录下,实现了把数据卷容器的数据备份到了本地真实机器上
(2)还原数据
复制一个终端创建一个新的数据卷容器,把上面的data的数据还原到这个新的数据卷容器中 [root@docker ~]# docker run -it -v /data --name data2 nginx /bin/bash root@3d9ad5566541:/# 在复制一个终端创建一个新容器 [root@docker ~]# docker run -it --volumes-from data2 -v /backup:/backup --name worker2 nginx /bin/bash root@c7f64deae85f:/# cd /backup/ root@c7f64deae85f:/backup# ls -l total 4 -rw-r--r-- 1 root root 174 Jul 19 10:30 backup.tar.gz root@c7f64deae85f:/backup# tar xf backup.tar.gz -C /data #解压到data目录 root@c7f64deae85f:/backup# cd /data root@c7f64deae85f:/data# ls -l total 0 drwxr-xr-x 2 root root 29 Jul 19 09:06 data root@c7f64deae85f:/data# cd data root@c7f64deae85f:/data/data# ls -l total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb 切换到新的数据卷容器的终端查看 root@3d9ad5566541:/# cd /data/ root@3d9ad5566541:/data# ls -l total 0 drwxr-xr-x 2 root root 29 Jul 19 09:06 data root@3d9ad5566541:/data# cd data/ root@3d9ad5566541:/data/data# ls -l total 8 -rw-r--r-- 1 root root 6 Jul 19 08:02 aaaa -rw-r--r-- 1 root root 4 Jul 19 09:06 bbb #还原和备份是一个道理,不过是把本地的数据解压到了目标容器上
(3)删除数据卷
#如果删除了挂载数据卷的容器,数据卷中的数据并不会删除,如果想要删除数据卷,就需要把挂载数据卷的容器全部删除后再删除数据卷,数据卷挂载的目录直接就是挂载数据卷容器的目录,可以通过docker rm -v来直接删除挂载数据卷的容器 ******删除数据卷,删之前需要把挂载数据卷的容器删除后才可以删除数据卷 [root@docker data]# docker volume ls DRIVER VOLUME NAME local 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a local b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 [root@docker data]# docker volume rm 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a 0cf0dfb4ade215d237fb76c2f10aa7b1b15097db899697add48dfeb828e3969a [root@docker data]# docker volume rm b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 b0f11d2fe3e68b5c20688a25a5b01eb16f765c33e636b2b2f251b31140dbbd91 [root@docker data]# docker volume ls DRIVER VOLUME NAME [root@docker data]# docker ps -a #查看所有容器发现只有数据卷被删除了 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 006b0ff06ccf nginx:latest "/docker-entrypoint.…" 15 minutes ago Exited (0) 6 minutes ago db2 0137efd1b9ba nginx:latest "/docker-entrypoint.…" 15 minutes ago Exited (0) 6 minutes ago db1 ******查看没有容器挂载的数据卷 [root@docker ~]# docker volume ls -f dangling=true #在删除数据卷时,如果这个数据有挂载的容器,那么是无法直接删除的,当删除了提示的容器后,这个时候数据卷是没有挂载任何容器的,使用这条命令就可以查看 ******删掉容器的同时删除容器挂载的数据卷 [root@docker ~]# docker rm -v container_name #当删除容器时删除挂载的数据卷有其他容器在挂载时,是无法正常删除数据卷的 [root@docker ~]# docker volume ls #查看本机上现有的数据盘 DRIVER VOLUME NAME local 6bddc148311a4b1f87cfbb6c5c3a364a7ce197a6f6c81fdfb5305a475e7a2bd2 [root@docker ~]# docker volume rm 6bddc148311a4b1f87cfbb6c5c3a364a7ce197a6f6c81fdfb5305a475e7a2bd2 #删除数据盘 Error response from daemon: remove 6bddc148311a4b1f87cfbb6c5c3a364a7ce197a6f6c81fdfb5305a475e7a2bd2: volume is in use - [3d9ad5566541f19bd384611b041ba84ee20dd05650b2c49a6680fde246e17cbf, 81f2748bdf35ee5f1866312389ceba0070823b16b7c7cbfa96f04e5f08dc5947, c7f64deae85f9dbde1a8964b6b8e895c8e350140469e7f249caab5133202cbb6] #这里提示需要先删除这三个容器才行 [root@docker ~]# docker rm 3d9ad5566541f19bd384611b041ba84ee20dd05650b2c49a6680fde246e17cbf 3d9ad5566541f19bd384611b041ba84ee20dd05650b2c49a6680fde246e17cbf [root@docker ~]# docker rm 81f2748bdf35ee5f1866312389ceba0070823b16b7c7cbfa96f04e5f08dc5947 81f2748bdf35ee5f1866312389ceba0070823b16b7c7cbfa96f04e5f08dc5947 [root@docker ~]# docker rm c7f64deae85f9dbde1a8964b6b8e895c8e350140469e7f249caab5133202cbb6 c7f64deae85f9dbde1a8964b6b8e895c8e350140469e7f249caab5133202cbb6 [root@docker ~]# docker volume rm 6bddc148311a4b1f87cfbb6c5c3a364a7ce197a6f6c81fdfb5305a475e7a2bd2 #最后删除数据盘就可以正常删除了 6bddc148311a4b1f87cfbb6c5c3a364a7ce197a6f6c81fdfb5305a475e7a2bd2 [root@docker ~]# docker volume ls DRIVER VOLUME NAME
四、挂载主机目录示例
利用挂载主机修改web容器的页面
(1)创建一个挂载的容器
[root@docker ~]# docker run -d -p 80:80 -v /date:/usr/share/nginx/html nginx:latest #nginx容器网页默认路径为/usr/share/nginx/html 9e03fd2558a8ab9d1acb8e2e331b659f7470783799d872633e09d5164e67efc3 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9e03fd2558a8 nginx:latest "/docker-entrypoint.…" 13 seconds ago Up 12 seconds 0.0.0.0:80->80/tcp wonderful_kapitsa
测试
(2)在真实机写入数据
[root@docker ~]# echo "Hello Docker" > /date/index.html
[root@docker ~]# echo "<h1>aaaaaaaaaa</h1>" > /date/index.html
(2)在真实机写入数据
[root@docker ~]# echo "Hello Docker" > /date/index.html
[root@docker ~]# echo "<h1>aaaaaaaaaa</h1>" > /date/index.html