Docker | 自定义Docker镜像

公众号封面

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏:Docker系列
✨特色专栏: MySQL学习
🥭本文内容: Docker | 自定义Docker镜像
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: 知识库,欢迎大家访问

1.前言

大家好,我是Leo哥🫣🫣🫣,前面我们学习了Docker的安装以及Docker的基本命令。学会了如何去通过Docker进行服务的安装,比如MySQL,Nginx等。那么大家可以思考一个问题,在之前,我们都是通过使用DockerHub官方提供的镜像,那么我们是否可以自定义镜像,对镜像diy呢,答案是当然可以,这篇文章我们就来学习一些前置知识以及自定义我们的镜像。好了,话不多说让我们开始吧😎😎😎。

2.什么是镜像

镜像 (Mirroring)是一种文件存储形式,是冗余的一种类型,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。可以把许多文件做成一个镜像文件,与GHOST等程序放在一个盘里用GHOST等软件打开后,又恢复成许多文件,RAID 1和RAID 10使用的就是镜像。常见的镜像文件格式有ISO、BIN、IMG、TAO、DAO、CIF、FCD。

所谓镜像文件其实和ZIP压缩包类似,它将特定的一系列文件按照一定的格式制作成单一的文件,以方便用户下载和使用,例如一个测试版的操作系统、游戏等。镜像文件不仅具有ZIP压缩包的“合成”功能,它最重要的特点是可以被特定的软件识别并可直接刻录到光盘上。其实通常意义上的镜像文件可以再扩展一下,在镜像文件中可以包含更多的信息。比如说系统文件、引导文件、分区表信息等,这样镜像文件就可以包含一个分区甚至是一块硬盘的所有信息。使用这类镜像文件的经典软件就是Ghost,它同样具备刻录功能,不过它的刻录仅仅是将镜像文件本身保存在光盘上,而通常意义上的刻录软件都可以直接将支持的镜像文件所包含的内容刻录到光盘上。

简单来说,在Docker中镜像就是一个轻量的、独立的软件包。用来打包运行环境和基于运行环境开发的软件。它包含软件运行所需的所有内容(包括代码、运行时、库、环境变量、配置文件)

所有的应用,打包docker镜像,就可以跑起来。

3.Docker镜像加载原理

Docker 镜像是构建 Docker 容器的基础,它是一个轻量级、可执行的独立软件包,包括运行应用所需要的所有内容——代码、运行时、库、环境变量和配置文件。接下来,我将详细介绍 Docker 镜像的加载原理。

3.1 Docker 镜像的分层

Docker 镜像采用了层叠的文件系统,这意味着镜像由一系列只读的层组成。这样做的好处是重用和共享,若干个镜像可以共享相同的层,节省磁盘空间和加速镜像下载。

  • 基础层: 所有镜像的第一层,通常是一个最小化的操作系统环境,如 Ubuntu 或 Alpine。
  • 依赖层: 包含应用程序运行所需的依赖、库文件等。
  • 应用层: 包括应用程序的代码和资源文件。

当你构建一个镜像时,每个指令(如 RUN, COPY, ADD 等)都会在现有镜像层之上创建一个新的层。

3.2 镜像加载过程

实际加载和运行 Docker 镜像的过程包含以下几个关键步骤:

  1. 拉取镜像: 当你使用 docker run 命令运行一个容器时,如果本地没有指定的镜像,Docker 将从 Docker Hub 或其他配置的镜像仓库拉取镜像。
  2. 镜像解压与加载: Docker 会将拉取的镜像文件解压到磁盘上,并按照镜像层的顺序将它们组合起来。
  3. Union File System: Docker 使用 UnionFS 把各层联合成一个统一的文件系统。多个只读层被叠加在一起,最顶部通常是一个可以写入的层,即容器层。
  4. 运行容器: 加载镜像后,Docker 可以在这个统一文件系统的基础上创建并启动一个新容器。
  5. 容器层动态写入: 容器运行后,对文件系统的所有更改都会发生在容器层。这些更改与下面的只读镜像层隔离开来,从而不会影响到基础镜像本身。
  6. 存储和缓存: 镜像层被拉取到本地之后,会被存储在本地的 Docker 宿主机上。当再次运行同样的镜像时,Docker 会使用这些已经存在的层来加速容器的运行。

3.3 优化读取速度和资源利用

Docker 的设计允许多个容器共享同一个基础镜像,这使得部署多个容器更加高效。例如,如果10个容器都基于同一个操作系统镜像,那么在磁盘上只需要有一个该操作系统镜像的副本,各个容器只需创建自己特有的容器层即可。

另外,Union File System 是增量的,这意味着只有当文件层发生改变时才需要额外存储空间。未被修改的部分仍然共享相同的物理存储空间。结合容器层的设计,这提供了高效的文件操作性能,同时确保了容器之间的文件系统隔离。

