Docker镜像的创建 和 Dockerfile

一. 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.mzph.cn/diannao/3537.shtml

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

相关文章

maven修改默认编码格式为UTF-8

执行mvn -version查看maven版本信息发现&#xff0c;maven使用的编码格式为GBK。 为什么想到要修改编码格式呢&#xff1f;因为idea中我将文件格式统一设置为UTF-8&#xff08;如果不知道如何修改文件编码&#xff0c;可以参考文末&#xff09;&#xff0c;然后使用maven打包时…

docker 和 docker-compose的区别

Docker 和 Docker Compose 是两个相关但具有不同功能的工具&#xff0c;它们在容器化应用的生命周期管理中扮演不同的角色&#xff1a; Docker&#xff1a; Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包应用及其依赖包到一个可移植的容器中&#xff0c;这样…

ESP32与SD卡交互实现:文件读写实战与初始化详解及引脚定义

本代码实现ESP32与SD卡的交互&#xff0c;包括定义SPI引脚、创建自定义SPI类实例、编写WriteFile与ReadFile函数进行文件读写。setup函数初始化串口、SPI、SD卡&#xff0c;向“/test.txt”写入“myfirstmessage”&#xff0c;读取并打印其内容。loop函数留空待扩展。 1. 需要…

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

PCV库之调用SIFT.py中process_image()执行错误的解决方案

背景介绍: windows10,python3.x,64位AMD R9处理器,ROG电脑,pycharm开发,已经安装好了PCV库 如何安装PCV库 请看我的博客Python之PCV库安装教程以及解说-CSDN博客文章浏览阅读111次&#xff0c;点赞5次&#xff0c;收藏3次。GitHub - Ultravioletrayss/PCVfile: 文档内含有pyt…

Nginx 配置 SSL(HTTPS)详解

Nginx作为一款高性能的HTTP和反向代理服务器&#xff0c;自然支持SSL/TLS加密通信。本文将详细介绍如何在Nginx中配置SSL&#xff0c;实现HTTPS的访问。 随着互联网安全性的日益重要&#xff0c;HTTPS协议逐渐成为网站加密通信的标配。Nginx作为一款高性能的HTTP和反向代理服务…

OpenCV 实现霍夫圆变换

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV实现霍夫变换 下一篇:OpenCV 实现重新映射 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 HoughCircles()检测图像中的圆圈。 理论 Hough 圆变换 H…

Cgicc搭建交叉编译环境(移植到arm)

Cgicc GUN Project官网连接&#xff1a;Cgicc- GNU Project - Free Software Foundation 1. 下载源码 Cgicc下载地址&#xff1a; [via http] Index of /gnu/cgicc [via FTP] ftp://ftp.gnu.org/gnu/cgicc/ 目前最新版&#xff1a;3.2.20 2. 源码构建原理 一般&#xff…

在VSCode中调试其他软件执行的python文件

在VSCode中调试其他软件执行的python文件 0. 实际场景 我有一段python代码想在Metashape中运行&#xff0c;但是又想在中间某一步停下来查看变量值。由于Metashape的python环境不容易在vscode中配置&#xff0c;所以直接用vscode调试单个文件的方式无法实现这个想法。还好&am…

42. UE5 RPG 实现火球术伤害

上一篇&#xff0c;我们解决了火球术于物体碰撞的问题&#xff0c;现在火球术能够正确的和攻击目标产生碰撞。接下来&#xff0c;我们要实现火球术的伤害功能&#xff0c;在火球术击中目标后&#xff0c;给目标造成伤害。 实现伤害功能的思路是给技能一个GameplayEffect&#x…

3DTiles生产流程与规范

一篇19年整理的比较老的笔记了。更多精彩内容尽在数字孪生平台。 瓦片切分 标准的四叉树切分对于均匀分布的地理数据切片非常有效&#xff0c;但是这样均等的切分不适用于随机分布、不均匀分布的地理数据&#xff0c;当地理数据稀疏分布的时候&#xff0c;均等的四叉树就不再高…

跟着Datawhale重学数据结构与算法(3)---排序算法

开源链接&#xff1a;【 教程地址 】【电子网站】 【写博客的目的是记录自己学习过程&#xff0c;方便自己复盘&#xff0c;专业课复习】 数组排序&#xff1a; #mermaid-svg-F3iLcKsVv8gcmqqC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16p…

PHP项目搭建与启动

1、拉取项目 2、安装phpstudy 下载地址&#xff1a; Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 软件安装&#xff1a; Apache2.4.39、Nginx1.15.11、MySQL8.0.12、 composer2.5.8 添加伪静态 将下面代码写入到伪静态配置文本域框内&#xff1a; location ~* (ru…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Text Edit的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 输入类控件 | Text Edit的使用及说明 文章编号&#xff…

VScode使用cmake编译

一&#xff1a;输入 ctrlshiftp打开用于命令执行的输入框 二&#xff1a;输入cmake&#xff0c;选择quick start 模式 三&#xff1a;选择版本最高的gcc版本 四&#xff1a;输入项目名称 选择C 五&#xff1a;选择executable 这样便创建好了最简单的cmake例程&#xff0c;一个…

企业微信代开发应用登录操作

首先声明&#xff1a;企微的文档写得真烂&#xff01;&#xff01;&#xff01;有一些问题&#xff0c;官方情愿在问答区给用户一个个解答&#xff0c;也不愿意在文档写清楚&#xff0c;生怕自己工作量不饱和被优化。 概念说明 代开发应用&#xff0c;是相对于自建应用来说的。…

[Swift]组件化开发

一、组件化开发基础 1.组件定义 在软件开发中&#xff0c;一个组件是指一个独立的、可替换的软件单元&#xff0c;它封装了一组相关的功能。组件通过定义的接口与外界交互&#xff0c;并且这些接口隔离了组件内部的实现细节。在Swift语言中&#xff0c;组件可以是一个模块、一…

车企如何利用数据技术,指导汽车全生命周期的业务运营?

引言&#xff1a;数据正作为重点&#xff0c;为行业提供不可或缺的指导 《汽车数据发展研究报告&#xff08;2023&#xff09;》指出&#xff0c;汽车行业正由传统硬件制造向“电动化、智能化、网联化”方向转变。德勤预测&#xff0c;到 2025 年&#xff0c;汽车行业 20%的利…

K8s: 部署 kubernetes dashboard

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

【JavaScript】内置对象 ③ ( Math 内置对象 | Math 内置对象简介 | Math 内置对象的使用 )

文章目录 一、Math 内置对象1、Math 内置对象简介2、Math 内置对象的使用 二、代码示例1、代码示例 - Math 内置对象的使用2、代码示例 - 封装 Math 内置对象 一、Math 内置对象 1、Math 内置对象简介 JavaScript 中的 Math 内置对象 是一个 全局对象 , 该对象 提供了 常用的 数…