• Docker 容器数据 持久化(系统学习Docker05)


    写在前面

    本来是可以将数据存储在 容器内部 的。但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来。以前的同事也没有将数据映射到外面 。搞得最后我们重新导的数据,痛的领悟啊~~)。
    再就是如果不将数据映射出来 ,比如要想使用容器内部的web日志,也是比较难搞,反正不就是其它容器/服务不是很方便。

    大体上来说,一般只要使用Docker都会将 重要的数据 进行持久化。

    本文有任何问题,欢迎留言指正~

    Docker 持久化存储技术

    默认仅在Container Layer(层) 保存的文件数据,删除容器就没有了

    Data Volume(卷):数据卷,数据挂载相关,外挂一个存储

    在这里插入图片描述
    这个外挂的存储 ,即:Volume 有三种类型:

    Volume 卷的三种类型:

    1. Volume
      Docker 自己管理的 Data Volume ,由docker后台自动创建,我们不要去 手动 更改映射出来的文件内容。挂载点 存于主机文件系统中的某个区域docker area(linux 一般是存储在 /var/lib/docker/volumes/ 目录下)。

      这种持久化方式是很推荐的*****。

    2. Bind Mounting
      将当前主机目录 与 指定的容器内部目录进行绑定 --> 实现数据共享

      我们在开发的时候比较推荐这种方式,实现数据共享

      Docker的 数据共享 技术 能极大提高开发人员的开发效率

      配合chrome插件super auto refresh plus,边写代码,边看运行结果。相当舒服~。

    3. tmpfs mount(Linux中):存于内存中(注意,并不是持久化到磁盘)。在容器的生命周期中,它能被容器用来存放非持久化的状态或敏感信息
      在这里插入图片描述
      上图 卷的三种类型,后文主要根据代码来讲解这几种类型

    Volume 相关的常用命令:

    列出所有卷:docker volume ls

    删除某个卷:docker volume rm 卷名
    删除所有未使用的卷:docker volume prune # 慎用
    创建:docker volume create

    查看某个卷的元信息:docker volume inspect 卷名



    容器数据 持久化 实操

    类型一:Volume
    如果没有显式创建卷,一个卷会在最开始 挂载<VOLUME["/var/lib/mysql"] > 时被创建。当容器停止时,卷仍然存在。多个容器可以通过read-write或read-only的方式使用同一个卷。只有在显式删除时,卷才会被删除。

    查看官方mysql Dockerfile 中定义的持久化存储方式:
    https://github.com/docker-library/mysql/blob/6952c5d5a9889311157362c528d65dc2e37ff660/5.7/Dockerfile
    
    发现是通过 VOLUME["/var/lib/mysql"] 这样的方式将数据持久化到本地的 
    意思是指,需要将容器内部/var/lib/mysql 目录下的数据 映射出去 
    不指定其实是不会将数据映射出来的。
    映射出来的位置是在/var/lib/docker/volumes/  ,他会自己在该目录下生成一个volume ID
    实际的数据就是保存在其中的。
    
    代码验证上面这段话:
    docker volume ls
    docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7 
    [root@localhost ~]# docker ps
    cef34ac36e63        mysql:5.7           "docker-entrypoint.s…"   16 seconds ago      Up 15 seconds       3306/tcp, 33060/tcp                          mysql1
    [root@localhost ~]# 
    docker exec -it mysql1 bash
    mysql -u root
    create database test1;
    quit
    exit
    回到本地主机:
    docker volume ls 
    docker volume inspect [volume ID]
    详细信息中可以看见挂载点
    cd 进去,可以看见实际的数据库文件是真实存在的。
    /var/lib/docker/volumes/1b7400bf5cca58f06957e865ab7c072b4cd5961c56d536357fb69575985ecbac/_data
    [root@localhost _data]# ls
    auto.cnf    client-cert.pem  ibdata1      ibtmp1              private_key.pem  server-key.pem
    ca-key.pem  client-key.pem   ib_logfile0  mysql               public_key.pem   sys
    ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem  test1
    [root@localhost _data]# 
    
    其实这个时候你把容器停止,删除容器。数据库的文件还是会在本地保留的
    # 强制删除运行中的容器
    docker rm -f mysql1 
    # 删除volume 
    docker volume rm VOLUME NAME 
    
    【升级1】
    上面的方式有一个不好的地方就是:由于没有指定映射的对应目录,自动为我们生成了一个很长的Volume ID,
    这个其实是不太好管理的。最好的方式是,我们自己指定名称。
    
    具体如下:
    通过-v 指定映射
    docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7 
    [root@localhost ~]# docker volume ls
    DRIVER              VOLUME NAME
    local               mysql
    [root@localhost ~]# 
    发现是我们自己指定的名称mysql 
    
    【升级2】
    上面的还有一个不好的一点 就是不太方便移植映射出来,
    我们如果可以将映射出来的目录指定到 Dockerfile 同一级目录下就更好了,
    要想实现这个 可以通过编写 docker-compose.yml 文件,在文件中定义volume
    
    

    volume这种方式可以很好的将数据持久化的本地文件系统中,【推荐】

    类型二:Bind Mounting
    将当前目录外部 与 指定的容器内部目录进行绑定 --> 实现数据共享

    案例中 实现容器内部 /usr/share/nginx/html 与 本机主机 /root/docker-nginx
    两个目录下的文件共享

    案例:

    
    [root@localhost ~]# mkdir docker-nginx
    [root@localhost ~]# cd docker-nginx/
    
    [root@localhost docker-nginx]# vim Dockerfile 
    FROM nginx:latest
    WORKDIR /usr/share/nginx/html
    COPY index.html index.html
    
    [root@localhost docker-nginx]# docker build -t liuge36docker/my-nginx .
    Sending build context to Docker daemon  3.072kB
    Step 1/3 : FROM nginx:latest
     ---> 2073e0bcb60e
    Step 2/3 : WORKDIR /usr/share/nginx/html
     ---> Running in 8bdefed78445
    Removing intermediate container 8bdefed78445
     ---> 747647be78f1
    Step 3/3 : COPY index.html index.html
     ---> b6a5afe9dcf8
    Successfully built b6a5afe9dcf8
    Successfully tagged liuge36docker/my-nginx:latest
    [root@localhost docker-nginx]# 
    
    
    # 创建容器
    将当前目录与 指定的容器内部目录进行绑定 
    [root@localhost docker-nginx]# docker rm -f web
    web
    [root@localhost docker-nginx]# docker run -d -v $(pwd):/usr/share/nginx/html -p 8777:80 --name web liuge36docker/my-nginx
    4822d9626b36c2b539527a9ba8d9cdebfaee19762b02f957559e4f2ae6e2d281
    
    [root@localhost docker-nginx]# docker exec -it web /bin/bash
    root@4822d9626b36:/usr/share/nginx/html# ls
    Dockerfile  index.html
    root@4822d9626b36:/usr/share/nginx/html# touch hello.txt
    root@4822d9626b36:/usr/share/nginx/html# exit
    exit
    
    [root@localhost docker-nginx]# ls
    Dockerfile  hello.txt  index.html
    [root@localhost docker-nginx]# echo  "1111" >> hello.txt 
    [root@localhost docker-nginx]# docker exec -it web /bin/bash
    
    root@4822d9626b36:/usr/share/nginx/html# cat hello.txt 
    1111
    root@4822d9626b36:/usr/share/nginx/html#
    

    后面我可能会根据 SpringBoot 单独写一篇文章 ,看看到底这个代码共享 该怎么去做。

    本文比较基础,后面我再写一下关于 容错、 备份、恢复、迁移数据卷 相关的东西。

    尽情期待~

    有什么问题,欢迎留言讨论~~

    更多文章:系统学习Docker 不迷路:https://blog.csdn.net/liuge36/category_7651616.html

  • 相关阅读:
    账户经常被盗号怎么办?防盗“黑科技”了解一下
    京训钉自动播放,京训钉自动续播刷课时,京训钉自动关弹窗,自动下一课,倍速播放
    记账小程序
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    maven的安装配置使用
    年轻就该多尝试,教你20小时Get一项新技能
    原生JS封装常用函数
    记账小程序
    java基础知识学习小总结(一)
    JavaSE集合类
  • 原文地址:https://www.cnblogs.com/liuge36/p/12614680.html
Copyright © 2020-2023  润新知