当前位置: 首页 > article >正文

【docker集群应用】Docker数据管理与镜像创建

文章目录

  • Docker数据管理
    • 数据卷(Data Volumes)
      • 示例
    • 数据卷容器(Data Volume Containers)
      • 示例
    • 端口映射
    • 容器互联
  • Docker镜像的创建方法
    • 基于现有镜像创建
      • 1.首先启动一个镜像,在容器里做修改
      • 2.然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像
    • 基于本地模板创建
      • 1. 从开源项目(如OPENVZ)下载操作系统模板文件
      • 导入为镜像
    • 3. 基于Dockerfile创建
      • Dockerfile
      • 联合文件系统(UnionFS):
      • 镜像加载原理

Docker数据管理

在 Docker 中,数据管理是一个重要的方面,尤其是在需要持久化数据或在不同容器之间共享数据时。
Docker 提供了两种主要的数据管理方式:数据卷(Data Volumes)和数据卷容器(Data Volume Containers)。

数据卷(Data Volumes)

数据卷是 Docker 中的一个特殊目录,它可以在容器之间共享和重用,并且独立于容器的生命周期。数据卷位于容器文件系统之外,因此即使删除了容器,数据卷中的数据也不会丢失。

示例

我们首先拉取了一个 CentOS 7 的镜像,然后创建了一个容器 web1,并使用 -v 选项将宿主机的 /var/www 目录挂载到容器内的 /data1 目录。

docker pull centos:7
docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash

在容器内部,我们创建了一个文件 abc.txt 并写入了一些内容。由于 /data1 是一个数据卷,这个文件实际上被写入了宿主机的 /var/www 目录中。

echo "this is web1" > /data1/abc.txt
exit

退出容器后,我们可以在宿主机上验证这一点:

cat /var/www/abc.txt

数据卷容器(Data Volume Containers)

数据卷容器是一种特殊类型的容器,它专门用于提供数据卷给其他容器使用。这种方式允许在不同的容器之间共享数据,无需手动管理数据卷的挂载路径。

示例

我们首先创建了一个名为 web2 的数据卷容器,它有两个数据卷:/data1/data2

docker run --name web2 -v /data1 -v /data2 -it centos:7 /bin/bash

web2 容器内部,我们向这两个数据卷中分别写入了文件。

echo "this is web2" > /data1/abc.txt
echo "THIS IS WEB2" > /data2/ABC.txt

然后,我们创建了一个新的容器 web3,并使用 --volumes-from 选项将 web2 容器中的数据卷挂载到 web3 中。这样,web3 就可以访问 web2 中的数据卷了。

docker run -it --volumes-from web2 --name web3 centos:7 /bin/bash

web3 容器内部,我们可以验证是否能够访问到 web2 中的数据卷内容。

cat /data1/abc.txt
cat /data2/ABC.txt

总结

  • 数据卷:提供了在容器和宿主机之间共享数据的机制,且数据独立于容器的生命周期。
  • 数据卷容器:允许在不同的容器之间共享数据,简化了数据管理。

端口映射

端口映射机制允许将容器内的服务暴露给外部网络访问。实质上是将宿主机的端口映射到容器中的指定端口。

  • 端口映射解决了外部访问容器内服务的问题。

示例

  1. 随机映射端口

    docker run -d --name test1 -P nginx
    
    • -P 表示随机选择一个宿主机端口映射到容器的80端口(通常为服务默认端口)。
  2. 指定映射端口

    docker run -d --name test2 -p 43000:80 nginx
    
    • -p 43000:80 表示将宿主机的43000端口映射到容器的80端口。

验证
使用 docker ps -a 查看容器状态及端口映射情况:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                   NAMES
9d3c04f57a68   nginx     "/docker-entrypoint.…"   4 seconds ago    Up 3 seconds    0.0.0.0:43000->80/tcp   test2
b04895f870e5   nginx     "/docker-entrypoint.…"   17 seconds ago   Up 15 seconds   0.0.0.0:49170->80/tcp   test1
  • 可通过浏览器访问:http://宿主机IP:43000http://宿主机IP:49170 来验证服务是否正常。

容器互联

默认情况下,Docker容器重启后其内部IP地址可能会发生变化,导致容器间通信不便。

  • 容器互联则提供了更为便捷且稳定的容器间通信方式,避免了因IP变化带来的困扰。

解决方案
使用容器互联功能,通过容器名称在容器间建立稳定的网络通信隧道。

命令示例

  1. 创建并运行源容器(命名为web1):

    docker run -itd -P --name web1 centos:7 /bin/bash
    
  2. 创建并运行接收容器(命名为web2),并通过 --link 选项指定与web1互联:

    docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash
    
    • --link web1:web1 表示将web1容器的名称及其别名都设置为web1,从而使web2能够识别并与之通信。

测试互联
进入web2容器内部,执行以下命令测试与web1的连通性:

docker exec -it web2 bash
ping web1

若能成功收到回复,则表明两容器间的互联配置正确。

以下是对Docker镜像创建方法的整理,包括基于现有镜像创建、基于本地模板创建以及基于Dockerfile创建三种方式,并详细解释了联合文件系统(UnionFS)、镜像加载原理以及Dockerfile的相关内容。

