美文网首页docker从入门到放弃
docker卷、持久化和迁移

docker卷、持久化和迁移

作者: 我傻笑你跑掉 | 来源:发表于2021-02-01 18:20 被阅读0次

    容器中的数据与Host相互独立,随着容器的释放(删除),这些数据也将丢失.
    为了避免这个问题,Docker提供了数据卷(Volume)这个数据持久化工具.
    持久化后的数据,不会随着容易删除而丢失.

    概述

    试想这样一个场景,几年前我创建了一个mysql5.5的容器,几年后由于业务变动,需要升级到mysql5.6,这个时候需要登陆到容器里面,把mysql的表文件复制下来,再想办法迁移到新的mysql服务中.

    这个手动复制的过程很容易出现意外,万一不粗心大意,没有复制data就删除了容器,那差不多可以跑路了,否则就等着全村吃席吧.

    好在Docker提供了bind mountvolume两种方式来做数据持久化,先准备个mysql镜像准备演示.

    docker pull mysql:5.6
    

    bind mount

    bind mount是将host上的一个目录mount到容器中,类似于一个共享文件夹.

    bind mount一个目录到容器,需要在创建容器时使用-v 本地目录:容器目录参数指定

    docker run  -v /Users/zhangsan/opt:/opt ......
    

    上述例子将本地/Users/zhangsan/opt目录挂在到容器的/opt目录. 登陆容器,

    docker exec -it mysql_test_volume /bin/bash
    echo Hello,World  >> index.html
    exit
    

    此时本地的/Users/zhangsan/opt目录就会出现刚才创建index.html.

    反之,如果在本地新增文件index2.html,容器内也会出现这个文件.

    使用bind mount需要注意以下几点:

    • host路径必须为全路径,否则回和volume混淆
    • 如果host目录不存在,docker会自动创建该目录
    • 如果容器目录不存在,docker会自动创建该目录
    • 如果容器目录已有数据,那么docker会将其覆盖掉

    就上面那个场景,如果使用了 bind mount,此时只需要新起一个5.6版本的容器,将目录mount到新地址即可.

    docker run  -v /Users/zhangsan/opt:/opt --name mysql_test_volume -d -e MYSQL_ROOT_PASSWORD=123456  -p 3306:3306 mysql:5.6
    

    由于bind mount本质是个共享文件夹,因而依赖于系统文件系统,不同系统间无法移植,

    windowsNTFS文件系统就无法与linux常用的ext3/4兼容,windows目录为\Users\zhangsan\...格式,
    ext4文件系统目录路径为/usr/...

    volume

    volume是容器上的一个或者多个目录,此目录可以绕过文件系统,与宿主机上的某目录绑定.

    volume于容器化初始化之时即会创建,可以在不同host上移植,卷中的数据会在build image期间完成复制.

    • 数据卷可以在容器之间共享和重用
    • 对数据卷的更改是直接进行的
    • 更新镜像时,不包括对数据卷的更改
    • 即使删除容器本身,数据卷也会保持

    使用docker volume create volume_name来创建一个卷

    docker volume create test
    

    test挂在到容器上

    docker run  -v test:/opt --name mysql_test_volume -d -e MYSQL_ROOT_PASSWORD=123456  -p 3306:3306 mysql:5.6
    

    查看所有卷,使用

    docker volume ls
    

    查看一个卷信息,使用

    docker volume inspect volume_name
    
    docker_volume.png

    删除未使用的卷

    docker volume prune
    

    删除一个卷

    docker volume rm volume_name
    

    bind mount不同的是,

    • 如果volume是空的而容器中的目录有内容,那么docker会将container目录中的内容拷贝到volume中
    • 但是如果volume中已经有内容,则会将container中的目录覆盖
    • Mac系统的docker Desktop实际上是构建在虚拟机上的,其volume在虚拟机的var/lib/docker/volume中,本机上不存在这个路径.

    volume迁移

    最2的方式,登陆host/var/lib/docker/volume目录找到对应的volume,打包带走,在新hostvolume中解压.
    上面部分提到过volume的特点,可以利用这点来进行迁移,假设有一个卷test需要迁移,步骤如下
    1.下载一个镜像,越小越好,比如(alpine)
    2.通过这个镜像创建容器A,挂在test,由于容器内容为空,test中的数据会被复制到容器目录中
    3.打包这个容器A打包成镜像image-A,push或者本地快照
    4.新机器上新建同名volume,然后pull或者import镜像image-A
    5.通过镜像image-A启动容器B,挂载卷test,由于test是空的而容器目录有内容,docker会将container目录中的内容拷贝到volume中.
    6.删除镜像image-A,容器A,容器B,由于数据卷不会被删除,因而就完成了迁移,可以给新的容器使用.
    这样volume就随着容器迁移到新的host上了

    相关文章

      网友评论

        本文标题:docker卷、持久化和迁移

        本文链接:https://www.haomeiwen.com/subject/xfhstltx.html