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

server/2024/11/30 4:58:51/

文章目录

  • 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.ppmy.cn/server/146075.html

相关文章

Javaweb关于web.xml的相关配置信息

Javaweb关于web.xml的相关配置信息 初始页面 <!-- 规定加载进入的初始页面--> <welcome-file-list><welcome-file>/login.jsp</welcome-file> </welcome-file-list>配置Servlet <!--配置Servlet--> <servlet><servlet-name&g…

Leetcode 颠倒二进制位

以下是对所提供的代码进行中文解释以及其算法思想分析&#xff1a; 算法思想 这段代码的目标是反转一个32位整数的二进制位。 核心思路是&#xff1a; 逐位提取&#xff1a; 利用位操作从输入整数的最低位开始&#xff0c;逐位提取其二进制位。逐位插入&#xff1a; 将提取到…

深度学习作业九 RNN-SRN-Seq2Seq

目录 1. 实现SRN &#xff08;1&#xff09;使用Numpy &#xff08;2&#xff09;在1的基础上&#xff0c;增加激活函数tanh &#xff08;3&#xff09;使用nn.RNNCell实现 &#xff08;4&#xff09;使用nn.RNN实现 2. 实现“序列到序列” 3. “编码器-解码器”的简单实…

计算机网络:网络安全

7.1、网络安全概述 1、安全包括哪些方面 数据存储安全应用程序安全操作系统安全网络安全物理安全用户安全教育 2、网络安全面临的问题 1&#xff09;截获——从网络上窃听他人的通信内容。 2&#xff09;中断——有意中断他人在网络上的通信。 3&#xff09;篡改——故意…

通过优化html的清洗来提高对网页RAG的效果

html检索的提升&#xff1a;HtmlRAG 之前在现实的工作场景中也做过很多次RAG&#xff0c;不过那会我的做法大多数是对数据进行结构化&#xff0c;例如做成json或者yaml文件存放进数据库里面。比如我现在有一个Word文档需要处理&#xff0c;那我就会按照一级标题&#xff0c;二…

【python】pip不是内部命令解决方法

【python】pip不是内部命令解决方法 原因解决方法 不会配置环境变量的可以卸载python&#xff0c;重新安装&#xff0c;这两天&#xff0c;我会再出一期安装python的教程&#xff0c;希望对你有帮助 原因 通常情况下&#xff0c;出现“pip不是内部命令”的问题&#xff0c;往往…

微信小程序中的WXSS与CSS的关系及使用技巧

微信小程序中的WXSS与CSS的关系及使用技巧 引言 在微信小程序的开发中,样式的设计与实现是构建用户友好界面的关键。微信小程序使用WXSS(WeiXin Style Sheets)作为其样式表语言,WXSS在语法上与CSS非常相似,但也有一些独特的特性。本文将深入探讨WXSS与CSS的关系,介绍WX…

面试小札:JVM虚拟机

1. 定义与基本概念 - JVM&#xff08;Java Virtual Machine&#xff09;即Java虚拟机&#xff0c;是Java程序的运行核心。它是一个虚构出来的计算机&#xff0c;通过在实际的计算机上仿真模拟各种计算机功能来运行Java字节码。字节码是一种中间格式&#xff0c;它使得Java程序能…