Dokcer 容器基础篇(二)

Dokcer 容器基础篇(一)

接收上面的基础篇一写的

Docker 镜像

什么是镜像

镜像 Image 是一种轻量级, 可执行的独立软件包, 用来打包软件运行环境和基于运行环境开发的软件. 它包含运行某个软件所需的所有内容, 包括代码, 运行时, 库, 环境变量和配置文件

联合文件系统 UnionFS

Union 文件系统 (UnionFS) 是一种分层, 轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下 (unite several directories into a single virtual filesystem)
Union 文件系统是 Docker 镜像的基础. 镜像可以通过分层来进行继承,基于基础镜像 (没有父镜像), 可以制作各种具体的应用镜像

特性:

一次同时加载多个文件, 但从外面看起来, 只能看到一个文件系统, 联合加载会把各层文件系统叠加, 这样最后的文件系统会包含所有底层的文件和目录

Docker 中使用的 AUFS(AnotherUnionFS)就是一种 Union FS。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。
Docker 目前支持的 Union 文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。

Docker 镜像加载原理

Docker 镜像实际上是由一层一层的文件系统组成, 这种层级的文件系统 UnionFS.

bootfs (boot file system) 主要包含 bootloader 和 kernel
bootloader 主要是引导加载 kernel, Linux 刚启动时回家再 bootfs 文件系统, 在 Docker 镜像的最底层是 bootfs, 包含 boot 加载器和内核
当 boot 加载完成之后, 整个内核就都在内存之中, 此时内存的使用权已经由 bootfs 转交给内核, 系统会卸载 bootfs
rootfs (root file system), 在 bootfs 智商, 包含的就是经典 Linux 系统中的 /dev, /proc, /bin 等标准目录和文件

镜像分层

docker pull 为例, 下载过程可以看到 docker 镜像好像是一层一层在下载

以 tomcat 为例, docker pull 下来的镜像文件有 400 MB, 为何文件如此之大?
答: “镜像分层”, kernel -> centOS -> jdk8 -> tomcat, 虽然我们只是用到了最后的 tomcat, 但是所有之前的都下载了

为什么 Docker 镜像是分层结构?

共享资源

比如: 多个镜像都从相同的 base 镜像构建而来, 那么宿主机只需要在磁盘上保存一份 base 镜像. 同时内存中也只需加载一份 base 镜像, 就可以为所有容器服务了. 而且镜像的每一层都可以被共享

镜像有什么特点?

特点:

Docker 镜像都是只读的
当容器启动时, 一个新的可写层被加载安东镜像的顶部
这一层通常被称作”容器层”, “容器层”之下被叫做”镜像层”

Docker 镜像操作补充

$ docker commit

提交容器副本使之成为一个新的镜像

$ docker commit -m="message" -a="author" <container_id> target_name:[tag_name]

Docker 容器数据卷

什么是 Docker 容器数据卷

将运用与运行的环境打包成容器运行, 运行可以伴随着容器, 但是我们希望数据持久化
容器之间可以会有数据共享的需要 (容器间继承 + 共享数据)

Docker 容器产生的数据, 如果不 docker commit 那么容器删除后, 数据也就丢失了

类似于 Redis 里的 RDB 和 AOF

特点:

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

数据卷

数据卷是一个可供一个或多个容器使用的特殊目录, 它绕过 UFS, 可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 卷会一直存在,直到没有容器使用
    数据卷的使用,类似于 Linux 下对目录或文件进行 mount

创建一个数据卷

1. 直接命令添加

添加数据卷命令

在用 docker run 命令的时候, 使用 -v (volume 缩写) 标记来创建一个数据卷并挂载到容器里. 在一次 run 中多次使用可以挂载多个数据卷

docker run -it -v /宿主机绝对路径:/容器内目录 <image_name>

# eg:  (目录没有会自动创建)
docker run -it -v /mydataVolume:/containerDataVolume centos

