Docker学习笔记(三)

笔者在上篇学习docker的笔记中学习理解并归纳了容器命令,镜像原理以及镜像commit。在这篇笔记中,笔者将会学习记录容器数据卷的原理以及命令。Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统。

容器数据卷

Docker将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的。容器之间希望有可能共享数据。Docker容器产生的数据,如果不通过Docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据就没有了。为了能保存数据,在Docker中,我们使用了卷。我们可以用Redis里面的rdb和aof文件来形容容器数据卷,容器数据卷就类似于Docker中的rdb和aof文件,主要用来数据共享以及数据持久化操作。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:

卷的设计目的是数据的持久化,完全独立于容器的生存周期,因此Docker不会再容器删除时删除其挂载的数据卷。

那么容器数据卷有什么特点呢?

  1. 数据卷可以在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期会一直持续到没有容器使用它为止
  5. 它可以使容器持久化
  6. 容器间的继承以及共享数据

如何去添加容器卷呢?

有两种方式:

  1. 直接命令添加
  2. DockerFile添加

命令docker run -it -v/宿主机绝对路径目录:/容器内目录 镜像名
v是卷的英文缩写。
在这里插入图片描述
可以看到文件根目录下的所有东西,并且没有我们想要的myDataVolume,我们可以待会儿新建一个,那么这个myDataVolume就是我们宿主机的绝对路径目录。那么容器内目录就是dataVolumeContainer。
在这里插入图片描述
我们先登录ubuntu镜像,可以看到,在文件根目录下并不能找到dataVolumeContainer。

$ docker run -it -v /myDataVolume:/dataVolumeContainer ubuntu

那么我们输入该命令,相当于插一个活动硬盘实现容器和主机之间数据共享。
在这里插入图片描述
可以看到生成了06a26ca52a24,这个是我们的容器。那么我们去根目录下去搜索,可以发现myDataVolume已创建成功。
在这里插入图片描述
在这里插入图片描述
我们可以使用如下命令查看其中内容。

$ ls -d /myDataVolume

在这里插入图片描述
此时,我们可以看到容器和主机之间的对接。
我们首先查看是否挂载成功,我们可以再启动一个终端来验证。

在这里插入图片描述
我们可以看到已经成功绑定。RW是读写的意思,我们现在可以对其进行读写操作。

那么容器和宿主机之间数据共享又是怎么样的呢?

在这里插入图片描述
我们先在/myDataVolume中主机建一个新文件。那么接下来,我们到容器中查看,发现容器中已经存在了这些数据。
在这里插入图片描述
那么我们修改一下host.txt这个文件,笔者发现docker的ubuntu中并没有安装vi和vim的包,因此笔者使用如下命令进行下载和更新。
在这里插入图片描述

apt update

apt-get install -y vim

下载完成后,我们就可以使用vi命令了。输入以下命令

$vi host.txt

进入编辑页面
在里面输入container update 01是可以的,按esc :wq保存退出。
然后我们再touch container.txt
在这里插入图片描述
在容器内修改了主机的文件,那么我再到主机去查看文件。
在这里插入图片描述
可以看到,container update 01可以被读取到。

容器停止退出后,主机修改后数据是否同步?

我们先用exit退出停止容器,并查看当前运行的容器,虽然容器停止了,但是主机还仍在运行。
在这里插入图片描述
我们创建一个新的文件host02,并对container.txt中的内容进行编辑。
在这里插入图片描述
那么我主机上有了个host02,现在启动容器能不能进行同步?

首先,我们先使用docker ps -l命令查看上一次运行的容器ID。
在这里插入图片描述
我们可以看到尾号为f411的就是我们上一次运行的容器。

$ docker start 9f1e1960f411

我们启动容器后,用docker ps查看一下。
在这里插入图片描述
可以看到这个容器就是我们上一次启动的容器,用attach命令进入容器。
在这里插入图片描述
再使用cd命令,在其dataVolumeContainer目录下能看到host02.txt
在这里插入图片描述
在这里插入图片描述

可以看到,即使是文件中的数据也与主机同步了。因此,数据之间的同步拉取就此实现。容器停止退出后,主机修改后数据完全同步。

命令(带权限)

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

以之前的示例为例子,我们可以输入命令

$ docker run -it -v /myDataVolume:/dataVolumeContainer:ro

