简单的docker学习 第6章 数据持久化

第6章 数据持久化

在容器层的 UnionFS(联合文件系统)中对文件/目录的任何修改,无论是手工修改还是容器在运行过程中的修改,在该容器丢失或被删除后这些修改将全部丢失。即这些修改是无法保存下来的。若要保存下来这些修改,通常有两种方式:

  • 定制镜像持久化:将这个修改过的容器生成一个新的镜像,让这些修改变为只读的镜像

  • 数据卷持久化:将这些修改通过数据卷同步到宿主机

6.1 定制镜像持久化

6.1.1 需求

我们这里要实现的功能是,为 tomcat:10.0 镜像修改其 webapps 目录。原本该目录内容是空的,用户访问 tomcat 页面会报 404,而真正的内容是在 webapps.dist 中。现要将原webapps 目录删除,然后重命名 webapps.dist 目录为 webapps,以使用户可以看到 tomcat页面。

首先先下载tomcat10.0

docker pull tomcat:10.0

image-20240710143029210

6.1.2 实现
  • 运行 tomcat 容器

    首先以分离模式启动 tomcat 容器。

    docker run --name tomcat10 -dp 8081:8080 tomcat:10.0
    

    此时通过浏览器是无法访问到 tomcat 页面的。

    image-20240710143150920

  • 进入容器后删除目录

    通过 docker exec 命令可以进入到容器命令行。可以看到 webapps 目录是空的,而真正需要的内容在 webapps.dist 目录中。

    docker exec -it tomcat10 /bin/bash
    

    image-20240710143312890

    删除 webapps 目录,然后将 webapps.dist 目录重命名为 webapps。

    rm -rf webapps
    mv webapps.dist webapps
    

    image-20240710143422416

    再次刷新访问地址 就可以看见tomcat首页了

    image-20240710143545000

  • 容器生成镜像

    执行 docker commit 命令,以当前运行的容器为范本生成镜像。

    # -a 指定该镜像的作者
    # tomcat10:cusdefine 为新镜像的<repository>:<tag>
    docker commit -m="modify webapps for tomcat10" -a="Jerry" tomcat10 tomcat10:cusdefine
    

    image-20240710143748361

  • 测试新镜像

    docker run --name tomcat10cusdefine -it -dp 9000:8080 tomcat10:cusdefine
    

    访问路径可以直接访问,无需进行修改

    image-20240710144010340

6.2 数据卷持久化

Docker 提供了三种实时同步(宿主机与容器 FS 间数据的同步)方式:

  • 数据卷(生产常用)

  • Bind mounts(绑定挂载)

  • tmpfs(临时文件系统)

6.2.1 数据卷概述
  • 数据卷简介

    数据卷是宿主机中的一个特殊的文件/目录,这个文件/目录与容器中的另一个文件/目录进行了直接关联,在任何一端对文件/目录的写操作,在另一端都会同时发生相应变化。

    在宿主中的这个文件/目录就称为数据卷,而容器中的这个关联文件/目录则称为该数据卷在该容器中的挂载点。

    数据卷的设计目的就是为了实现数据持久化,其完全独立于容器的生命周期,属于宿主机文件系统,但不属于 UnionFS。因此,容器被删除时,不会删除其挂载的数据卷

  • 数据卷的特性

    数据卷具有如下明显特性

    • 数据卷在容器启动时初始化,如果容器启动后容器本身已经包含了数据,那么,这些数据会在容器启动后直接出现在数据卷中,反之亦然

    • 可以对数据卷或挂载点中的内容直接修改,修改后对方立即可看到

    • 数据卷会一直存在,即使挂载数据卷的容器已经被删除

    • 数据卷可以在容器之间共享和重用

6.2.2 创建读写数据卷 run -v

读写数据卷指的是容器对挂载点具有读写权限。

  • 命令

    数据卷是在使用 docker run 启动容器时指定的,其语法格式为:

    docker run –it –v /宿主机目录绝对路径:/容器内目录绝对路径 镜像
    

    注:无论是宿主机中的数据卷还是容器中的挂载点,如果指定的目录不存在,那么 docker引擎都会自动创建。即使是多级目录不存在。

  • 需求

    在宿主机中的/root/host_mount 目录与 ubuntu 容器的/opt/uc_mount 目录间建立关联,即宿主机中的/root/host_mount 目录作为数据卷,而 ubuntu 容器的/opt/uc_mount 目录作为挂载点。

  • 创建数据卷

    以交互方式启动一个 ubuntu 容器,同时指定在启动容器时创建数据卷。容器启动完毕后在容器中查看/opt 目录,可以看到新建了一个 uc_mount 子目录。这个就是容器中的挂载点目录。

    docker run --name myubuntu -it -v /root/host_mount:/opt/uc_mount ubuntu:latest /bin/bash
    

    image-20240710150109193

    在容器数据卷目录中生成一个文件,则在宿主机对应/host_mount目录中也生成了对应的文件

    image-20240710150205528

  • 停止容器后的操作

    即使容器停止了,在宿主机中只要修改了数据卷目录内容,在重新启动容器后,该修改过的数据仍会出现在容器中。因为容器是一个 UnionFS,是一个存在于宿主机中的文件系统,无论容器是否运行,该 FS 都是存在的。通过 exit 退出并停止容器。

    image-20240710150511061

    修改宿主机文件内容

    image-20240710150549775

    重启容器,观察文件已经发生了变化

    docker start myubuntu
    docker exec -it myubuntu /bin/bash
    

    image-20240710150800530

  • 查看数据卷详情

    通过 docker inspect [容器] 命令可以查看到当前容器中挂载点与数据卷的绑定关系。

    # RW标识读写权限
    docker inspect myubuntu
    

    image-20240710151001662

    这里给出了数据卷 Source 与挂载点 Destination 的绑定关系,且容器对挂载点的默认操作权限是 RW 读写的。