Docker镜像的创建方法

创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。

基于现有镜像创建

1.首先启动一个镜像,在容器里做修改

例如使用docker run -it centos:7 /bin/bash命令启动一个CentOS 7的容器。

docker create -it centos:7 /bin/bash
docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS    PORTS     NAMES
000550eb36da   centos:7   "/bin/bash"   3 seconds ago   Created             gracious_bassi

2.然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像

docker commit -m "new" -a "centos" 000550eb36da centos:test
##格式:
docker commit -m "new" -a "centos" <CONTAINER_ID> centos:test
##常用选项:
-m 说明信息;
-a 作者信息;
-p 生成过程中停止容器的运行。
docker images
  • 注意事项
    • 使用docker ps -a可以查看所有容器的状态,包括已停止的容器。
    • 提交时,需要提供容器的ID或名称、说明信息、作者信息等。

基于本地模板创建

通过导入操作系统模板文件可以生成镜像,模板可以从 OPENVZ 开源项目下载,下载地址为http://openvz.org/Download/template/precreated

1. 从开源项目(如OPENVZ)下载操作系统模板文件

wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz

导入为镜像

cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test
  • 注意事项
    • 需要确保下载的模板文件是完整的,并且与Docker版本兼容。
    • 导入时,可以为新镜像指定一个标签(tag)。

3. 基于Dockerfile创建

Dockerfile

  • Dockerfile是一个文本文件,包含了构建Docker镜像所需的一系列指令。
  • 每条指令都会创建一个新的镜像层,并且可以被缓存和复用。
  • Dockerfile的结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
  • Dockerfile中的指令可以包括复制文件、安装软件包、设置环境变量等。

详细来说,Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻烦。
除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像。Dockerfile是由多条的指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取Dockerfile 中的指令生成指定镜像。
Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释。

联合文件系统(UnionFS):

我们下载的时候看到的一层层的就是联合文件系统。

  • Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、Overlay2 及 Devicemapper 都是一种 UnionFS。
  • Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
  • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

镜像加载原理

  • Docker镜像由多层文件系统组成,最底层是bootfs,包含bootloader和kernel。
  • 在bootfs之上是rootfs,包含了典型的Linux系统目录和文件。
  • 当创建容器时,Docker会在镜像的最上层添加一个空的read-write层,容器内的所有文件修改都会发生在这一层。

详细来讲,
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。

  • 为什么Docker里的centos大小才200M?
    • Docker中的镜像通常是精简的操作系统,只包含最基本的命令、工具和程序库。
    • 不同的Linux发行版可以共用bootfs,因此它们的镜像大小相对较小。

详细来讲,因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。

  • Docker镜像结构的分层
    • 镜像由多层构成,每一层都是只读的。
    • 容器在镜像的最上面添加了一层可读写层,用于存储容器内的文件修改。
    • 如果删除了容器,其最上面的可读写层也会被删除,但镜像层不会受到影响。
    • 镜像层是不可变的,即使在某一层中添加了一个文件并在下一层中删除它,该文件仍然会保留在镜像中(但在容器中不可见)。

镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。
(1)Dockerfile 中的每个指令都会创建一个新的镜像层;
(2)镜像层将被缓存和复用;
(3)当Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;
(4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效;
(5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了。


http://www.kler.cn/a/419102.html

相关文章:

  • LabVIEW内燃机气道试验台测控系统
  • 【深度学习基础】一篇入门模型评估指标(分类篇)
  • 第144场双周赛:移除石头游戏、两个字符串得切换距离、零数组变换 Ⅲ、最多可收集的水果数目
  • 力扣刷题TOP101:8.BM10 两个链表的第一个公共结点
  • 1、SpringBoo中Mybatis多数据源动态切换
  • pip安装github上的开源软件包
  • Flutter:encrypt插件 AES加密处理
  • 10.请求拦截和响应拦截
  • Rust代写 OCaml代做 Go R语言 SML Haskell Prolog DrRacket Lisp
  • Jackson库--ObjecMapper
  • vue3 与 spring-boot 完成跨域访问
  • Maven java 项目,想执行verify阶段指令,通常需要配置哪些插件呢?
  • YOLOv8-ultralytics-8.2.103部分代码阅读笔记-ops.py
  • Java知识及热点面试题总结(二)
  • 远程桌面协助控制软件 RustDesk v1.3.3 多语言中文版
  • 精准用户获取与私域流量运营:多商户链动 2+1 模式商城小程序的赋能策略
  • Linux内核编译流程(Ubuntu24.04+Linux Kernel 6.8.12)
  • spring boot 调用C#封装的DLL文件中的函数
  • 力扣3372.连接两棵树后最大目标节点数目I
  • 内网使用docker搭建librespeed测速网站
  • 挑战用React封装100个组件【004】
  • UaGateway:实现OPC DA和OPC UA的高效转换
  • FFmpeg一些常用的命令
  • ElasticSearch的学习
  • JAVA中HashMap、TreeMap、LinkedHashMap 的用法与注意事项
  • 简单搭建qiankun的主应用和子应用并且用Docker进行服务器部署