六、Docker:数据卷

其他文章:

一、Docker:概述

二、Docker:安装

三、Docker:命令

四、Docker:可视化管理

五、Docker:镜像(image)

六、Docker:数据卷

七、Docker:DockerFile

八、Docker:Docker网络原理

九、Docker:IDEA整合Docker

----------------------------------------------------------------

六、数据卷

解决容器和系统的资源隔离问题。

什么是数据卷

docker中的数据如何保存?

如果数据都放在容器内部,容器删除后,数据就会丢失了。需求:数据可以持久化。

如果安装了一个mysql容器,容器删除,数据必须还在。需求:容器数据存在的宿主机。

什么是数据卷技术?容器直接可以有一个数据共享技术,docker容器中产生的数据,同步到本地宿主机。这就是数据卷技术。使用目录挂载,将容器内部的目录挂载到linux上即可。

image-20210506173442098

总结:数据卷解决容器数据的持久化和同步操作!容器之间也可以数据共享!

如何使用数据卷

方式一:直接使用命令挂载 -v

[root@localhost ~]# 
[root@localhost ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost ~]# 
[root@localhost ~]# ls /local # 宿主机没有该目录
ls: cannot access /local: No such file or directory
[root@localhost ~]# 
# 使用-v挂载,将宿主机的/local目录和容器的/home目录进行映射
[root@localhost ~]# docker run -it -v /local:/home centos /bin/bash   
[root@bc9c7875eb78 /]# 
[root@bc9c7875eb78 /]# ls /home/ # 查看容器内的/home目录
[root@bc9c7875eb78 /]# 
[root@bc9c7875eb78 /]# touch /home/test.java # 在home下面创建文件
[root@bc9c7875eb78 /]# 
[root@bc9c7875eb78 /]# ls /home/      
test.java
[root@bc9c7875eb78 /]#

# 宿主机查看结果 
[root@localhost ~]# ls /local/ # 容器启动后会自动创建该目录
test.java
[root@localhost ~]# 
# 容器停止后,依然可以通过宿主机操作该目录。当容器重启后可以看到相关的修改。数据会自动同步。

