通过网盘分享的文件:MD文档笔记
链接: https://pan.baidu.com/s/1ao2wfyLEdN50YmIqdzfGYQ?pwd=5w5z 提取码: 5w5z
–来自百度网盘超级会员v6的分享

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

若要保存下来这些修改通常有以下方式

  • 定制镜像持久化

    将这个修改过的容器生成一个新的镜像,让这些修改变为只读的镜像

    应用场景

    • 对 UnionFS 产生一次性变化,且这种变化易于持久化为镜像

    • 不适合变更非常频繁的实时性场景

  • 数据卷持久化

    将这些修改通过数据卷同步到宿主机

    • 数据卷属于宿主机文件系统,与 UnionFS 是挂载关系,与容器挂载点是硬链接关系.容器的存在与否与数据卷没有关系
    • 数据卷持久化可以做到对容器变更的实时性持久化,不会出现数据丢失的情况
  • Dockerfile持久化

    理解 docker run –v 方式与 Dockerfile 的VOLUME 指令方式指定数据卷的区别

    • docker run –v 方式是针对已经存在的镜像的,而 Dockerfile 的VOLUME 指令方式是针对准备创建的镜像的

    • docker run –v 方式可以指定宿主机中的数据卷目录,而 Dockerfile 的VOLUME 指令方式无法指定宿主机中的数据卷目录,其是 Docker Daemon 自动分配的

所以对于用户来说通过 docker run –v 方式来指定数据卷会更为清晰明了些

一.定制镜像持久化

1.需求

这里要实现的功能是为 tomcat:10.0 镜像修改其 webapps 目录

这是因为新版本的tomcat目录结构发生了变化,webapps 目录变成了空目录,而原先的webapps目录中的内容放到了webapps.dist 目录中,因此用户访问tomcat 页面会报 404

现要将原 webapps 目录删除,然后重命名 webapps.dist 目录为 webapps,以使用户可以看到 tomcat页面

2.实现

(1).运行 tomcat 容器

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

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

在这里插入图片描述

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

http://192.168.1.11:8081/

在这里插入图片描述

(2).进入容器后删除目录

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

docker exec -it mytomcat /bin/bash

在这里插入图片描述

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

rm -rf webapps/

mv webapps.dist webapps

在这里插入图片描述

此时刷新浏览器就可以看到 tomcat 页面了

在这里插入图片描述

(3).容器生成镜像

重新开启会话或者"CTRL+P+Q"退出容器

执行 docker commit 命令,以当前运行的容器为模版生成镜像

  • -m 指定本次提交的日志

  • tomcat10:own 为新镜像的<repository>:<tag>此时可以看到已经生成

docker commit -m="modify webapps" mytomcat tomcat10.0:own

在这里插入图片描述

(4).测试新镜像

docker run --name owntomcat -dp 9000:8080 tomcat10.0:own

在这里插入图片描述

通过浏览器可以直接访问到 tomcat 页面

在这里插入图片描述

二.数据卷持久化

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

  1. 数据卷
  2. Bind mounts(绑定挂载)
  3. tmpfs(临时文件系统)

1.数据卷概述

(1).Docker的理念

将应用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了

但是我们对数据的要求希望是持久化的、容器之间希望有可能共享数据

为了能保存数据在docker中我们使用数据卷

(2).什么是数据卷

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

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

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

因此容器被删除时不会删除其挂载的数据卷

(3).数据卷的特性

数据卷具有如下明显特性

  • 数据卷在容器启动时初始化

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

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

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

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

(4).容器数据卷能做什么

  • 容器数据的持久化

  • 容器之间继承和共享数据

2.创建数据卷

2.1.创建只读数据卷

2.1.1.只读数据卷简介

只读数据卷指的是容器对挂载点的操作权限是只读的,宿主机对数据卷的操作权限始终是读写的

有些情况下为了防止容器在运行过程中对文件产生修改就需要创建只读数据卷

具体语法如下

docker run –it –v /宿主机目录绝对路径:/容器内目录绝对路径:ro  镜像
2.1.2.使用示例
(1).创建数据卷

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

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

在这里插入图片描述

(2).数据卷/挂载点互操作

在容器中修改挂载点中的文件,系统会给出只读文件系统的提示,说明容器对数据卷是只读的

cd /opt/uc_mount/

echo "hello world" >> hello.log

在这里插入图片描述

宿主机中对数据卷文件的修改是成功的

CTRL+P+Q退出容器

cd /home/host_mount/

echo "hello world" >> hello.log

在这里插入图片描述

在容器中同样也是可以看到宿主机中的修改的

docker exec -it myubuntu ls -l /opt/uc_mount

在这里插入图片描述

(3).查看数据详情

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

docker inspect myubuntu

在这里插入图片描述

2.2.创建读写数据卷

2.2.1.读写数据卷简介

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

数据卷是在使用 docker run 启动容器时指定的

其语法格式为

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

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

2.2.2.读写数据卷示例

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

(1).创建数据卷

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

容器启动完毕后在容器中查看/opt 目录,可以看到新建了一个 uc_mount 子目录,这个就是容器中的挂载点目录

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

ls -l /opt

在这里插入图片描述

再打开一个会话窗口,查看宿主机的/root 目录,可以看到新建了一个 host_mount 目录,这个就是数据卷目录

在这里插入图片描述

(2).数据卷/挂载点互操作

宿主机数据卷目录与容器挂载点目录中进行文件修改互操作,修改完毕后,对方都可立即看到修改

在宿主机数据卷目录中创建一个新的文件

echo "hello world" >> /root/host_mount/hello.log

