4. Docker数据卷

3 Docker数据管理

如果将正在运行中的容器修改生成了新的数据, 或者修改了现有的一个已经存在的文件内容
那么新产生的数据将会被复制到读写层, 进行持久化保存, 这个读写层也就是容器的工作目录, 此即'写实复制'机制.

如下图, 是对根的数据写入到了容器的可写层, 但是把/data的数据写入到了一个另外的volume中, 用于数据的持久化

图片.png

3.1 容器的数据管理介绍

Docker镜像是分层设计的, 镜像层是只读的, 通过镜像启动的容器添加了一层可读写的文件系统, 用户写入的数据都保存在这一层中

3.1.1 Docker容器的分层

容器的数据分层:

  • LowerDir: image镜像层, 镜像本身, 只读
  • UpperDir: 容器的上层(读写), 容器变化的数据存在此处
  • MergeDir: 容器的文件系统, 使用Union FS,联合文件系统, 将LowerDir和UpperDir合并给容器使用, 用户看到的是MergerDir层的内容
  • WorkDir: 容器在宿主机的工作目录

范例: 查看容器的数据分层

  1. 启动一个centos7容器
root@ubuntu-1804-100:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              centos7.8.2003      afb6fca791e0        8 months ago        203MB
root@ubuntu-1804-100:~# docker run -it afb6fca791e0  bash 
[root@08e74b15d57b /]# 
root@ubuntu-1804-100:~# ll /var/lib/docker/overlay2/
total 24
drwx------  6 root root 4096 Jan 25 15:27 ./
drwx--x--x 14 root root 4096 Jan 25 15:10 ../
drwx------  5 root root 4096 Jan 25 15:27 3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/
drwx------  4 root root 4096 Jan 25 15:27 3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93-init/
drwx------  3 root root 4096 Jan 23 16:28 b4388765de3df5844b30cd4126ac952e32591193ee01d1083c413b639b199c26/
drwx------  2 root root 4096 Jan 25 15:27 l/
    1. 确定其工作目录
root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
08e74b15d57b        afb6fca791e0        "bash"              About a minute ago   Up About a minute                       intelligent_faraday
root@ubuntu-1804-100:~# docker inspect 08e74b15d57b
        "GraphDriver": {
            "Data": {
             "LowerDir": "/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93-init/diff:/var/lib/docker/overlay2/b4388765de3df5844b30cd4126ac952e32591193ee01d1083c413b639b199c26/diff",
             "MergedDir": "/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/merged",
             "UpperDir": "/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/diff",
             "WorkDir": "/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/work"
            },
            "Name": "overlay2"
        },
root@ubuntu-1804-100:~# tree -d -L 2 /var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93
/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93
├── diff   #存容器修改的数据
├── merged #用户看到的是MergerDir的内容,存放着联合系统 
│   ├── bin -> usr/bin
│   ├── dev
│   ├── etc
│   ├── home
│   ├── lib -> usr/lib
│   ├── lib64 -> usr/lib64
│   ├── media
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin -> usr/sbin
│   ├── srv
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
└── work
    └── work
    1. 修改容器数据
[root@08e74b15d57b /]# pwd
/
[root@08e74b15d57b /]# mkdir testdir
[root@08e74b15d57b /]# touch t
testdir/ tmp/     
[root@08e74b15d57b /]# touch testdir/test.txt
[root@08e74b15d57b /]# 
    1. 查看容器变化
root@ubuntu-1804-100:~# tree -d -L 2 /var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93
/var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93
├── diff
│   └── testdir  # testdir创建在了diff目录
├── merged
│   ├── bin -> usr/bin
│   ├── dev
│   ├── etc
│   ├── home
│   ├── lib -> usr/lib
│   ├── lib64 -> usr/lib64
│   ├── media
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin -> usr/sbin
│   ├── srv
│   ├── sys
│   ├── testdir # merged目录也产生了一个testdir文件夹
│   ├── tmp
│   ├── usr
│   └── var
└── work
    └── work