总体来说,Docker 使用一种分层的方式来管理和加载镜像,这种方法带给了 Docker 镜像和容器之间的高效能力和灵活性。通过缓存,共享层和增量更新。

4. Docker中的分层

下面我们就以 CentOS 发行版的 overlay2 文件系统进行介绍,其实不管是什么发行版,其远离都如出一辙。

overlayer2 官方介绍: https://docs.docker.com/storage/storagedriver/overlayfs-driver/

先来看张图:

image-20231128162209929

从上图中的右边可以看到 OverlayFS 中有三个层级结构:lowerdirupperdirmerged 层。

对应的,使用 docker inspect [container-id] 就可以看到这几个层所在的位置:

"GraphDriver": {"Name": "overlay2","Data": {"LowerDir": "/var/lib/docker/overlay2/45abab78c6fd022d9ce132a0fb995f9e91bc0a807ccc73e2461fce6c9b68b250/root","MergedDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/merged","UpperDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/upper","WorkDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/work"}
},

docker镜像都是只读的,当容器启动时,一个新的可写层被加到镜像的顶部。

这一层就是我们通常说的容器层,容器之下的都叫镜像层

5.自定义镜像

5.1 准备

首先本地准备一个服务jar包,Redis或者MySQL都可以。

5.2 通过容器转镜像

使用以下命令进行转换

docker commit  容器ID 镜像名称:版本号
docker save -o 压缩文件名称  镜像名称:版本号

最后通过以下命令加载一下即可。

docker load -i 压缩文件名称

这样就大功告成了!

其实这样方式我们使用的并不大,我们今天这里只是简单了解一下,后面我们会详细讲解另一种方式dockfile

6.文章参考

  • https://docs.docker.com/engine/install/centos/#install-from-a-package
  • https://docs.docker.com/engine/reference/commandline/cli/

7.总结

以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。

如果你想了解更多关于Leo,可以关注微信公众号-程序员Leo,后面文章会首先同步至公众号。

公众号封面

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux:Network: ARP被动删除的一个情况

今天看到Linux内核里arp代码相关的一个函数,让人想起来很久之前掉进去的一个坑。 说产品的实现里,会存放一个dummy的neighbor(arp记录)在系统里,然后根据这个dummy的记录做一些特殊的处理。 但是当时根本就不知道这个记录的存在,也就无从谈起说要在做设计时考虑它的存在。…

微信小程序实现微信登录

文章目录 涉及到的微信官方文档login.wxml效果login.wxml login.js效果login.jsutil.js 后端(使用django)urls.pyviews.py 流程: 1. wx.getUserProfile() 会调出获取用户微信的页面 2. 当用户点击“允许”后,wx.login() 带着code去…

vue实现海康H5视频插件播放视频的实例,实现取流失败了之后重新获取新的流播放视频

vue实现海康H5视频插件播放视频的实例,实现取流失败了之后重新获取新的流播放视频 h5player是一个基于HTML5的流式网络视频播放器,无需安装浏览器插件即可通过websocket协议向媒体服务取流播放多种格式的音视频流。 首先去海康开发平台,把插…

CopyOnWriteArrayList源码解析

CopyOnWriteArrayList源码解析 文章目录 CopyOnWriteArrayList源码解析一、CopyOnWriteArrayList二、总结 一、CopyOnWriteArrayList 在 JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那么CopyOnWriteArrayL…

【.NET Core】委托(Delegate)应用详解

【.NET Core】委托(Delegate)应用详解 文章目录 【.NET Core】委托(Delegate)应用详解一、概述二、委托(Delegate)定义三、基础委托(Delegate) - 无返回值委托四、基础委托(Delegate) - 有返回值委托五、Mu…

Vue2或者uniapp 中 使用 iframe 嵌入本地 HTML 页面 并 相互通信。

1.使用 iframe 嵌入本地 HTML 页面&#xff08;以pdfjs为例&#xff09; 在 public 文件夹下新建 static 文件夹&#xff0c;然后将 html 文件及相关引用拷贝到 static 文件夹下 uniapp在src下新建hybrid文件 vue 文件完整代码 <template><div class"wrap&q…

java实现简单连点器1

这段代码是使用Java的AWT库来实现模拟鼠标点击的操作。它创建了一个Robot对象&#xff0c;通过该对象可以模拟鼠标和键盘操作。在这段代码中&#xff0c;首先设置了点击位置的坐标&#xff08;x和y&#xff09;&#xff0c;点击间隔时间&#xff08;interval&#xff09;以及点…

顶级数据恢复工具—— 最全的15个数据恢复软件榜单

在这个信息为王的数字时代&#xff0c;关键数据的丢失对个人和企业来说都可能是灾难性的。无论是由于意外删除、硬件故障还是恶意攻击&#xff0c;拥有强大的数据恢复解决方案都是至关重要的。在本综合指南中&#xff0c;我们将探索市场上最好的数据恢复软件&#xff0c;包括顶…

