容器数据卷

容器数据卷

什么是容器数据卷

如果数据都在容器中,那么我们不小心把容器删除了,数据也会跟着删除。

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地。

这就叫做卷技术!类似目录挂载,将我们的容器内的目录,挂载到Linux上面去。

总结:容器持久化的同步操作!容器间也是可以数据共享。

使用数据卷

方法一:直接使用命令挂载 run -it -v

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

# 将/home/test目录共享到容器/home里。
[root@localhost ~]# docker run -it -v /home/test:/home centos /bin/bsh

# 检测是否挂载成功
[root@localhost ~]# docker inspect 97a42265b5b6
[
    {
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/test",
                "Destination": "/home",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        ...
    }
]
Source=主机内的地址
Destination=docker容器的地址

测试是否共享,只要容器没有删除再次打开容器还是有共享文件。

安装MySQL

# 运行容器,需要做数据挂载!
# 安装启动mysql,需要配置密码的,这是要注意点!
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

# 启动mysql
    # -d 后台运行
    # -p 端口映射
    # -v 挂载数据卷
    # -e 环境配置
    # --name 容器名字
[root@localhost test]# docker run -d -p 3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
e2cd5ddb165ae5db53108269899cb8f3943f1dd64cd04f66445468cc989346cd

# 测试是否能连上MySQL
[root@localhost ~]# docker exec -it e2cd5ddb165a /bin/bash
root@e2cd5ddb165a:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.23 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

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

mysql> 

  • 测试删除MySQL容器数据还会不会存在,测试结果如下图。

命名和匿名挂载

匿名挂载

# 匿名挂载
-v 容器内路径

[root@localhost ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
WARNING: IPv4 forwarding is disabled. Networking will not work.
81e590c33d5ced13125210fae910523e7355862b9c60eef4343a70f6b4090e65

# 查看所有的volume的情况
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
...
local     80f56ffda149eaca23399d1f2a5076e008d073391a7d2df52ea600734dbf0361
...
# 在这里发现,这种就叫做匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径。

命名挂载

# 命名挂载
-v 卷名:容器内部路径

[root@localhost ~]# docker run -d -P --name nginx02 -v nameNgix:/ect/nginx nginx
WARNING: IPv4 forwarding is disabled. Networking will not work.
22b32e8e28265bc110073476a38917d1b3f236185c087f7deff1710d88f71c84
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
...
local     nameNgix

# 查看这就卷路径
[root@localhost ~]# docker volume inspect nameNgix
[
    {
        "CreatedAt": "2021-01-23T10:55:58+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nameNgix/_data",
        "Name": "nameNgix",
        "Options": null,
        "Scope": "local"
    }
]

所有的docker容器的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data

[root@localhost ~]# ls -lah /var/lib/docker/volumes/
总用量 24K
drwx------  6 root root    282 1月  23 10:55 .
drwx--x--x 13 root root    167 1月  22 23:21 ..
drwxr-xr-x  3 root root     19 1月  21 19:46 1129bb7f0e172536609ef062f69aff7361c3c6119f246565dfd15ad5286f518a
drwxr-xr-x  3 root root     19 1月  19 22:14 80f56ffda149eaca23399d1f2a5076e008d073391a7d2df52ea600734dbf0361
drwxr-xr-x  3 root root     19 1月  23 10:51 9c4cbb1c6bcd9b6ff79606770f2d653acbca69174b008410faa645e5b79072d2
brw-------  1 root root 253, 0 1月  22 23:21 backingFsBlockDev
-rw-------  1 root root    32K 1月  23 10:55 metadata.db
drwxr-xr-x  3 root root     19 1月  23 10:55 nameNgix

我们通过命名挂载可以方便的找到我们的一个卷,大多数情况在使用命令挂载

# 如何确定是命名挂载还是匿名挂载,还是指定路径挂载。
-v 容器内路径               # 匿名挂载
-v 卷名:容器内路径           # 命名挂载
-v /宿主机路径::容器内路径    # 指定路径挂载

扩展

# 通过-v容器内路径:ro,rw改变读写权限。
:ro readdonly # 只读
:rw readwrite # 读写

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了。
docker run -d -P --name nginx02 -v nameNginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nameNginx:/etc/nginx:rw nginx

方法二:Dockerfile

Dockerfile就是用来构建docker镜像的构建文件!

创建Dockerfile

[root@localhost docker-test-volume]# vim dockerfile1
# 设置基础容器
FROM centos
# 挂载目录
VOLUME ["volume01", "volume02"]
# 生成完以后输出提示内容
CMD echo "---end---"
# 进入容器使用bash
CMD /bin/bash

构建镜像

[root@localhost docker-test-volume]# docker build -f dockerfile1 -t webb/centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : VOLUME ["volume01", "volume02"]
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in 81d4391f6f83
Removing intermediate container 81d4391f6f83
 ---> 5b7725918c4d
Step 3/4 : CMD echo "---end---"
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in db020d2e09e2
Removing intermediate container db020d2e09e2
 ---> b38ac4724313
Step 4/4 : CMD /bin/bash
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in cc71706a0ade
Removing intermediate container cc71706a0ade
 ---> b883d4704605
Successfully built b883d4704605
Successfully tagged webb/centos:1.0

启动镜像

[root@localhost docker-test-volume]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED         SIZE
webb/centos                       1.0       b883d4704605   2 minutes ago   209MB
...
[root@localhost docker-test-volume]# docker run -it b883d4704605 /bin/bash
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@2a3fff76922c /]# ls -alh
total 0
drwxr-xr-x   1 root root  38 Jan 23 03:24 .
drwxr-xr-x   1 root root  38 Jan 23 03:24 ..
-rwxr-xr-x   1 root root   0 Jan 23 03:24 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3 15:22 bin -> usr/bin
drwxr-xr-x   5 root root 360 Jan 23 03:24 dev
drwxr-xr-x   1 root root  66 Jan 23 03:24 etc
drwxr-xr-x   2 root root   6 Nov  3 15:22 home
lrwxrwxrwx   1 root root   7 Nov  3 15:22 lib -> usr/lib
lrwxrwxrwx   1 root root   9 Nov  3 15:22 lib64 -> usr/lib64
drwx------   2 root root   6 Dec  4 17:37 lost+found
drwxr-xr-x   2 root root   6 Nov  3 15:22 media
drwxr-xr-x   2 root root   6 Nov  3 15:22 mnt
drwxr-xr-x   2 root root   6 Nov  3 15:22 opt
dr-xr-xr-x 138 root root   0 Jan 23 03:24 proc
dr-xr-x---   2 root root 162 Dec  4 17:37 root
drwxr-xr-x  11 root root 163 Dec  4 17:37 run
lrwxrwxrwx   1 root root   8 Nov  3 15:22 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Nov  3 15:22 srv
dr-xr-xr-x  13 root root   0 Jan 23 03:24 sys
drwxrwxrwt   7 root root 145 Dec  4 17:37 tmp
drwxr-xr-x  12 root root 144 Dec  4 17:37 usr
drwxr-xr-x  20 root root 262 Dec  4 17:37 var
------------------------------------------------------
- drwxr-xr-x   2 root root   6 Jan 23 03:24 volume01 -
- drwxr-xr-x   2 root root   6 Jan 23 03:24 volume02 -
------------------------------------------------------
# 这个目录就是我们生成镜像的时候自动挂载的,数据目录。

