Docker镜像的创建 和 Dockerfile

news/2024/5/19 14:53:39

一. Docker 镜像的创建

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

1 基于现有镜像创建

(1)首先启动一个镜像,在容器里做修改docker run -it --name web3 centos:7 /bin/bash     #启动容器​yum install -y epel-release  #安装epel源yum install -y nginx         #安装nginxyum install net-tools        #安装tools工具nginx                        #启动服务netstat -natp |grep 80       #查看端口是否开启​docker ps -a   #查看容器ID​(2)然后将修改后的容器提交为新的镜像,需要使用该容器的ID号创建新镜像docker commit -m "new nginx" -a "xxxx" 容器id centos:test#常用选项:-m 指定说明信息;-a 指定作者信息;-p 生成过程中停止容器的运行。
8237bc36daba  原容器ID。
centos:test  生成新的镜像名称。​
docker images    #查看生成的新镜像docker run -itd nginx:centos7 bash          #使用新的镜像创建容器
docker ps -a                              #查看容器状态
docker exec -it 容器id bash           #进入容器
nginx                                       #启动nginx服务
netstat -natp |grep 80                      #查看80端口是否开启

2. 基于本地模板创建

通过导入操作系统模板文件可以生成镜像,模板可以从OPENVZ 开源项目下载,下载地址为: 

openvz.org/ Download/template/precreated

模板里面就是使用docker export 命令导出的容器文件​#下载模板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 import debian-7.0-x86-minimal.tar.gz -- debian:test  #方法二​#查看镜像docker images​#使用导入的镜像创建容器docker run -itd debian:test bashdocker ps -a

3. 基于 Dockerfile 创建

 3.1 联合文件系统(UnionFS ) 


Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

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

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

3.2 镜像加载原理 


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。

  • bootfs 就是内核引导器(引导加载内核)和内核。
  • rootfs 是n多个基础镜像(提供基础操作环境)和应用镜像叠加在一起的只读层。
  • 运行的容器实例会在 rootfs 之上添加一个可读可写层。

 

3.3 为什么Docker里的centos的大小才200M?(容器中操作系统容量小的原因) 


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

大部分镜像是通用的,但如果专门基于某个版本创建的镜像,在其他版本的操作系统中运行可能会有问题。

3.4  Docker镜像结构的分层


镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

(1)Dockerfile 中的每个指令都会创建一个新的镜像层;

(2)镜像层将被缓存和复用;

(3)当 Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;