root@ubuntu-1804-100:~# ll -i /var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/diff/testdir/
total 8
1180068 drwxr-xr-x 2 root root 4096 Jan 25 15:36 ./
1177364 drwxr-xr-x 3 root root 4096 Jan 25 15:36 ../
1180069 -rw-r--r-- 1 root root    0 Jan 25 15:36 test.txt
root@ubuntu-1804-100:~# ll -i /var/lib/docker/overlay2/3c6b0f2b912e955e67ada7ff1545794bd644f0b4674ac18d91ba78bd4f71ea93/merged/testdir/
total 8
1180068 drwxr-xr-x 2 root root 4096 Jan 25 15:36 ./
1177348 drwxr-xr-x 1 root root 4096 Jan 25 15:36 ../
1180069 -rw-r--r-- 1 root root    0 Jan 25 15:36 test.txt
结论:
在容器中做的修改是发生在upper layer在diff文件夹 
修改后会复制一份到merged layer的merger文件夹 
这样会在系统看到2个相同文件 但是其实是同一个文件 因为id相同
如果把容器删了 容器目录也就自动被删了 数据就丢了
镜像文件夹和对应启动的容器的文件夹不是同一个
容器退出会立即释放磁盘空间, 释放那些没有被修改的数据, 而修改了的数据, 只要容器不删除是会被保留的
容器启动 会在对应的容器目录生成merged目录 把镜像数据加载进去 
一旦容器停止 merged目录就会消失 资源也就会被释放, 但是数据还在 容器启动还能看到merged
每次开启容器 都会复制出一份镜像空间大小
镜像本身只需要在磁盘有一个即可 但是每次运行成容器 需要复制出一份空间

3.1.2 哪些数据需要持久化

有状态的协议

有状态协议就是通信双方要记住双方, 并且共享一些信息, 而无状态协议的通信每次都是独立的, 与上一次的通信没什么关系.
状态可以理解为记忆, 有状态对应有记忆, 无状态对应无记忆

3.1.3 容器数据持久保存的方式

如果要将写入到容器的数据永久保存, 则需要将容器中的数据保存到宿主机的指定目录

Docker的数据类型分为两种:

  • 数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录, 推荐使用此种方式, 此方式比较常用
  • 数据卷容器(Data Volume Container): 间接使用宿主机空间, 数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器, 然后让其它容器通过数据卷容器读写宿主机的数据, 此方式不常用

3.2 数据卷

3.2.1 数据卷特点和使用

数据卷实际上就是宿主机上的目录或者是文件, 可以被直接mount到容器当中使用

实际生产环境中, 需要对不同类型的服务, 不同类型的数据存储要求做相应的规划, 最终保证服务的可扩展性, 稳定性以及数据的安全性

3.2.1.1 数据卷使用场景

日志输出
静态web页面
应用配置文件
多容器间目录或文件共享

3.2.1.2 数据卷的特点

对于容器内的文件, 映射到宿主机后, 管理更加方便, 多个容器共享宿主机的目录, 直接修改宿主机目录的文件, 即可完成容器内容的更新
数据卷是目录或文件, 并且可以在多个容器之间共同使用, 实现容器之间共享和重用
对数据卷更改数据在所有容器里面会立即更新
数据卷的数据可以持久保存, 即使删除使用该数据卷的容器, 也不会影响
在容器里面的写入数据不会影响到镜像本身, 即数据卷的变化不会影响镜像的更新
依赖于宿主机的目录, 宿主机出问题, 上面容器会受影响, 当宿主机较多时, 不方便统一管理
数据卷在容器启动时初始化, 如果容器使用的挂载点包含了数据, 会将这些原有数据拷贝到宿主机的挂载目录, 否则镜像内原有的数据相当于被隐藏无法访问了

3.2.1.3 数据卷使用方法

启动容器时, 可以指定使用数据卷实现容器数据的持久化数据卷有三种

  • 手动指定宿主机目录或文件: 指定宿主机的具体路径和容器路径的挂载关系
  • 匿名卷: 不指定数据卷的名称, 只指定容器内需要被持久化保存的路径或文件, Docker会自动指定宿主机的路径
  • 命名卷: 指定数据卷的名称, 和容器内路径的挂载关系, Docker会自动指定宿主机的路径
数据卷存储容器数据实现容器和数据分离
需要更新数据时直接在宿主机更新即可 不需要重新做镜像 
也支持多个容器共享同一个宿主机目录 实现批量升级页面 只要修改宿主机文件即可
docker run [-v|--volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]]

