【云原生】Docker镜像的创建,Dockerfile

一、Docker镜像的创建

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

1.基于现有镜像创建

(1)首先启动一个镜像,在容器里做修改docker run -it --name web 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 "cx" 容器id nginx:centos7#常用选项:-m 指定说明信息;-a 指定作者信息;-p 生成过程中停止容器的运行。fe21b13926d1  原容器ID。nginx:centos  生成新的镜像名称。​
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 创建 

 联合文件系统(UnionFS ) 

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

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

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

镜像加载原理 

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等。

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

 Docker镜像结构的分层

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

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

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

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

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

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

二、 Dockerfile操作命令的指令

FROM 指定基础镜像,dockerfile构建镜像的第一个指令
MAINTAINER 指定镜像维护人信息(可选
RUN 指定Linux命令,建议多条命令可用 && 或 ; 串起来使用
ENV 设置镜像的环境变量
EXPOSE 暴露容器端口
VOLUME  指定容器的匿名数据卷
ADD/COPY复制本地文件/目录到镜像中
USER指定容器的运行用户
WORKDIR指定容器的工作目录
CMD/ENTRYPOINT指定容器启动时执行的命令
ARG 指定构建镜像时传入的参数变量       docker build --build-arg 变量=值

 ADD 和 COPY 的区别

COPY 只能复制本地文件/目录到镜像中
ADD 不光可以复制本地文件/目录到镜像中,还可以通过URL下载文件复制到镜像中,还能将本地的tar压缩包解压后复制到镜像中(URL下载和tar包解压不能一起使用)

CMD 和 ENTRYPOINT 的区别

 ENTRYPOINT指定的容器启动命令优先级更高,如果CMD和ENTRYPOINT同时存在,那么CMD指定的内容将作为ENTRYPOINT指定的命令的选项或参数使用

容器启动时运行的命令优先级

docker run --entrypoint=命令  >  镜像里的 ENTRYPOINT ["命令"]  > docker run ... 镜像  命令  >  镜像里的 CMD ["命令"]

在编写Dockerfile 时,有严格的格式需要遵循:

第一行必须使用FROM指令指明所基于的镜像名称;
之后使用MAINTAINER 指令说明维护该镜像的用户信息;
然后是镜像操作相关指令,如RUN指令/EXPOSE/ADD/ENV/ARG等等。每运行一条指令,都会给基础镜像添加新的一层。(多条命令可以使用 ; 或 && 合并成一条命令,减少镜像的层数)
最后使用CMD或者ENTRYPOINT指令指定启动容器时要运行的命令操作

 如何缩小镜像体积大小?

1)尽可能的使用小体积的基础镜像
2)尽可能检查Dockerfile文件中指令的数量
3)可以构建镜像步骤最后添加清空系统和应用程序的缓存命令
4)使用多阶段(多级)构建 FROM 第一阶段的基础镜像  [AS 别名]      
                          .....
                          FROM 第二阶段的基础镜像
                          COPY --from=别名/0  第一阶段构建的文件/目录  当前阶段的文件/目录

三、Dockefile的实际运用

 1.Dockfile源码编译nginx

 通过Dockerfile创建源码编译的nginx(基于centos7基础镜像),并且通过后台运行

vim Dockerfile#基于镜像的指定
FROM centos:7
#作者信息
MAINTAINER this is nginx image <cx 20230724>
ADD nginx-1.22.0.tar.gz /usr/local/
RUN yum install -y pcre-devel zlib-devel openssh-devel gcc gcc-c++ make ncurses ncurses-devel bison cmake gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel
RUN useradd -M -s /sbin/nologin nginx && \
cd /usr/local/nginx-1.22.0 && \
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make installEXPOSE 80
#EXPOSE 443CMD ["/usr/local/nginx/sbin/nginx", "-g","daemon off;"]

 注意:容器里的服务必须为前台启动程序,否则会容器启动又关闭,无法正常提供服务。

所以在进行容器提供服务时,需要了解各种服务的前台运行,若该服务没有前台运行选项,则需要在容器中挂一个占用前台的运行指令,避免容器开启后有关闭。

2.镜像容量过大的解决方案  