6.2.3 创建只读数据卷 ro

只读数据卷,指的是容器对挂载点的操作权限是只读的。宿主机对数据卷的操作权限始终是读写的。有些情况下,为了防止容器在运行过程中对文件产生修改,就需要创建只读数据卷。

  • 命令

    该命令仅比之前的命令仅多了:ro【readonly】,具体语法如下:

    docker run –it –v /宿主机目录绝对路径:/容器内目录绝对路径:ro 镜像
    
  • 创建数据卷

    以交互方式启动一个 ubuntu 容器,同时指定在启动容器时创建只读数据卷

    docker run --name myubuntu01 -it -v /root/host_mount:/opt/uc_mount:ro ubuntu:latest /bin/bash
    

    image-20240710151851451

  • 数据卷/挂载点互操作

    上面图中在容器中无法在挂载点进行新增文件,提示没有权限,在宿主机修改aaa.xxx文件,在容器中可以发现文件已经被修改

    image-20240710152157831

    image-20240710152227774

  • 查看数据绑定详情

    # 通过 docker inspect [容器] 命令可以查看到该数据卷的只读属性。
    docker inspect myubuntu01
    

    image-20240710152426300

6.2.4 数据卷共享 volumes-from

当一个容器与另一个容器使用相同的数据卷时,就称这两个容器实现了“数据卷共享”。

  • 数据卷容器

    数据卷容器是实现数据卷共享的一种非常有效的方案。当一个容器 C 启动运行时创建并挂载了数据卷,若其它容器也需要共享该容器 C 挂载的数据卷,这些容器只需在 docker run 启动时通过 --volumes-from [容器 C] 选项即可实现数据卷共享。此时容器 C 就称为数据卷容器。

    注意:如果 --volumes-from 后面的容器挂掉,其余引用此容器卷的容器也会受到影响,无法使用共享数据卷

  • 需求

    myubuntu2 容器要共享前面的 myubuntu 容器的数据卷,即宿主机中/root/host_mount为数据卷目录,而这两个容器的挂载点目录都是/opt/uc_mount。

  • 进入 myubuntu 容器

    通过 docker exec 命令进入 myubuntu 容器后,进入挂载点目录/opt/uc_mount

    docker exec -it myubuntu
    

    image-20240710153546659

  • 创建并运行 myubuntu2 容器

    这里在创建并运行 myubuntu2 容器时,使用–volumes-from 指定该容器要共享 myubuntu的数据卷,即指定 myubuntu 容器为数据卷容器。此时可以发现,myubuntu2 容器中也同样出现了挂载点目录/opt/uc_mount。

    docker run --name myubuntu2 --volumes-from myubuntu -it ubuntu:latest /bin/bash
    

    image-20240710153843132

  • 数据卷共享操作

    在myubuntu2中修改文件内容,在myubuntu中查看也进行了修改

    image-20240710154024413

    image-20240710154047591

6.3 Dockerfile 持久化

Dockerfile 持久化,其实就是通过使用 Dockerfile 的 VOLUME 指令指定数据卷方式实现的持久化。

6.3.1 VOLUME 指令

VOLUME 指令可以在容器中创建可以挂载数据卷的挂载点。其参数可以是字符串数组,也可以是使用空格隔开的多个纯字符串。

例如,VOLUME ["/var/www", "/etc/apache"]VOLUME /var/www /etc/apache

6.3.2 持久化实现
  • 创建 Dockerfile

    在/root 目录中 mkdir 一个目录,例如 vols,然后在其中新建 Dockerfile,内容如下。这里指定/opt/xxx 与/opt/ooo 为容器端的挂载点。

    FROM centos:7
    # xxx以及ooo都是容器的挂载点
    VOLUME /opt/xxx /opt/ooo
    CMD /bin/bash
    
  • 构建镜像 build

    # 使用 Dockerfile 构建镜像 volscon:latest
    docker build -t volscon:latest .
    

    image-20240710154555132

  • 运行新建镜像

    # 以交互方式运行新建镜像
    docker run --name myvols -it volscon
    

    image-20240710154828207

  • 查看宿主机端目录

    # Ctrl + P + Q 退出容器后,使用 docker inspect 查看当前容器中的挂载点目录到底与宿主机中的哪个数据卷对应
    docker inspect myvols
    

    image-20240710154946647

  • 验证

    在容器端首先进入/opt/xxx 目录,并在其中新建一个文件 hello.log。

    docker exec -it myvols /bin/bash
    cd /opt/xxx
    echo "hello world" > hello.log
    

    image-20240710155231610

    在宿主机端,从 docker inspcet 命令中找到/opt/xxx 目录对应的数据卷 Source 目录,首先进入到该目录,然后就可以查看到对应的 hello.log 文件了。说明数据卷设置成功,可以实现从容器到数据卷的持久化了。

    image-20240710155355664

    在宿主机端修改文件内容,在容器端同样也是可以看到的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值