ls -l /root/host_mount/

在这里插入图片描述

在容器中可以查看到该文件出现了

ls -l /opt/uc_mount/

在这里插入图片描述

在容器中对文件内容进行修改

echo "container modify" >> /opt/uc_mount/hello.log

在这里插入图片描述

在宿主机中可以查看到该修改过的文件内容

cat /root/host_mount/hello.log

在这里插入图片描述

(3).停止容器后的操作

即使容器停止了,在宿主机中只要修改了数据卷目录内容,在重新启动容器后,该修改过的数据仍会出现在容器中

因为容器是一个 UnionFS,是一个存在于宿主机中的文件系统,无论容器是否运行,该 FS 都是存在的

通过exit 退出并停止容器

exit

在这里插入图片描述

在宿主机数据卷目录修改文件

echo "host modify" >> /root/host_mount/hello.log

在这里插入图片描述

重新启动并进入容器,查看容器中挂载点目录中的文件内容,发现已发生改变

docker start myubuntu

docker exec -it myubuntu /bin/bash

cat /opt/uc_mount/hello.log

在这里插入图片描述

(4).查看数据卷详情

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

docker inspect myubuntu

在这里插入图片描述

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

3.数据卷容器

3.1.什么是数据卷容器

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

数据卷容器是实现数据卷共享的一种非常有效的方案

如果有一些持续更新的数据需要在容器之间共享最好创建数据卷容器

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

如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除

如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的数据卷

3.2.创建数据卷容器

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

(1).创建容器1的数据卷
docker run --name myubuntu -it -v /root/host_mount:/opt/uc_mount ubuntu:latest /bin/bash

ls -l /opt
# 进入挂载点目录/opt/uc_mount
cd /opt/uc_mount/

在这里插入图片描述

(2).创建容器2

这里在创建并运行myubuntu2 容器时,使用–volumes-from 指定该容器要共享myubuntu的数据卷,即指定myubuntu 容器为数据卷容器

此时可以发现myubuntu2 容器中也同样出现了挂载点目录/opt/uc_mount

# 创建容器
docker run --name myubuntu2 --volumes-from myubuntu -it ubuntu:latest /bin/bash

# 进入目录
cd /opt/uc_mount/

在这里插入图片描述

(3).数据卷共享操作

经过上述操作,myubuntu1 与 myubuntu2 这两个容器实现了数据卷共享

此时无论是在宿主机,还是 myubuntu1 或 myubuntu2 任意容器中挂载点目录中的任意写操作,在另外两方均可同步看到该写操作的结果

下面举例

首先在宿主机数据卷目录中创建一个文件 data.log

echo "你好世界" >> /root/host_mount/data.log

在这里插入图片描述

在 myubuntu1 容器中可以查看到 data.log 文件

然后myubuntu1 容器也修改该文件

# 进入容器,如果是多窗口操作则不需要该步骤
docker exec -it myubuntu /bin/bash
# 查看文件
cat /opt/uc_mount/data.log
# 容器1修改文件
echo "myubuntu1 modify" >> /opt/uc_mount/data.log

在这里插入图片描述

在 myubuntu2 容器中可以查看到 data.log 文件

然后myubuntu2 容器也修改该文件

# 进入容器,如果是多窗口操作则不需要该步骤
docker exec -it myubuntu2 /bin/bash
# 查看文件
cat /opt/uc_mount/data.log
# myubuntu2 容器对文件的修改
echo "myubuntu2 modify" >> /opt/uc_mount/data.log

在这里插入图片描述

在 myubuntu1 容器中可看到

cat /opt/uc_mount/data.log

在这里插入图片描述

在宿主机中可看到

cat /root/host_mount/data.log

在这里插入图片描述

三.DockerFile持久化

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

VOLUME 指令可以在容器中创建可以挂载数据卷的挂载点

其参数可以是字符串数组,也可以是使用空格隔开的多个纯字符串

例如

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

或

VOLUME /var/www /etc/apache

1.创建 Dockerfile

在/root目录中mkdir一个目录vols(例如vols),然后在其中新建 Dockerfile,内容如下

这里指定/opt/xxx 与/opt/ooo 为容器端的挂载点

[root@docker ~]# cd /root
[root@docker ~]# mkdir vols
[root@docker ~]# cd vols/
[root@docker ~]# vim Dockerfile
FROM ubuntu

VOLUME /opt/xxx /opt/ooo 

CMD /bin/bash

在这里插入图片描述

2.构建镜像 build

使用 Dockerfile 构建镜像 volscon:latest

docker build -t volscon .

在这里插入图片描述

3.运行新建镜像

以交互方式运行新建镜像

docker run --name myvols -it volscon

ll /opt/

在这里插入图片描述

4.查看宿主机端目录

重新开启一个会话(Ctrl + P + Q 退出容器后,使用 docker inspect 查看当前容器中的挂载点目录到底与宿主机中的哪个数据卷对应)

docker inspect myvols

在这里插入图片描述

5.验证

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

docker exec -it myvols /bin/bash

cd /opt/xxx

echo "hello world" >> hello.log

在这里插入图片描述

在宿主机端,从 docker inspcet 命令中找到/opt/xxx 目录对应的数据卷Source 目录,首先进入到该目录,然后就可以查看到对应的 hello.log 文件了

说明数据卷设置成功,可以实现从容器到数据卷的持久化了

在这里插入图片描述

cd /root/images/volumes/b0a468e52fe84b0faf6838e7c50dcccc3e9bb8f5a9b7ac8ef372f14f9010658a/_data

cat hello.log

在这里插入图片描述

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

这里不再演示

更多推荐