1)尽可能的使用小体积的基础镜像
2)尽可能检查Dockerfile文件中指令的数量
3)可以构建镜像步骤最后添加清空系统和应用程序的缓存命令
4)使用多阶段(多级)构建 FROM 第一阶段的基础镜像  [AS 别名]      
                          .....
                          FROM 第二阶段的基础镜像
                          COPY --from=别名/0  第一阶段构建的文件/目录  当前阶段的文件/目录

 针对上面的镜像的创建进行基础镜像的进行多阶级构建 :

第一阶段构建
FROM centos:7 AS first
MAINTAINER this is nginx image <cx 20230724>
ADD nginx-1.22.0.tar.gz /usr/local/
RUN yum install -y pcre-devel zlib-devel openssh-devel gcc gcc-c++ make ncurses ncurses-devel bison cmake gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel
RUN useradd -M -s /sbin/nologin nginx && \
cd /usr/local/nginx-1.22.0 && \
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install && \
yum clean all#第二阶段构建
FROM centos:7
#复制第一阶段的目录到当前阶段
COPY --from=first /usr/local/nginx/ /usr/local/nginx/
RUN useradd -M -s /sbin/nologin nginx
EXPOSE 80
#EXPOSE 443CMD ["/usr/local/nginx/sbin/nginx", "-g","daemon off;"

 四、总结