(4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效;

(5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了。

3.5 Dockefile 的引入


Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本, 用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

我们需要定制首己额外的需求时,只需在 Docketlle 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。就是描述该层应当如何构建。有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。

除了手动生成 Docker 镜像之外,可以使用 dockerfile 自动生成镜像。Dockerfile 是由多条的指令组成的文件,其中每条指令对应Linux中的一条命令,Docker程序将读取 Dockerfile 中的指令生成指定镜像。

Dockerfile 结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。Dockerfile 每行支持一 条指令, 每条指令可携带多个参数,支持使用以“#“号开头的注释。

二. Dockerfile 操作命令的指令

Dockerfile简介:

Dockerfile 其实就是我们用来构建 Docker 镜像的源码,当然这不是所谓的编程源码,而是一些命令的组合,只要理解它的逻辑和语法格式,就可以编写 Dockerfile了。

简单点说,Dockerfile 的作用:它可以让用户个性化定制Docker镜像。因为工作环境中的需求各式各样,网络上的镜像很难满足实际的需求。

Dockerfile常见命令: 

命令作用
FROM image_name:tag声明基础镜像
MAINTAINER user_name声明镜像的作者
ENV key value设置环境变量 (可以写多条)
RUN command编译镜像时运行的脚本(可以写多条)
CMD设置容器的启动命令
ENTRYPOINT设置容器的入口程序

ADD source_dir/file

dest_dir/file

将宿主机的文件复制到镜像内,如果是一个压缩文件,将会在复制后自动解压。支持URL路径下载源文件,但下载方式不能自动解压。

COPY source_dir/file

dest_dir/file

和ADD相似,将宿主机的文件复制到镜像内,但是如果有压缩文件并不能解压。不支持URL路径下载。
WORKDIR path_dir设置工作目录
ARG设置工作目录
VOLUMN设置容器的挂载卷

2.1 FROM 镜像

指定新镜像所基于的基础镜像,第一条指令必须为 FROM 指令,每创建一个镜像就需要一条 FROM 指令

2.2 MAINTAINER 名字

说明新镜像的维护人信息

2.3 RUN 命令

在所基于的镜像上执行命令,并提交到新的镜像中

尽量减少run命令的条数。

  • 当命令较长时,可以使用 \ 来换行;
  • 多条命令可以使用 ; 或 && 合并成一条命令,减少镜像的层数。

2.4 ENTRYPOINT 

设定容器启动时第一个运行的命令及其参数。

可以通过使用命令 docker run --entrypoint 来覆盖镜像中的 ENTRYPOINT 指令的内容。

 两种格式:​exec格式(数值格式):ENTRYPOINT [“命令”,“选项”,“参数”]​shell格式:ENTRYPOINT 命令 选项 参数ENTRYPOINT ["rm", "-rf", "/*"]

前面四个命令就可以创建成一个粗略的镜像。

2.5 CMD

CMD ["要运行的程序","参数1","参数2"]

启动容器时默认执行的命令或者脚本,Dockerfile 只能有一条CMD命令。如果指定多条命令,只执行最后一条命令。

如果在docker run时指定了命令或者镜像中有ENTRYPOINT,那么CMD就会被覆盖。

CMD 可以为 ENTRYPOINT 指令提供默认参数。

 两种格式:​exec形式:CMD [“要运行的程序”,“参数1”, “参数2”]​shell形式: CMD 命令 参数1 参数2

ENTRYPOINT和CMD共存的情形: ENTRYPOIN 指定命令,CMD 传参

容器运行时的优先级:

docker run --entrypoint > Dockerfile ENTRYPOINT > docker run命令> Dockerfile CMD

ENTRYPOINT和CMD的区别:

  • ENTRYPOINT 设定容器启动时第一个运行的命令;CMD 是启动容器时默认执行的命令,如果指定多条CMD命令,只执行最后一 条命令。
  • 如果在 docker run 时指定了命令或者镜像中有 ENTRYPOINT,那么 CMD 就会被覆盖,并且会将 CMD 中的命令作为参数传给 ENTRYPOINT。
  • CMD 可以为 ENTRYPOINT 进行传参。

2.6 EXPOSE 端口号

指定新镜像加载到 Docker 时要开启的端口。

用于暴露端口,否则即使做了端口映射,外部也找不到。

2.7 ENV

ENV 环境变量 变量值

设置一个环境变量的值,会被后面的RUN使用。

linxu PATH=$PATH:/opt
  ENV PATH $PATH:/opt

2.8 ADD

ADD 源文件/目录 目标文件/目录

将源文件复制到镜像的指定路径中,源文件要与 Dockerfile 位于相同目录中,或者是一个URL。(URL路径,在线路径)

有如下注意事项:

 1、如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下。如果目标路径不存在,则会自动创建目标路径。​2、如果源路径是个文件,且目标路径是不以/结尾,则docker会把目标路径当作一个文件。如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件。如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。注意, 这种情况下,最好显示的以/结尾,以避免混淆。​3、如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。如果目标路径是个已经存在的目录,则docker 会把源路径目录下的文件拷贝到该目录下。​4、如果源文件是个归档文件,则docker会自动帮解压。(解压后复制源目录到镜像中的目录)URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。(不支持下载和解压一起使用,下载就不会解压。即只解压本地压缩包,不会解压下载的压缩包)
复制代码
  • ADD 的优点: 在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip、bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点: 在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。


http://www.mrgr.cn/p/56630877

相关文章

nginx高级篇之location高级实战

nginx location高级实战location是nginx的核心重要功能,可以设置网站的访问路径,一个web server会有多个路径,那么location就得设置多个。 Nginx的locaiton作用是根据用户请求的URI不同,来执行不同的应用。 针对用户请求的网站URL进行匹配,匹配成功后进行对应的操作。1.语…

【树莓派】yolov5 Lite,目标检测,行人检测入侵报警

延续之前的程序&#xff1a; https://qq742971636.blog.csdn.net/article/details/138172400 文章目录 播放声音pygame不出声音怎么办&#xff08;调节音量&#xff09;树莓派上的音乐播放器&#xff08;可选&#xff09;命令行直接放歌&#xff08;尝试放mp3歌曲&#xff09; …

一般神经网络的微分与网络参数的初始化

(文章的主要内容来自电科的顾亦奇老师的 Mathematical Foundation of Deep Learning, 有部分个人理解) 一般深度神经网络的微分 上周讨论的前向和反向传播算法可以推广到任意深度神经网络的微分。 对于一般的网络来说&#xff0c;可能无法逐层分割&#xff0c;但仍然可以用流…

第十五届蓝桥杯省赛第二场C/C++B组D题【前缀总分】题解(AC)

暴力解法 O ( 26 n 5 ) O(26n^5) O(26n5) 枚举将第 i i i 个字符串的第 j j j 个字符改为 c c c 的所有方案&#xff0c;时间复杂度 O ( 26 n 2 ) O(26n^2) O(26n2)&#xff0c;修改并计算总分&#xff0c; O ( n 3 ) O(n^3) O(n3)。 暴力优化 O ( 26 n 3 log ⁡ n ) O…

openGauss 函数

函数 openGauss常用的函数如下: 数学函数abs(x) 描述:绝对值。 返回值类型:和输入相同。 示例: openGauss=# SELECT abs(-17.4);abs ------17.4 (1 row)cbrt(dp) 描述:立方根。 返回值类型:double precision 示例: openGauss=# SELECT cbrt(27.0);cbrt ------3 (1 row)c…

宿舍Giwifi聚合方案

方案A: 方案B: 方案C:

在 Linux 上把 Vim 配置为默认编辑器

目录 ⛳️推荐 在 Linux 命令行中编辑 将 Vim 设置为其他程序的默认值 在 Alpine 中编辑电子邮件 总结 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 我使用 Linux 大概有…

SpringBoot整合AOP实现打印方法执行时间切面

pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>代码 创建注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; imp…

MySQL中什么情况下会出现索引失效?如何排查索引失效?

目录 1-引言&#xff1a;什么是MySQL的索引失效&#xff1f;(What、Why)1-1 索引失效定义1-2 为什么排查索引失效 2- 索引失效的原因及排查&#xff08;How&#xff09;2-1 索引失效的情况① 索引列参与计算② 对索引列进行函数操作③ 查询中使用了 OR 两边有范围查询 > 或 …

rust中结构体的属性默认是不能修改的,要想修改可以有两种方式

Rust中结构体里面的属性默认是不支持修改的&#xff0c;而且默认不是pub的&#xff0c;要想修改的话&#xff0c;有两种方式&#xff0c;我以为和python里面的类似呢&#xff0c;但是还是需要一点技术含量的。如果想在引到外部修改&#xff0c;需要声明pub&#xff0c;如果想在…

Ubuntu 24.04 LTS x86_64 OVF (sysin) - VMware 虚拟机模板

Ubuntu 24.04 LTS x86_64 OVF (sysin) - VMware 虚拟机模板Ubuntu 24.04 LTS x86_64 OVF (sysin) - VMware 虚拟机模板 Ubuntu 24.04 LTS (GNU/Linux 6.8-generic x86_64) 请访问原文链接:Ubuntu 24.04 LTS x86_64 OVF (sysin) - VMware 虚拟机模板,查看最新版。原创作品,转…

路由选择协议三剑客--BGP协议

一、背景 边界网关协议(Border Gateway Protocol, BGP)是用来处理像因特网规模大小的网络协议,能够妥善处理好不相关路由域间的多路连接协议。BGP一般用于企业和企业之间,也就是运营商骨干网的通信,一般使用在AS内或AS间通信,在大型企业网中实现的比较多。 内部网关协议只…

Multitouch 1.27.28 免激活版 mac电脑多点触控手势增强工具

Multitouch 应用程序可让您将自定义操作绑定到特定的魔术触控板或鼠标手势。例如&#xff0c;三指单击可以执行粘贴。通过执行键盘快捷键、控制浏览器的选项卡、单击鼠标中键等来改进您的工作流程。 Multitouch 1.27.28 免激活版下载 强大的手势引擎 精心打造的触控板和 Magic …

【分布式通信】NPKit,NCCL的Profiling工具

NPKit介绍 NPKit (Networking Profiling Kit) is a profiling framework designed for popular collective communication libraries (CCLs), including Microsoft MSCCL, NVIDIA NCCL and AMD RCCL. It enables users to insert customized profiling events into different C…

Ubuntu 22.04.4 LTS磁盘扩容

安装gpartedsudo apt updatesudo apt install gparted然后启动gpartedsudo gparted启动成功会完成一个新的对话框,直接调整磁盘大小的话会提示失败扩容查看只读文件系统的详细信息,点击Information(信息) 查看磁盘的挂载位置按顺序运行以下命令sudo -i mount -o remount -r…

K8s: 部署 kubernetes dashboard

部署 Dashboard K8s 官方有一个项目叫 dashboard&#xff0c;通过这个项目更方便监控集群的状态 官方地址: https://github.com/kubernetes/dashboard 通常我们通过命令行 $ kubectl get po -n kube-system 能够查看到集群所有的组件&#xff0c;但这样的方式比较不太直观 …

Jenkins 简述及其搭建

什么是持续集成?持续集成(CI)是在软件开发过程中自动化和集成许多团队成员的代码更改和更新的过程。在 CI 中,自动化工具在集成之前确认软件代码是有效且无错误的,这有助于检测错误并加快新版本的发布。什么是持续交付?持续交付 (CD) 是指每天多次将新软件投入生产,自动…

火山引擎VeDI:如何高效使用A/B实验,优化APP推荐系统

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群在移动互联网飞速发展的时代,用户规模和网络信息量呈现出爆炸式增长,信息过载加大了用户选择的难度,这样的背景下,推荐系统应运而生,为用户提供个性化的内容推荐。推荐系统在不断迭代…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(三)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 4 - 6节&#xff09; P5《04.快速入门》 本节来实现一个 HelloWorld 效果&#xff1a; 1、打开编辑器&#xff0c;选择新建项目&…