<options>
ro 从容器内对此数据卷是只读的, 不写此项默认为可读可写
rw 从容器内对数据卷可读可写, 此为默认值

方式1:

指定宿主机目录或文件格式
-v <宿主机绝对路径的目录或者文件>:<容器目录或文件>[:ro] # 将宿主机目录挂载容器目录, 两个目录都可自动创建

方式2:

匿名卷, 只指定容器内路径, 不指定宿主机的保存路径, 宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录, 并挂载至容器指定路径
-v <容器内路径>

docker run --name nginx -v /etc/nginx nginx

方式3:

命令卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data
-v <卷名>:<容器目录路径>
<卷名>可以通过以下命令事先创建, 如果没有实现创建卷名, docker run是会自动创建卷名
docker volume create <卷名>

示例
docker run -d -p 80:80 --name nginx01 -v vol1:/usr/share/nginx/html nginx

管理卷命令

docker volume COMMAND

Commands:
  Create         Create a volume
  inspect        Display detailed information on one or more volumes
  ls             List volumes   
  prune          Remove all unused local volumes
  rm             Remove one or more volumes

3.2.2 目录数据卷案例

3.2.2.1 拉取一个nginx镜像

root@ubuntu-1804-100:~# docker pull nginx
root@ubuntu-1804-100:~# docker images
nginx               latest              f6d0b4767a6c        13 days ago         133MB
root@ubuntu-1804-100:~# docker run -d -P f6d0b4767a6c
c90866e77de9f13b992c5de0a9deb8c0982d8cb08840736c8bb46a3af6ee79e2
root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
c90866e77de9        f6d0b4767a6c        "/docker-entrypoint.…"   5 seconds ago       Up 4 seconds        0.0.0.0:32768->80/tcp   nostalgic_poitras
root@ubuntu-1804-100:~# docker port nostalgic_poitras
80/tcp -> 0.0.0.0:32768

3.2.2.2 确定 /usr/share/nginx/html/ 目录为存放nginx网页的目录

root@ubuntu-1804-100:~# docker exec -it c90866e77de9 bash
root@c90866e77de9:/# ls /usr/share/nginx/html/
50x.html  index.html

3.2.2.3 指定宿主机目录挂载到 /usr/share/nginx/html/ 下

root@ubuntu-1804-100:~# docker run -d -v /data/nginx/html:/usr/share/nginx/html -p 80:80 --name n1 nginx
060ef54e073c3258091c4ff89c22787a1f85aa779043d5fed2bdb06814e34151
root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
060ef54e073c        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp      n1

此时, 容器中/usr/share/nginx/html/内的内容会被因此, 需要手动在/data/nginx/html目录下创建文件

[21:43:29 root@centos-7-1 ~]#curl 10.0.0.100
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.6</center>
</body>
</html>
root@ubuntu-1804-100:~# echo 'welcome to nginx website in docker' > /data/nginx/html/index.html
[21:50:48 root@centos-7-1 ~]#curl 10.0.0.100
welcome to nginx website in docker

之后, 只需要更新宿主机/data/nginx/html目录下的文件即可完成页面的更新

3.2.2.4 实现多个容器间的数据共享

root@ubuntu-1804-100:~# docker run -d -v /data/nginx/html:/usr/share/nginx/html -p 81:80 --name n2 nginx
b36fa9f082782b1fb7c3919bd02e79b684fa2e6a833acd60412d72257e1dd42d
[21:51:23 root@centos-7-1 ~]#curl 10.0.0.100:81
welcome to nginx website in docker

多个容器可以共享宿主机的一个目录, 可以实现批量更新页面

        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/nginx/html",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }

3.2.2.5 删除容器, 测试数据不会丢失

直接删除所有容器
root@ubuntu-1804-100:~# docker ps -aq  | xargs docker rm -f 
root@ubuntu-1804-100:~# ll /data/nginx/html/
total 12
drwxr-xr-x 2 root root 4096 Jan 25 21:51 ./
drwxr-xr-x 3 root root 4096 Jan 25 21:47 ../
-rw-r--r-- 1 root root   35 Jan 25 21:51 index.html

3.2.2.6 测试后续容器仍然可以使用该目录内容