在这里插入图片描述
我们先回到上一层,将myDataVolume删光。然后我们去容器内输入命令ll看一下情况。
在这里插入图片描述
可以看到,里面的总量为0。再次查询容器目录,发现文件夹并没有删掉
在这里插入图片描述
现在我们停止并退出容器。我们输入命令
在这里插入图片描述
可以看到我们又进入一个容器,输入ll,并且进入dataVolumeContainer,发现只有这两个文件。
在这里插入图片描述
那么我们进入到主机
在这里插入图片描述
可以看到,也只有这两个文件。那么我们重复之前的步骤创建host文件。我们使用vim命令往host.txt中加入host update。
在这里插入图片描述
我们可以看到主机里有文件,且里面有host update。此时,我们去容器内查看。
在这里插入图片描述
此时已经存在了host.txt以及它的内容,但是我们使用touch container.txt命令时会发现不能写操作,因为它是一个只读文件。并且通过vi/vim不能对其进行修改。只允许主机单向修改。
在这里插入图片描述

Docker file添加

类似于java中的 Hello.java ------- Hello.class
Docker中的 images --------- DockerFile

首先,登录根目录下新建mydocker文件夹并进入。
在这里插入图片描述
输入mkdir /docker建立一个目录,然后用cd命令打开它。
可在Dockerfile中使用VOLUME指令来给镜像添加一个或者多个数据卷。

VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]

说明:由于可移植和分享考虑,用-v主机目录:容器目录这种方法不能够直接在Dockerfile中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有宿主机上都存在这样的特定目录。
在这里插入图片描述
用vim打开文档,输入图中命令,并且保存文档。

输入以下命令去创建文档

$ docker build -f /mydocker/Dockerfile -t cccc/ubuntu .

在这里插入图片描述
我们成功构建了一个镜像。
在这里插入图片描述
可以看到我们的镜像创建成功了,那我们直接进行运行。
在这里插入图片描述
我们运行一下,会发现里面已经有dataVolumeContainer1和dataVolumeContainer2了。

那么通过上述步骤以后,容器内的卷目录地址对应的主机目录地址在哪?

在这里插入图片描述
用cd命令进入/dataVolumeContainer1的目录,再创建一个container1.txt的文档。那么我们在容器内建了,我们去哪找主机目录呢呢?

新开一个终端,查询正在运行的容器,并且用inspect去查看内部信息
在这里插入图片描述

在这里插入图片描述
可以看到这两个容器的RW,也就是读写都是True。
而source后面显示的一长串则代表本地机器宿主机上的。那么我们再打开一个终端。
在这里插入图片描述
用cd打开这一长串的地址以后,用ll遍历里面的东西,可以发现这个container1.txt就在里面,这就实现了宿主机到容器,容器到宿主机之间的共享。
在这里插入图片描述
我们touch host.txt再到容器中去寻找。
在这里插入图片描述
在这里插入图片描述
此时,我们可以发现主机和容器都包含这两个文件。
如果遇到Docker挂载主机目录Docker访问出现cannot open directory .:Permission denied这个问题时。
解决办法:在挂载目录后多加一个–privileged=true参数即可。

数据卷容器

命名的容器挂载数据卷。其他容器通过挂载这个(父容器)实现数据共享,挂在数据卷的容器,称之为数据卷容器。

我们以我们上一步新建的镜像cccc/ubuntu为模板并运行容器dc01/dc02/dc03。

重复之前的步骤,我们在dataVolumeContainer2中创建一个dc01_add.txt文档
在这里插入图片描述
此时我们使用ctrl + P + Q 退出,我们可以看到dc01正在运行着,那么我们的父容器就准备好了。
在这里插入图片描述
接下来我们写dc02和dc03继承它。
在这里插入图片描述
在这里插入图片描述
我们可以发现在dataVolumeContainer2中也有dc01_add.txt
在这里插入图片描述
建立一个dc02_add.txt然后退出。
那么我们在3之中进行查看。
在这里插入图片描述
在这里插入图片描述
可以看到这里已经有dc01和dc02了,那么与之前一样,我们touch dc03_add.txt然后退出。
在这里插入图片描述
我们用ps命令看一下,发现这三个都在运行。那么3中的东西会不会影响1和2呢?

在这里插入图片描述
进去以后我们可以发现,容器卷达到了继承和共享传递的目的,父到子,子到父都能互相传递。

那么我们删除dc01后,doc02修改后dc03可否继续访问?
在这里插入图片描述
进入dc02,并在里面创建一个dc02_update.txt文档。那么我们之前用的是2和3继承1,我们可以发现实际上2并没有受到影响,那么3也不会受到影响。那么我现在在2上面修改了,在3上面会有什么影响吗。

在这里插入图片描述
我们可以看到,存在dc02_update.txt,因为数据共享是一直存在的。我们可以新建dc04继承dc03后再删除dc03,dc04依旧有这些信息。所以容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值