Torres-tao  

Docker数据管理

容器中的管理数据主要有两种方式:

  1. 数据卷(Data Volumes):容器内数据直接映射到本地主机环境
  2. 数据卷容器(Data Volume Containers):使用特定容器维护数据卷

数据卷

数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount行为。

数据卷可提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效和方便;
  • 对数据卷内的数据修改会立马生效,无论是容器内操作还是本地操作
  • 对数据卷的更新不会影响镜像,解耦开应用和数据
  • 卷会一直存在,直到没有容器使用,可以安全地卸载它

使用数据卷

docker run -it -v 主机目录:容器内目录

测试:

#主机目录下面没有ceshi目录
[root@aliyun home]# ll
总用量 12
drwxr-xr-x 2 root root 4096 4月  15 15:07 docker
drwxr-xr-x 3 root root 4096 4月   6 17:03 python
drwxr-xr-x 2 root root 4096 3月  25 15:46 shell
#将主机上的/home/ceshi目录挂载到容器内部的/home
[root@aliyun home]# docker run -it -v /home/ceshi:/home centos /bin/bash
#进入容器
[root@e4042f5dff6d /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#切换到容器内的/home目录
[root@e4042f5dff6d /]# cd /home/
#查看容器内/home目录下内容,空目录
[root@e4042f5dff6d home]# ls
#新建一个hello.txt文件
[root@e4042f5dff6d home]# vi hello.txt
#查看hello.txt文件内容
[root@e4042f5dff6d home]# cat hello.txt 
Hello World

#查看主机上/home/ceshi路径下的内容
[root@aliyun ~]# ls
interview  tools
[root@aliyun ~]# cd /home/ceshi/
[root@aliyun ceshi]# ll
总用量 4
-rw-r--r-- 1 root root 12 4月  19 09:11 hello.txt
[root@aliyun ceshi]# cat hello.txt 
Hello World

###发现容器内/home目录下的内容会自动同步到宿主机中/home/ceshi目录下

#同理,测试宿主机中/home/ceshi目录下新建的文件或修改文件内容是否会自动同步到容器内/home目录
#修改hello.txt文件内容
[root@aliyun ceshi]# vim hello.txt 
#查看hello.txt文件内容,新增一行Hello Torres!!!
[root@aliyun ceshi]# cat hello.txt 
Hello World
Hello Torres!!!
#新建一个test.txt文件
[root@aliyun ceshi]# touch test.txt
[root@aliyun ceshi]# ll
总用量 4
-rw-r--r-- 1 root root 28 4月  19 09:18 hello.txt
-rw-r--r-- 1 root root  0 4月  19 09:18 test.txt

#查看容器内/home目录下内容
[root@e4042f5dff6d home]# ls -al
total 12
drwxr-xr-x 2 root root 4096 Apr 19 01:18 .
drwxr-xr-x 1 root root 4096 Apr 19 01:10 ..
-rw-r--r-- 1 root root   28 Apr 19 01:18 hello.txt
-rw-r--r-- 1 root root    0 Apr 19 01:18 test.txt
[root@e4042f5dff6d home]# cat hello.txt 
Hello World
Hello Torres!!!

实战:安装MySql

#拉取镜像
[root@aliyun ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Pull complete 
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
0ceb82207cd7: Pull complete 
37f2405cae96: Pull complete 
e2482e017e53: Pull complete 
70deed891d42: Pull complete 
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

#运行容器,需要做数据挂载(注意:启动mysql,需要设置密码)
#官方启动命令
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#自己启动
-d:后台启动
-p:端口映射
-v:数据卷挂载
-e:设置环境变量
--name:定义容器名

[root@aliyun ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:5.7
6e755c41e69700decc8d6bb5966dbb82f6cb1dd6666975185445d8674d2b0704
#docker ps查看启动状态
[root@aliyun ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                               NAMES
6e755c41e697   mysql:5.7   "docker-entrypoint.s…"   38 seconds ago   Up 37 seconds   33060/tcp, 0.0.0.0:3310->3306/tcp   mysql01

#查看宿主机/home目录
[root@aliyun home]# ll
总用量 20
drwxr-xr-x 2 root root 4096 4月  19 09:18 ceshi
drwxr-xr-x 2 root root 4096 4月  15 15:07 docker
drwxr-xr-x 4 root root 4096 4月  19 10:31 mysql
drwxr-xr-x 3 root root 4096 4月   6 17:03 python
drwxr-xr-x 2 root root 4096 3月  25 15:46 shell
#查看mysql目录,发现挂载成功
[root@aliyun home]# cd mysql/
[root@aliyun mysql]# ll
总用量 8
drwxr-xr-x 2 root    root 4096 4月  19 10:31 conf
drwxr-xr-x 5 polkitd root 4096 4月  19 10:31 data

这样子就可以不用进入容器去修改数据等,同时也将数据存储到了本地。

思考:如果容器删除,本地数据是否也会跟着删除?

#删除mydql01容器
[root@aliyun ~]# docker rm -f mysql01
mysql01
[root@aliyun ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
#mysql01删除成功
[root@aliyun ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED       STATUS                      PORTS     NAMES
e4042f5dff6d   centos         "/bin/bash"   2 hours ago   Exited (0) 53 minutes ago             inspiring_volhard
7b913eab7ec9   fb5657adc892   "/bin/bash"   2 hours ago   Exited (0) 2 hours ago                tomcat01
#查看宿主机/home/mysql目录
[root@aliyun mysql]# pwd
/home/mysql
[root@aliyun mysql]# ll
总用量 8
drwxr-xr-x 2 root    root 4096 4月  19 10:31 conf
drwxr-xr-x 5 polkitd root 4096 4月  19 10:31 data

结论:当容器删除,宿主机对应挂载目录下内容依旧存在。

具名挂载和匿名挂载

#匿名挂载(即不指定本地挂载目录,使用docker的默认挂载目录)
[root@aliyun ~]# docker run -d -P -v /etc/nginx  --name=nginx01 nginx
9afbc16cec6c7f48f856faa1d4d8e15abb661ac8563e133832b80ee6efcb70b9
#查看所有volume的情况
[root@aliyun ~]# docker volume ls
DRIVER    VOLUME NAME
local     0c6e50ec3765f8b35ec4538836b8a987eb7ee893eecf4e1d9c61de61c0e2b2f5
#查看容器的具体信息
[root@aliyun ~]# docker inspect nginx01
···
"Mounts": [
            {
                "Type": "volume",
                "Name": "0d46c494e6c57f919827871a6810171c46f2999c00e63b2197e6623206556ff6",
                "Source": "/var/lib/docker/volumes/0d46c494e6c57f919827871a6810171c46f2999c00e63b2197e6623206556ff6/_data",
                "Destination": "/etc/nginx",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]
···


#具名挂载(指定宿主机挂载路径)
[root@aliyun ~]# docker run -d -P -v juming_nginx:/etc/nginx  --name=nginx02 nginx
c43e0f78971a88cebacf138e9b1b8516222c001cf72af3e4df8c83749c5f560e
#查看卷信息
[root@aliyun ~]# docker volume ls
DRIVER    VOLUME NAME
local     0c6e50ec3765f8b35ec4538836b8a987eb7ee893eecf4e1d9c61de61c0e2b2f5
local     0d46c494e6c57f919827871a6810171c46f2999c00e63b2197e6623206556ff6
local     00442e8628703dd84374e7512833e1889a0a6cea32172be79ff792e29b138fd7
local     b2af5d99231a0aa2c446b10ac1e8ba774a04253e8e27de155779fe061ea2467a
local     juming_nginx
#查看容器信息
[root@aliyun ~]# docker inspect nginx02
···
 "Mounts": [
            {
                "Type": "bind",
                "Source": "juming_nginx",
                "Destination": "/etc/nginx",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
···

所有docker容器内的卷,在没有指定路径的情况下,默认挂载目录为:/var/lib/docker/volumes/XXX/_data

如何区分挂载方式?

  • -v 容器内路径(匿名)
  • -v 卷名:容器内路径(具名)
  • -v 宿主机路径(绝对路径):容器内路径(指定路径挂载)

扩展

  • 通过-v容器内路径:ro/rw改变读写权限
ro:readonly(容器只读)
rw:readwrite(容器读写)
  • 一旦设置了这个容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx01 v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx01 v juming-nginx:/etc/nginx:rw nginx

只要看到ro,说明这个路径只能通过宿主机来改变,容器对所挂载数据卷内的数据就无法修改了。

数据卷容器

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,其目的是专门提供数据卷给其他容器使用

#创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata
[root@aliyun ~]# docker run -it -v /dbdata --name dbdata centos
#查看/dbdata目录
[root@b806186465ba /]# ls
bin  dbdata  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@b806186465ba /]# cd dbdata
[root@b806186465ba dbdata]# ls
#其他容器使用--volume-from来挂载dbdata容器中的数据卷,创建db1和db2容器
[root@aliyun ~]# docker run -it --volumes-from dbdata --name db1 centos
#db1
[root@70f46c3b15dc /]# ls
bin  dbdata  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

[root@aliyun ~]# docker run -it --volumes-from dbdata --name db2 centos
#db2
[root@d94f48a32c2d /]# ls
bin  dbdata  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

容器db1和db2都挂载到同一个数据卷到相同的/dbdata目录,三个容器任何一方在该目录下的写入,其他容器都可以看到。

#在dbdata容器中创建一个test文件
[root@b806186465ba dbdata]# pwd
/dbdata
[root@b806186465ba dbdata]# touch test.sh
#在db1容器中查看
[root@70f46c3b15dc /]# cd dbdata/
[root@70f46c3b15dc dbdata]# ls
test.sh
#在db2容器中查看
[root@d94f48a32c2d /]# cd /dbdata/
[root@d94f48a32c2d dbdata]# ls
test.sh

可以多次使用--volumes-from参数来从多个容器挂载多个数据卷,还可以从其他已挂载了容器卷的容器来挂载数据卷

[root@aliyun ~]# docker run -d --name db3 --volumes-from db1 centos

注意:使用--volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态

如果删除了挂载的容器(dbdata、db1和db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个 还挂载它的容器时显示使用 docker rm -v命令来指定同时删除关联的容器。

利用数据卷容器来迁移数据

可利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。

备份

$ docker run --volumes-from dbdata -v $(pwd):/backup --name worker centos tar -cvzf /backup/backup.tar.gz /dbdata

解析:

​ 首先利用centos镜像创建了一个容器worker,使用--volumes-from dbdata参数让worker容器挂载dbdata容器的数据卷(即dbdata数据卷);使用-v $(pwd):/backup参数来挂载本地的当前目录到worker容器的/backup目录

​ worker容器启动后,使用tar -cvzf /backup/backup.tar.gz /dbdata 将/dbdata下内容打包备份为容器内的/backup/backup.tar.gz,即宿主机当前目录下的backup.tar.gz

恢复

如果要恢复数据到一个容器,操作如下:

#创建一个带有数据卷的容器dbdata2
$ docker run -v /dbdata --name dbdata2 centos /bin/bash

#再创建一个新的容器,挂载dbdata2的容器,并使用tar解压备份文件到所挂载的容器中
$ docker run --volumes-from dbdata2 -v $(pwd):/backup centos tar -xvzf /backup/backup.tar.gz
posted on 2022-04-19 15:34  雷子锅  阅读(139)  评论(0编辑  收藏  举报