root@ubuntu-1804-100:~# docker run -d -v /data/nginx/html:/usr/share/nginx/html -p 82:80 --name n3 nginx
b7cf38d6fbe45f8cebb85821028f55c991904e1ae14d2fffbf5b5d3652565986
[21:52:52 root@centos-7-1 ~]#curl 10.0.0.100:82
welcome to nginx website in docker

注意: 使用这种方式进行容器内数据的持久保存, 容器目录内本身的数据有时会被宿主机的目录覆盖, 挂载后无法获取容器目录内本身的文件, 需要提前把文件移走

3.2.3 匿名卷案例

指定容器内的目录, 但不指保存到宿主机哪个目录, 也不给保存的路径起名
匿名卷, 容器内本身的数据不会被宿主机的目录覆盖, 会把容器内本身的数据复制到宿主机的保存路径里

3.2.3.1 创建容器

root@ubuntu-1804-100:~# docker run -d -v /usr/share/nginx/html -p 80:80 --name n1 nginx
21accd803798f60749845b9e0d9991536037ac8558f51b36436e9f69bbf7c8fc
root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
21accd803798        nginx               "/docker-entrypoint.…"   2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp   n1
[21:56:50 root@centos-7-1 ~]#curl 10.0.0.100
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

3.2.3.2 查找容器内容保存到的路径,docker inspect 容器ID