# 查看容器挂载信息
[root@localhost ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
b5992d9af84d   centos    "/bin/bash"   31 seconds ago   Up 30 seconds             sharp_ramanujan
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# docker inspect b5992d9af84d  # 查看容器信息
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/local",  # 宿主机地址
                "Destination": "/home", # docker内地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

实战:安装mysql

容器中/data目录是存储mysql的数据的,需要将/data目录挂载到宿主机上,防止数据丢失。

注意点:1.将配置文件映射出来;2.将数据映射出来;3.密码处理

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

即使使用docker rm 容器id 删除了容器,mysql的数据依然存在。

直接挂载分两种:匿名挂载和具名挂载

# -v /宿主机目录:/容器目录   # 这是直接将两个目录进行映射 目录都以/开头
# -v /容器目录             # 这是匿名挂载
# -v 挂载名称:/容器目录      # 这是具名挂载  挂载名称不以/开头


# 查看卷信息 docker volume 
[root@localhost docker]# docker volume --help 

Usage:  docker volume COMMAND

Manage volumes

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

Run 'docker volume COMMAND --help' for more information on a command.
[root@localhost docker]# 
[root@localhost docker]# 
[root@localhost docker]# 
[root@localhost docker]# docker volume ls # 目前不存在卷
DRIVER    VOLUME NAME
[root@localhost docker]# 

# 匿名挂载
[root@localhost docker]# 
[root@localhost docker]# docker run -P -d -v /etc/nginx --name nginx01 nginx # 匿名挂载
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f7ec5a41d630: Already exists 
aa1efa14b3bf: Pull complete 
b78b95af9b17: Pull complete 
c7d6bca2b8dc: Pull complete 
cf16cd8e71e0: Pull complete 
0241c68333ef: Pull complete 
Digest: sha256:75a55d33ecc73c2a242450a9f1cc858499d468f077ea942867e662c247b5e412
Status: Downloaded newer image for nginx:latest
3d33b05202eeee3f3e60a68f7c9f039ea77dc4981cbf8557b8ec03a9ffbbc934
[root@localhost docker]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
3d33b05202ee   nginx       "/docker-entrypoint.…"   28 seconds ago   Up 26 seconds   80/tcp                                                 nginx01
[root@localhost docker]# 
[root@localhost docker]# docker volume ls  # 查看卷信息
DRIVER    VOLUME NAME
local     1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3 # 匿名
[root@localhost docker]# 
[root@localhost docker]# ls /var/lib/docker/volumes/ # 查看目录中的卷信息
1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3  metadata.db
backingFsBlockDev
[root@localhost docker]# 
[root@localhost docker]# 
[root@localhost docker]# docker volume inspect 1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3  # 查看挂载的详细信息
[
    {
        "CreatedAt": "2021-05-07T19:19:29+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3/_data", # 宿主机的目录
        "Name": "1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3",
        "Options": null,
        "Scope": "local"
    }
]
[root@localhost docker]# 

# 具名挂载(常用)
[root@localhost docker]# 
[root@localhost docker]# docker run -P -d -v nginx-Juming:/etc/nginx --name nginx02 nginx
6f4fcf67b2fb40ab2cb81685dd4de7ac2cef38f6c2599e1eec719a79797c2538
[root@localhost docker]# 
[root@localhost docker]# docker volume ls
DRIVER    VOLUME NAME
local     1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3
local     nginx-Juming  # 具名
[root@localhost docker]# 
[root@localhost docker]# ls /var/lib/docker/volumes/
1f8593b8dd6b2c78764a5710d037156795a644d0f9460e40d4300b0fbdbc04b3  metadata.db
backingFsBlockDev                                                 nginx-Juming # 具名
[root@localhost docker]# 
[root@localhost docker]#  docker volume inspect  nginx-Juming # 查看挂载的详细信息
[
    {
        "CreatedAt": "2021-05-07T19:27:01+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nginx-Juming/_data", # 宿主机的目录 可以在这里修改配置文件
        "Name": "nginx-Juming",
        "Options": null,
        "Scope": "local"
    }
]
[root@localhost docker]# 

权限控制

# 数据卷权限控制  -v nginx-Juming:/etc/nginx:ro
[root@localhost docker]# docker run -P -d -v nginx-Juming:/etc/nginx:ro --name nginx02 nginx

# ro: read only 只读。只能在容器外部改变文件,不能在容器内部改变文件
# rw: read write 读写。默认权限。容器内外都能改变文件。

方式二:使用DockerFile

之前我们使用commit构建过镜像。

初识Dockerfile。先体验一下。

Dockerfile就是用来构建docker镜像的构建文件!Dockerfile就是一段命令脚本,通过这个脚本可以生成镜像!镜像是一层一层的,脚本是一个一个命令,可以理解成每个命令就是一层镜像。

[root@localhost ~]# mkdir docker-build-test
[root@localhost ~]# cd docker-build-test/
[root@localhost docker-build-test]# 

# 1.生成dockerfile
[root@localhost docker-build-test]# vim DockerFile #名字可以自定义 建议用dockerfile
# dockerfile中的内容每一行是一条命令。 每一条命令有指令(大写)和参数组成。每个命令就是一层镜像。
[root@localhost docker-build-test]# cat DockerFile
FROM centos    # 基于centos镜像为基础

VOLUME ["volume01","volume02"]   # 自动挂载的数据卷目录

CMD echo "----end----"

CMD /bin/bash
[root@localhost docker-build-test]#
[root@localhost docker-build-test]# docker build --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --add-host list           Add a custom host-to-IP mapping (host:ip)
      --build-arg list          Set build-time variables
      --cache-from strings      Images to consider as cache sources
      --cgroup-parent string    Optional parent cgroup for the container
      --compress                Compress the build context using gzip
      --cpu-period int          Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int           Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int          CPU shares (relative weight)
      --cpuset-cpus string      CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string      MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                Always remove intermediate containers
      --iidfile string          Write the image ID to the file
      --isolation string        Container isolation technology
      --label list              Set metadata for an image
  -m, --memory bytes            Memory limit
      --memory-swap bytes       Swap limit equal to memory plus swap: '-1' to
                                enable unlimited swap
      --network string          Set the networking mode for the RUN instructions
                                during build (default "default")
      --no-cache                Do not use cache when building the image
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --rm                      Remove intermediate containers after a successful
                                build (default true)
      --security-opt strings    Security options
      --shm-size bytes          Size of /dev/shm
  -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.
      --ulimit ulimit           Ulimit options (default [])
[root@localhost docker-build-test]# 

# 2.通过dockerfile构建镜像
[root@localhost docker-build-test]# docker build -f /root/docker-build-test/DockerFile  -t wuxl/centos:1.0 . 
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 46e3da7ae117
Removing intermediate container 46e3da7ae117
 ---> 77b04bfac2fa
Step 3/4 : CMD echo "----end----"
 ---> Running in dd2b6ddfed0b
Removing intermediate container dd2b6ddfed0b
 ---> 8512e84141d6
Step 4/4 : CMD /bin/bash
 ---> Running in eab90b2dd126
Removing intermediate container eab90b2dd126
 ---> d60645df454b
Successfully built d60645df454b
Successfully tagged wuxl/centos:1.0
[root@localhost docker-build-test]# 

# 3.查看镜像
[root@localhost docker-build-test]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED              SIZE
wuxl/centos   1.0       d60645df454b   About a minute ago   209MB  # 构建的镜像
tomcat        2.0       c01bd59511a6   7 days ago           672MB
tomcat        latest    c0e850d7b9bb   2 weeks ago          667MB
mysql         5.7       87eca374c0ed   2 weeks ago          447MB
nginx         latest    62d49f9bab67   3 weeks ago          133MB
centos        latest    300e315adb2f   5 months ago         209MB
[root@localhost docker-build-test]# 

# 4.运行镜像 这里需要注意,如果使用的是容器名称启动,必须加tag:  wuxl/centos:1.0  
[root@localhost docker-build-test]# docker run -it d60645df454b /bin/bash # 运行
[root@b8d89421ecfd /]# 
[root@b8d89421ecfd /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var       volume02 # 目录
dev  home  lib64  media       opt  root  sbin  sys  usr  volume01 # 目录
[root@b8d89421ecfd /]#

[root@localhost ~]# docker ps 
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                                                  NAMES
b8d89421ecfd   d60645df454b   "/bin/bash"              About a minute ago   Up About a minute                                                          funny_banach

# 查看容器的挂载情况(匿名挂载)
[root@localhost ~]# docker inspect b8d89421ecfd
        "Mounts": [
            {
                "Type": "volume",
                "Name": "2c728e3c84280bead80b4c39fd016dc87c385e377cea0fc12c4ced893eb7673b",
                "Source": "/var/lib/docker/volumes/2c728e3c84280bead80b4c39fd016dc87c385e377cea0fc12c4ced893eb7673b/_data", # 宿主机目录
                "Destination": "volume02", # 容器目录
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "1d8c109f6254daada08d5646529b630e8ff4cc9e099c7cb4a5674f9446e05ce1",
                "Source": "/var/lib/docker/volumes/1d8c109f6254daada08d5646529b630e8ff4cc9e099c7cb4a5674f9446e05ce1/_data", # 宿主机目录
                "Destination": "volume01", # 容器目录
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

这种方式使用的十分多,因为我们通常会构建自己的镜像。

假设构建镜像的时候没有挂载数据卷,要手动挂载镜像 -v 卷名:/容器内目录。

数据卷容器

两个容器相互同步数据。比如多个mysql容器同步数据。

image-20210507121755944

# 使用上面我们通过dockerfile构建的镜像,启动三个容器 测试

# 1.启动第一个容器(作为父容器或数据卷容器)
[root@localhost ~]# docker ps    
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
wuxl/centos   1.0       d60645df454b   39 minutes ago   209MB
tomcat        2.0       c01bd59511a6   7 days ago       672MB
tomcat        latest    c0e850d7b9bb   2 weeks ago      667MB
mysql         5.7       87eca374c0ed   2 weeks ago      447MB
nginx         latest    62d49f9bab67   3 weeks ago      133MB
centos        latest    300e315adb2f   5 months ago     209MB
[root@localhost ~]# 
[root@localhost ~]# docker run -it  --name wuxlcentos01 wuxl/centos:1.0
[root@81d68891cee7 /]# ls -l
total 0
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 360 May  7 12:38 dev
drwxr-xr-x.   1 root root  66 May  7 12:38 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Dec  4 17:37 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 123 root root   0 May  7 12:38 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  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 May  7 09:13 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 May  7 12:38 volume01 # 数据卷01
drwxr-xr-x.   2 root root   6 May  7 12:38 volume02 # 数据卷02
[root@81d68891cee7 /]# 
[root@81d68891cee7 /]# cd volume01
[root@81d68891cee7 volume01]# touch centos01.java  # 在数据卷01中创建一个文件
[root@81d68891cee7 volume01]# ls
centos01.java
[root@81d68891cee7 volume01]# 


# 启动第二个容器 继承wuxlcentos01容器的数据卷:  --volumes-from wuxlcentos01 
[root@localhost ~]# 
[root@localhost ~]# docker run -it --volumes-from wuxlcentos01 --name wuxlcentos02 wuxl/centos:1.0
[root@be78dfb1ac82 /]# ls -l
total 0
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 360 May  7 12:43 dev
drwxr-xr-x.   1 root root  66 May  7 12:43 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Dec  4 17:37 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 125 root root   0 May  7 12:43 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  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 May  7 09:13 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  27 May  7 12:39 volume01
drwxr-xr-x.   2 root root   6 May  7 12:38 volume02
[root@be78dfb1ac82 /]# ls /volume01/  # wuxlcentos01创建的数据
centos01.java
[root@be78dfb1ac82 /]# touch /volume01/centos02.java # wuxlcentos02也创建文件
[root@be78dfb1ac82 /]# 
[root@be78dfb1ac82 /]# ls /volume01/
centos01.java  centos02.java
[root@be78dfb1ac82 /]# 

# 启动第三个容器 也继承wuxlcentos01容器的数据卷:  --volumes-from wuxlcentos01 
[root@localhost ~]# docker run -it --volumes-from wuxlcentos01 --name wuxlcentos03 wuxl/centos:1.0
[root@f6c6b2d2c8e3 /]# ls -l
total 0
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 360 May  7 12:46 dev
drwxr-xr-x.   1 root root  66 May  7 12:46 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Dec  4 17:37 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 130 root root   0 May  7 12:46 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  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 May  7 09:13 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  48 May  7 12:44 volume01  # 继承的数据卷
drwxr-xr-x.   2 root root   6 May  7 12:38 volume02  # 继承的数据卷
[root@f6c6b2d2c8e3 /]# ls /volume01/
centos01.java  centos02.java
[root@f6c6b2d2c8e3 /]# touch /volume01/centos03.java 
[root@f6c6b2d2c8e3 /]# 
[root@f6c6b2d2c8e3 /]# ls /volume01/                
centos01.java  centos02.java  centos03.java
[root@f6c6b2d2c8e3 /]# 

即使docker rm wuxlcentos01后,wuxlcentos02和wuxlcentos03的数据依然存在。因为数据共享是一个双向拷贝的概率。

image-20210507122314696

两个mysql容器的数据如何实现同步?

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

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

# mysql02容器启动时使用--volumes-from mysql01 ,就可以使得两个mysql容器的数据同步了。
# mysql01是父容器(数据卷容器),mysql02是mysql01的子容器。

结论

容器之间的配置信息的传递(集群),数据卷容器的生命周期一直持续到没有任何容器使用为止。不会因为某个容器的关闭、删除导致数据的丢失。一旦父容器的数据通过-v持久化到了宿主机,这个数据就不会丢失。

上述知识实际操作基本够用。

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:Age of Ai 设计师:meimeiellie 返回首页
评论

打赏作者

诸葛小猿

传播知识,共享价值

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值