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

news/2024/11/30 8:50:09/

一、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.ppmy.cn/news/979059.html

相关文章

ConcurrentHashMap 相比于 HashMap 的优势

ConcurrentHashMap 使用每个链表头节点作为锁对象, 把一把大锁转换成多把小锁, 大大缩小了锁冲突的概率 HashTable 是给整个 Hash 表加锁, 因此只要有线程抢到了锁其他线程就得阻塞等待. ConcurrentHashMap 是对每个链表加锁, 因此只要不是对同一个链表进行修改就不会阻塞, 大…

crawlab爬虫python篇(保姆级图文教程)

文章目录 前言一、创建项目二、创建爬虫1.新建项目2.新建爬虫3. 上传文件总结资料解决方案记录前言 一个python刚到门槛水平的程序员是如何使用crawlab爬取网站,在这里做个图文教程记录下。 提示:这里做一个简单的网站爬取完整示例图文教程 一、创建项目 首先,我们将创建一…

【Android】merge,include和viewstub的区别

序言 在Android开发中&#xff0c;merge、include和ViewStub都是用于布局的标签。 merge标签&#xff1a; merge标签用于优化布局层级&#xff0c;可以减少不必要的视图层次&#xff0c;提高布局的性能。 它会将标记的子视图合并到其父视图中&#xff0c;而不会创建新的视图…

《中国大学生计算机设计大赛》应用与开发组 “国二省一“ 备赛心得,万字干货 (建议收藏)

&#x1f4a7; 《中国大学生计算机设计大赛》备赛心得 \color{#FF1493}{《中国大学生计算机设计大赛》备赛心得} 《中国大学生计算机设计大赛》备赛心得&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客…

ArgoCD结合Gitlab交付项目到kubernetes集群

ArgoCD结合Gitlab交付项目到kubernetes集群 作者:行癫(盗版必究) 一:环境准备 1.kubernetes集群环境 2.HA_Argocd环境 3.Gitlab集群环境 二:项目配置 1.配置Gitlab 创建仓库,并写入yaml文件,利用yaml构建application;此案例结合了NFS实现持久化存储

图文教程:如何在 3DS Max 中创建3D迷你卡通房屋

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 在本教程中&#xff0c;我们将学习如何创建一个有趣的、低多边形的迷你动画房子&#xff0c;你可以在自己的插图或视频游戏项目中使用它。您将学习的一些技能将包括创建基本的3D形状和基本的建模技术。让我…

LLM - Chinese-Llama-2-7b 初体验

目录 一.引言 二.模型下载 三.快速测试 四.训练数据 五.总结 一.引言 自打 LLama-2 发布后就一直在等大佬们发布 LLama-2 的适配中文版&#xff0c;也是这几天蹲到了一版由 LinkSoul 发布的 Chinese-Llama-2-7b&#xff0c;其共发布了一个常规版本和一个 4-bit 的量化版本…

macOS Monterey 12.6.8 (21G725) Boot ISO 原版可引导镜像

macOS Monterey 12.6.8 (21G725) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Lin…