root@ubuntu-1804-100:~# docker inspect 21accd803798
        "Mounts": [
            {
                "Type": "volume",
                "Name": "547540f918f0d8c45629a058e86c644b82ecf571c48535883adb2742b1b51ee6",
                "Source": "/var/lib/docker/volumes/547540f918f0d8c45629a058e86c644b82ecf571c48535883adb2742b1b51ee6/_data",  # 宿主机保存路径
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
root@ubuntu-1804-100:~# ls /var/lib/docker/volumes/547540f918f0d8c45629a058e86c644b82ecf571c48535883adb2742b1b51ee6/_data
50x.html  index.html

3.2.3.3 删除容器后, 数据仍然存在

root@ubuntu-1804-100:~# ls /var/lib/docker/volumes/547540f918f0d8c45629a058e86c644b82ecf571c48535883adb2742b1b51ee6/_data
50x.html  index.html

之后, 新创建的容器的匿名卷路径会映射到不同的目录, 虽然数据没丢, 但是后期不好确定宿主机存放路径存的是哪些数据

匿名卷的问题: 一旦容器删除, 那么docker inspect命令就无法执行, 也就无法查找到宿主机是哪个目录保存着文件, 除非事先提前记录下来, 或者find查找文件, 所有, 容器删除后, 匿名卷存在的意义不大
dockerfile中的volume就是匿名卷
docker rm选项可以删除容器时, 同时删除相关联的匿名卷
docker rm -f -v n1 删除的是匿名卷 指定的宿主机目录不会被删除 命名卷也不会删除

3.2.4 命名卷案例

3.2.4.1 创建卷名

root@ubuntu-1804-100:~# docker volume create nginxdata1
nginxdata1
root@ubuntu-1804-100:~# ll /var/lib/docker/volumes/
drwxr-xr-x  3 root root  4096 Jan 25 22:15 nginxdata1/

3.2.4.2 创建容器

root@ubuntu-1804-100:~# docker run -d -p 80:80 -v nginxdata1:/usr/share/nginx/html  --name n1 nginx
c98ae2ae222faccfcc6f1f8172759164ad9b69a2c6199e55b3a08c5523902565
root@ubuntu-1804-100:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
c98ae2ae222f        nginx               "/docker-entrypoint.…"   5 seconds ago       Up 3 seconds        0.0.0.0:80->80/tcp   n1

命名卷也会保留容器目录本身的数据

root@ubuntu-1804-100:~# ll /var/lib/docker/volumes/nginxdata1/_data/
total 16
drwxr-xr-x 2 root root 4096 Jan 25 22:16 ./
drwxr-xr-x 3 root root 4096 Jan 25 22:15 ../
-rw-r--r-- 1 root root  494 Dec 15 21:59 50x.html
-rw-r--r-- 1 root root  612 Dec 15 21:59 index.html

3.2.4.3 修改页面测试

root@ubuntu-1804-100:~# echo 'nginx v1.0' > /var/lib/docker/volumes/nginxdata1/_data/index.html
[22:01:08 root@centos-7-1 ~]#curl 10.0.0.100
nginx v1.0

3.2.4.4 命名卷因为对卷起了名字, 所以方便实现数据共享

root@ubuntu-1804-100:~# docker run -d -p 81:80 -v nginxdata1:/usr/share/nginx/html  --name n2 nginx
096b4174e20fcff4ca9ea67c2581e61b8d753a019e8f05d6ad045a47f9c70dd2
[22:18:51 root@centos-7-1 ~]#curl 10.0.0.100:81
nginx v1.0

3.2.5 MySQL使用目录数据卷

3.2.5.1 拉取MySQL镜像

root@ubuntu-1804-100:~# docker pull mysql:5.7.29
root@ubuntu-1804-100:~# docker images
mysql               5.7.29              5d9483f9a7b2        9 months ago        455MB

3.2.5.2 启动一个MySQL容器

root@ubuntu-1804-100:~# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=000000 mysql:5.7.29
a98c53d9a36ebe591b6af0aca192a9642ec8739e4e43858abc790bd85d0b2bfd
root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
a98c53d9a36e        mysql:5.7.29        "docker-entrypoint.s…"   4 seconds ago       Up 3 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   lucid_kapitsa

3.5.2.3 从客户端连接到MySQL

[22:24:16 root@centos-7-1 ~]#mysql -uroot -p000000 -h10.0.0.100
MySQL [(none)]> create database hellodb;
Query OK, 1 row affected (0.00 sec)
root@ubuntu-1804-100:~# docker exec -it a98c53d9a36e bash 
root@a98c53d9a36e:/# ls -l /var/lib/mysql
...
drwxr-x--- 2 mysql mysql     4096 Jan 25 14:34 hellodb
...

此时, 一旦容器删除, 那么数据也就丢失了, 再次创建新容器, 也无法使用原先的数据

root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
a98c53d9a36e        mysql:5.7.29        "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   lucid_kapitsa
root@ubuntu-1804-100:~# docker rm -f a98c53d9a36e
a98c53d9a36e
MySQL [(none)]> show databases;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.0.100' (111)
ERROR: Can't connect to the server

3.5.2.4 实现目录卷容器, 持久保存MySQL数据

root@ubuntu-1804-100:~# docker run -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=000000 --name mysql1 mysql:5.7.29
0d267f1991a8cbf46e1620dc91d54822075d7b3dffa6d7848ff0200e6b35710a
root@ubuntu-1804-100:~# ll /data/mysql/
total 110660
drwxr-xr-x  5  999 root       4096 Jan 25 22:40 ./
drwxr-xr-x 10 root root       4096 Jan 25 22:40 ../
-rw-r-----  1  999 docker       56 Jan 25 22:40 auto.cnf
-rw-------  1  999 docker     1676 Jan 25 22:40 ca-key.pem
-rw-r--r--  1  999 docker     1112 Jan 25 22:40 ca.pem
-rw-r--r--  1  999 docker     1112 Jan 25 22:40 client-cert.pem
-rw-------  1  999 docker     1676 Jan 25 22:40 client-key.pem
-rw-r-----  1  999 docker      425 Jan 25 22:40 ib_buffer_pool
-rw-r-----  1  999 docker 12582912 Jan 25 22:40 ibdata1
-rw-r-----  1  999 docker 50331648 Jan 25 22:40 ib_logfile0
-rw-r-----  1  999 docker 50331648 Jan 25 22:40 ib_logfile1
drwxr-x---  2  999 docker     4096 Jan 25 22:40 mysql/
drwxr-x---  2  999 docker     4096 Jan 25 22:40 performance_schema/
-rw-------  1  999 docker     1680 Jan 25 22:40 private_key.pem
-rw-r--r--  1  999 docker      452 Jan 25 22:40 public_key.pem
-rw-r--r--  1  999 docker     1112 Jan 25 22:40 server-cert.pem
-rw-------  1  999 docker     1676 Jan 25 22:40 server-key.pem
drwxr-x---  2  999 docker    12288 Jan 25 22:40 sys/
[22:38:57 root@centos-7-1 ~]#mysql -uroot -p000000 -h10.0.0.100
MySQL [(none)]> 
MySQL [(none)]> create database hellodb;
Query OK, 1 row affected (0.00 sec)

测试数据的持久保存

root@ubuntu-1804-100:~# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
0d267f1991a8        mysql:5.7.29        "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql1
root@ubuntu-1804-100:~# docker rm -f 0d267f1991a8
0d267f1991a8
root@ubuntu-1804-100:~# ll /data/mysql/
total 188488
drwxr-xr-x  6  999 root       4096 Jan 25 22:41 ./
drwxr-xr-x 10 root root       4096 Jan 25 22:40 ../
-rw-r-----  1  999 docker       56 Jan 25 22:40 auto.cnf
-rw-------  1  999 docker     1676 Jan 25 22:40 ca-key.pem
...

再次创建容器, 仍可以使用原先的数据

root@ubuntu-1804-100:~# docker run -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=000000 --name mysql2 mysql:5.7.29
f61e09f4adde1a26ed56b2240b9a7919b9b176bb9e4baccf5c51ed1a0af33694
[22:43:52 root@centos-7-1 ~]#mysql -uroot -p000000 -h10.0.0.100
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.29 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

三种数据卷对比

目录数据卷: 
优点: 可以人为指定宿主机保存容器数据的目录, 方便查看, 只要做好目录规划, 不会影响后期管理; 同时, 其他容器也可以基于相同的宿主机目录进行挂载, 实现数据共享.
缺点: 宿主机目录一旦故障, 容器数据就会丢失, 不过可以借助存储, 让宿主机的目录也成为一个挂载点, 这样就可以保证数据的安全
匿名数据卷: dockerfile中volume指令就是匿名卷
优点: 暂时没发现
缺点: 会在/var/lib/docker/volumes生成哈希字符串的目录, 不方便查找, 也不方便后期管理
命名数据卷: 启动容器时, 给数据卷起个名字, 最终还是存在volumes目录下
优点: 有名字就方便查看和后期管理
缺点: 只能存到volumes目录下, 无法实现自定义
匿名卷和数据卷对于数据共享的支持没有目录数据卷号好, 虽然可以通过docker inspect确定宿主机存放数据的目录
但是如果想做数据共享, 后续的容器还是要基于这个宿主机目录做目录数据卷

3.3 数据卷容器

3.3.1 数据卷容器介绍

在Dockerfile中创建的是匿名卷, 无法直接直线多个容器之间共享数据
数据卷容器最大的功能是可以让数据在多个Docker容器之间共享

如下图: 既可以让B容器访问A容器的内容, 而容器C也可以访问A容器的能内容, 既可以实现A,B,C三个容器之间的数据读写共享

图片.png

相当于先要创建一个后台运行的容器作为Server, 用于提供数据卷, 这个卷可以作为其他容器提佛那个数据存储服务, 其他使用此卷的容器作为client端, 但此方法并不常用
优点: 作为数据卷的容器, 即使停止, 也不会影响其余容器, 并且即使删除了volume容器, 原有的容器还是能正常访问数据
缺点: 一旦volume容器删除, 那么新创建的容器就无法访问数据了

3.3.2 使用数据卷容器

启动容器时, 指定使用数据卷容器
docker run 命令的以下选项可以实现数据卷容器, 格式如下:
-- volumes-from <数据卷容器>

3.3.3 数据卷容器功能

将提供卷的容器Server删除, 已经运行的容器client依然可以使用挂载的卷, 因为容器是通过挂载访问数据的
但是, 无法创建新的数据卷容器客户端
需要重新把数据卷Server创建, 然后再创建容器client, 此方式用于线上共享数据目录等环境, 因为即使数据卷容器被删除了, 其他已经运行的容器依然可以挂载使用
由此可知, 数据卷容器的功能只是将数据挂载信息传递给其他使用数据卷容器的容器, 而数据卷容器本身并不会提供存储功能
数据卷容器可以作为共享的方式为其他容器提供文件共享, 类似NFS, 可以在生成环境启动一个实例挂载本地目录, 然后其他的容器分别挂载此容器的目录, 即可保证各个容器之间数据一致性
数据卷容器的Server和Client可以不使用同一个镜像生成
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容