这个卷和外部的一定有一个同步的目录!首先需要在容器内部创建文件。

[root@f1a7ca9f247c /]# cd volume01
[root@f1a7ca9f247c volume01]# touch contariner.txt
[root@f1a7ca9f247c volume01]# ls
contariner.txt

退出容器使用docker inspect来查找。

[root@localhost ~]# docker inspect f1a7ca9f247c
[
    {
        "Mounts": [
            {
                "Type": "volume",
                "Name": "65a7986cd0c9e83005f0a00f926d0c8b204026b1dbb9115ce79859d943735ed1",
                "Source": "/var/lib/docker/volumes/65a7986cd0c9e83005f0a00f926d0c8b204026b1dbb9115ce79859d943735ed1/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "949e6d5754e236bd1b547d9c885e30ab58454b270d706bfc3468b3eb6b0d5261",
                "Source": "/var/lib/docker/volumes/949e6d5754e236bd1b547d9c885e30ab58454b270d706bfc3468b3eb6b0d5261/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        ...
    }
]

测试一下文件是否同步成功。这种方式未来会使用比较多,通常会构建自己的镜像!

假设构建镜像时候没有挂载卷,要手动镜像挂载-v卷名:容器内部路径!

[root@localhost ~]# cd /var/lib/docker/volumes/65a7986cd0c9e83005f0a00f926d0c8b204026b1dbb9115ce79859d943735ed1/_data
[root@localhost _data]# ls
contariner.txt

数据卷容器

挂载三个容器

# 启动容器
[root@localhost ~]# docker run -it --name docker01 webb/centos:1.0
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@109cbca8ee4b /]# ls
        -------数据卷--------
bin ...  volume01   volume02
        --------------------
# 使用ctrl+p+q退出容器

# 启动第二镜像 
[root@localhost ~]# docker run -it --name docker02 --volumes-from docker01 webb/centos:1.0
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@109cbca8ee4b /]# ls
        -------数据卷--------
bin ...  volume01   volume02
        --------------------

创建第二个容器,判断是否共享成功!

创建第三个容器。

实现多个MySQL数据共享。

[root@localhost ~]#  docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql

[root@localhost ~]#  docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql

[root@localhost ~]#  docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql03 --volumes-from mysql01 mysql

# 这个时候,可以实现两个容器数据同步!

结论:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。