java+python农村集体产权管理系统php+vue

注册、登陆该系统根据操作权限的不同分为管理员和用户两种&#xff0c;新用户在登陆前要进行用户注册&#xff0c;注册完成后方可进行登陆。 本次设计的关键问题处理&#xff0c;主要有如下几点&#xff1a; (1&#xff09;本次开发&#xff0c;采用主流Thinkphp框架进行开发&a…

KernelSHAP vs TreeSHAP

Kernel SHAP和Tree SHAP都用于近似Shapley值。Tree SHAP要快得多。缺点是它只能用于基于树的算法&#xff0c;如随机森林和xgboost。另一方面&#xff0c;Kernel SHAP是模型不可知的(model agnostic)&#xff0c;这意味着它可以与任何机器学习算法一起使用。我们将比较这两种近…

如何把 Oracle 19C RAC+DG加入到ORACLE EM 13C监控

平时见ORACLE 19c rac single dg的部署很多了&#xff0c;ORACLE em 13c 的安装也很多了,但如何把手工部署的oracle 19c rac dg 添加到em 13c 中去&#xff0c;让EM13C 来实现对RACDG的监控&#xff0c;主要是DG的EM13C的监控&#xff0c;还没有看到&#xff0c;大部分都是直接…

AI编译优化技术“loop tiling“、“ordering“、“caching“和“unrolling“

文章目录 概念例子 概念 在计算机科学和编程中&#xff0c;特别是在高性能计算和优化编译器设计领域&#xff0c;“loop tiling”、“ordering”、"caching"和"unrolling"是一些常见的术语&#xff0c;它们涉及到改进程序性能的不同策略。下面分别解释这些…

2023极客大挑战-AGRT战队wp

目录 RE Shiftjmp 点击就送的逆向题 幸运数字 ​编辑 砍树 小黄鸭 flower-or-tea mySelf 是男人就来扎针 听说cpp很难&#xff1f; Easymath 寻找初音未来 Rainbow 浪漫至死不渝 ezandroid Pwn nc_pwntools password ret2text write1 ret2libc ezpwn wr…

力扣23. 合并 K 个升序链表(java,最小堆解法)

Problem: 23. 合并 K 个升序链表 文章目录 题目描述思路解题方法复杂度Code 题目描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 思路 1.对于合并k个有序链表&#xff0c;我们较为容易想…

高翔:《自动驾驶与机器人中的SLAM技术 》-Slam_in_autonomous_driving 编译过程中遇到的问题

使用的环境是ubuntu20.04 问题1.安装g2o没有问题&#xff0c;不过在编译整个项目工程时候报错&#xff1a; ”openmp_mutex.h: 30:10: fatal error: g2o/config.h: No such file or directory“: 解决办法&#xff1a; 只需要将/thirdparty/g2o/build/g2o下的config.h放到/…

shiro整合redis

shiro整合redis 前言&#xff1a;shiro默认的session是存储在jvm内存中的&#xff0c;这样会导致java服务内存占用更大以及一旦服务器宕机或者版本迭代需要重启服务时&#xff0c;缓存中的数据不能恢复&#xff0c;导致用户需要重新登录认证&#xff0c;体验很差。因此利用第三…

C++ STL : std::list,源码面前,了无秘密,大裤衩啥颜色材质给你写的明明白白,哈哈

eat std::list source code list的好处是每次插入或删除一个元素&#xff0c;就配置或释放一个元素空间。因此&#xff0c;list对于空间的运用有绝对的精准&#xff0c;一点也不浪费。而且&#xff0c;对于任何位置的插入和元素移除都永远是常数时间。 可惜了当下有点忙能力欠…

c语言练习12周(15~16)

编写int fun(char s[])函数&#xff0c;返回字串中所有数字累加和 题干编写int fun(char s[])函数&#xff0c;返回字串中所有数字累加和。 若传入串"k2h3yy4x"返回整数9&#xff1b;若传入串"uud9a6f7*"返回整数22 //只填写要求的函数 int fun(cha…

JSON详细教程

&#x1f60a;JSON详细教程 &#x1f6a9;JSON简介☃️JSON语法规则&#x1f50a;JSON和JavaScript对象的区别 ☃️JSON数据类型字符串&#x1f50a;数字&#x1f50a;布尔值&#x1f50a;数组&#x1f50a;对象&#x1f50a;Null ☃️JSON对象&#x1f50a;访问JSON对象的值&a…

堆的应用(堆排序、Top-K问题)

文章目录 1 堆排序2 Top-K问题 1 堆排序 堆排序是一种基于二叉堆&#xff08;通常使用数组实现&#xff09;的排序算法。 它的基本思想是利用堆这种数据结构的性质&#xff0c;通过建立一个堆&#xff08;大堆或小堆&#xff09;&#xff0c;使得堆的根节点是所有节点中的最大值…