Dockerfile结构大致分为四个部分:基础镜像信息(用from指定)、维护者信息(maintainer、镜像操作指令和容器启动时执行指令。

  • 第一行必须使用FROM指令指明所基于的镜像名称;
  • 之后使用MAINTAINER 指令说明维护该镜像的用户信息;
  • 然后是镜像操作相关指令,如RUN指令/EXPOSE/ADD/ENV/ARG等等。每运行一条指令,都会给基础镜像添加新的一层。(多条命令可以使用 ; 或 && 合并成一条命令,减少镜像的层数)
  • 最后使用CMD或者ENTRYPOINT指令指定启动容器时要运行的命令操作。

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

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

相关文章

财报解读:谷歌成功绝地反击?厮杀尚未真正开始!

在经历了一轮激烈的攻防战之后&#xff0c;谷歌、微软同一天发布了财报&#xff0c;从数据来看&#xff0c;谷歌成功抵御了微软携OpenAI发起的挑战&#xff0c;业绩表现全面超预期&#xff0c;而微软的业绩虽然整体也超预期&#xff0c;但相比其四面出击的高调则黯淡了许多。 巨…

stable diffusion如何确保每张图的面部一致?

可以使用roop插件&#xff0c;确定好脸部图片后&#xff0c;使用roop固定&#xff0c;然后生成的所有图片都使用同一张脸。 这款插件的功能简单粗暴&#xff1a;一键换脸。 如图所示&#xff1a; 任意上传一张脸部清晰的图片&#xff0c;点击启用。 在其他提示词不变的情况下…

Spring核心概念、IoC和DI的认识、Spring中bean的配置及实例化、bean的生命周期

初始Spring 一、Spring核心概念1.1IoC(Inversion of Contral)&#xff1a;控制反转1.2IoC代码实现1.2DI代码实现 二、bean的相关操作2.1bean的配置2.1.1bean的基础配置2.1.2bean的别名配置2.1.3bean的作用范围配置 2.2bean的实例化 - - 构造方法2.3bean的实例化 - - 实例工厂与…

python基础

变量和简单的数据类型 变量 变量的命名规则&#xff1a; 1、只能包含字母、数字和下划线&#xff0c;并且不能以数字开头 2、变量名中不能是python中的保留字 字符串 字符串的几种定义方法 name Bob name "Bob" name """Bob"""…

Excel录制宏批处理:避免重复工作,轻松提升效率

在处理大量数据时&#xff0c;我们常常需要进行一些重复且繁琐的操作&#xff0c;这不仅费时费力&#xff0c;还容易出错。而Excel的录制宏批处理功能可以帮助我们避免这些重复的工作&#xff0c;提高工作效率。本文将为您介绍如何使用Excel的录制宏批处理功能&#xff0c;让您…

web APIs-练习一

轮播图点击切换&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"…

数据结构:线索二叉树

线索二叉树 通过前面对二叉树的学习&#xff0c;了解到二叉树本身是一种非线性结构&#xff0c;采用任何一种遍历二叉树的方法&#xff0c;都可以得到树中所有结点的一个线性序列。在这个序列中&#xff0c;除第一个结点外&#xff0c;每个结点都有自己的直接前趋&#xff1b;…

记录Selenium自动化测试过程中接口的调用信息

上一篇博客&#xff0c;我写了python自动化框架的一些知识和粗浅的看法&#xff0c;在上一篇中我也给自己提出一个需求&#xff1a;如果记录在测试过程中接口的调用情况&#xff1f;提出这个需求&#xff0c;我觉得是有意义的。你在测试过程中肯定会遇到一些莫名其妙的问题&…

【JAVA】 String 类简述笔记

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言String类创建一个String类 常用方法字符串长度 length() 方法连接字符串 concat() 方法创建格式化字符串 format()功能 前言 string是C、java、VB等编程语言中的字符串&…

行星碰撞(力扣)栈 JAVA

给定一个整数数组 asteroids&#xff0c;表示在同一行的行星。 对于数组中的每一个元素&#xff0c;其绝对值表示行星的大小&#xff0c;正负表示行星的移动方向&#xff08;正表示向右移动&#xff0c;负表示向左移动&#xff09;。每一颗行星以相同的速度移动。 找出碰撞后剩…

unity进阶--xml的使用学习笔记

文章目录 xml实例解析方法一解析方法二 xml-path创建xml文档 xml实例 解析方法一 解析方法二 xml-path 创建xml文档

C++数据结构笔记(11)二叉树的#号创建法及计算叶子节点数

首先分享一段计算叶子节点数目的代码&#xff0c;如下图&#xff1a; 不难发现&#xff0c;上面的二叉树叶子节点数目为4。我们可以采用递归的方式&#xff0c;每当一个结点既没有左结点又没有右节点时&#xff0c;即可算为一个叶子结点。 int num0; //全局变量&#xff0c;代…

MyBatis-入门-快速入门程序

本次使用MyBatis框架是基于SpringBoot框架进行的&#xff0c;在IDEA中创建一个SpringBBot工程&#xff0c;根据自己的需求选择对应的依赖即可 快速入门 需求&#xff1a;使用MyBatis查询所有用户数据步骤&#xff1a; 准备工作&#xff08;创建Spring Boot工程、数据库user表…

【误差自适应跟踪方法AUV】自适应跟踪(EAT)方法研究(Matlab代码Simulin实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、Simulink模型、文献 &#x1f4a5;1 概述 摘要&#xff1a;跟踪问题&#xff08;即如何遵循先前记忆的路径&#xff09;是移动机器人中最重要的问题之一。根据机器人状…

机器学习深度学习——线性回归的从零开始实现

虽然现在的深度学习框架几乎可以自动化实现下面的工作&#xff0c;但从零开始实现可以更了解工作原理&#xff0c;方便我们自定义模型、自定义层或自定义损失函数。 import random import torch from d2l import torch as d2l线性回归的从零开始实现 生成数据集读取数据集初始…

windows默认编码格式修改

1.命令提示符界面输入 chcp 936 对应 GBK 65001 对应 UTF-8 2.临时更改编码格式 chcp 936(或65001) 3.永久更改编码格式 依次开控制面板->时钟和区域->区域->管理->更改系统区域设置&#xff0c;然后按下图所示&#xff0c;勾选使用UTF-8语言支持。然后重启电脑。此…

防止连点..

1.连点js文件 let timer; letflag /*** 节流原理&#xff1a;在一定时间内&#xff0c;只能触发一次** param {Function} func 要执行的回调函数* param {Number} wait 延时的时间* param {Boolean} immediate 是否立即执行* return null*/ function throttle(func, wait 500…

【数字IC基础】竞争与冒险

竞争-冒险 1. 基本概念2. 冒险的分类3. 静态冒险产生的判断4. 毛刺的消除使用同步电路使用格雷码增加滤波电容增加冗余项&#xff0c;消除逻辑冒险引入选通脉冲 1. 基本概念 示例一&#xff1a; 如上图所示的这个电路&#xff0c;使用了两个逻辑门&#xff0c;一个非门和一个与…

Windows 找不到文件‘chrome‘。请确定文件名是否正确后,再试一次

爱像时间&#xff0c;永恒不变而又短暂&#xff1b;爱像流水&#xff0c;浩瀚壮阔却又普普通通。 Windows 找不到文件chrome。请确定文件名是否正确后&#xff0c;再试一次 如果 Windows 提示找不到文件 "chrome"&#xff0c;可能是由于以下几种原因导致的&#xff1…

机器学习深度学习——模型选择、欠拟合和过拟合

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——多层感知机的简洁实现 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有…