查看数据卷是否挂载成功

docker inspect centos

在 Volumes key 中会看到挂载的文件夹, 在 HostConfig 中的 Binds 看到二者相互绑定, 那么成功.

容器和宿主机之间数据共享
在容器中修改文件内容, 宿主机中可以发现文件内容发生改变. “可读可写”

注意:如果是centos7上安装的docker,其默认容器中的containerDataVolume是不能进行写操作的。是因为CentOS7中的安全模块SELinux把权限禁掉了。
解决办法:

  1. 在运行容器的时候,给容器加特权,及加上 --privileged=true 参数。使用该参数,容器内的root拥有真正的root权限.否则,容器内的root只是外部的一个普通用户权限
    docker run -it --privileged=true -v /mydataVolume:/containerDataVolume centos
  2. 临时关闭SELinux:setenforce 0
  3. 添加SELinux规则,改变要挂载的目录的安全性文本。参考这个

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

文件操作权限

$ docker run -it -v /宿主机绝对路径:/容器内目录:权限 <image_name>

# eg:
docker run -it  --privileged=true -v  /mydataVolume:/containerDataVolume:ro  centos

ro - Read Only, 只读

在 container 中 执行 touch container.txt 会返回错误信息

2. 使用 Dockerfile 添加

Dockerfile 会在下一章讲解

  1. 在宿主机目录下创建mydocker目录,并进入到该目录下
  2. 在改目录下创建Dockerfile文件,touch Dockerfile
  3. 编写Dockerfile文件
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumerContainer2"]
CMD echo ">>> finish, success...."
CMD /bin/bash

说明:
出于可移植性和分享的考虑,用-v 主机目录:容器目录这种方法不能直接在Dockerfile中实现
由于宿主机目录是依赖于特定宿主机的,并不能保证在所有的宿主机上都存在这样的特定目录。

  1. build后生成镜像
# 生成名称为mycentos/centos 的镜像
docker build -f /mydocker/Dockerfile -t mycentos/centos .
  1. 查看镜像
    docker imgaes

  2. 运行镜像
    docker run -it mycentos/centos /bin/bash

我们发现容器中已经存在了我们创建的两个数据卷

  1. 查看主机对应默认地址
    docker inspect mycentos/centos

可以查看到对应的绑定目录

数据卷容器

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

容器间数据的传递共享

容器间传递共享(--volumes-from)

1. 先启动一个父容器dco1

docker run -it -d  --name dc01 mycentos/centos

在容器中的dataVolumeContainer1/目录下创建一个dc_add.txt文件

echo 'this is parent container dc01' >> dc01_add.txt

2. 分别创建dc02,dc03,继承自dc01

先创建dc02

docker run -it -d --volumes-from dc01 --name dc02 mycentos/centos

进入到dc02容器中dataVolumeContainer1/目录查看,是否存在dc01_add.txt文件??

答案:是

然后在这个目录下再创建dc02_add.txt

echo 'this is dc02 container' >> dc02_add.txt

再创建dc03
docker run -it -d --volumes-from dc01 --name dc03 mycentos/centos

发现目录下dc01_add.txt和dc02_add.txt文件都存在

在该目录下创建dc_03.txt

echo 'this is dc03 container' > dc03_add.txt

3. 回到dc01,可以看到dc01也有了dc02_add.txt和dc03_add.txt文件

4. 删除父容器dc01,dc02修改后dc03可否访问??
可以

5. 删除dc02后dc03可否访问??
可以

结论:

容器之间配置信息的传递,数据卷的生周期一直持续到没有容器使用它为止。

Dockerfile解析

利用数据卷容器来备份, 恢复, 迁移数据卷

摘选自: Docker - 从入门到实践 Gitbook

可以利用数据卷对其中的数据进行进行备份, 恢复和迁移.

posted @ 2020-10-06 23:24  刘翊扬  阅读(172)  评论(0编辑  收藏  举报