06 - 镜像管理之:基础知识

news2025/1/24 17:57:26

1 了解镜像

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

但注意, 镜像不包含任何动态数据( /proc、/sys,其中,/proc里面装的主要是内核参数,在内核运行状态不同时里面的值是不一样的,而/sys目录则包含了系统资源的管理信息,这两个目录中的数据都是动态生成的) ,因此,其内容在构建好之后一般是不会变的。这里,第一,你要知道什么是动态数据,第二,将来我们要自己装一个linux操作系统,你想把这个linux做成一个容器镜像,其实很简单,就是把linux里面所有的文件目录打包一份就行了,但是打包的时候会把/proc和/sys这两个目录排除。(因此, 容器镜像不包含内核,容器共用宿主机的内核


2 镜像的制作


2.1 通过对系统打包的方式制作镜像


1)最小化安装一个操作系统

2)将此系统文件打包,把装的一个系统做成一个容器镜像,也就是把根文件系统打个包就行了(除了/proc和/sys之外)

[root@node02 ~]# tar -cvf --numeric-owner --exclude=/proc --exclude=/sys /data/centos7u2.tar /

3)将打包文件拷贝到运行容器的主机上

[root@node02 ~]# scp  centos7u2.tar  192.168.1.72:/root

4)利用打包文件生成镜像

[root@node02 ~]# docker  import  centos7u2.tar  docker.io/centos7u2:latest
[root@node02 ~]# docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos7u2              latest              1e1148e4cc2c        30 seconds ago      987 MB

5)使用自己生成的镜像创建容器做测试

[root@node02 ~]# docker run -itd --name c1 docker.io/centos7u2 /bin/bash

2.2 基于Dockerfile文件制作镜像


1)编写dockerfile文件

[root@node02 ~]# cat /root/test01 
	FROM local-test/centos7.2:v1				
	RUN yum install -y httpd &&  yum install -y vsftpd 

	解释:
		FROM:用于指定一个基础镜像
		RUN:执行任务,建议同一个任务的多条指令使用&&连接多个命令完成 

2)构建镜像

[root@node02 ~]# docker build -t centos7.2-httpd:v2 -f test01 /root

	参数说明:	
	    -t:用于指定镜像名称、标记
	    -f:指定dockerfile名称 

3)查看镜像

[root@node02 ~]# docker images 
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
centos7.2-httpd        v2                  2cdfd7a685f6        2 minutes ago       1.08 GB

3 Dockerfile指令说明


3.1 FROM

FROM < image >

用于指定基础镜像


3.2 MAINTAINER

MAINTAINER < name >

用于指定镜像的作者信息,当执行docker inspect指令时会有输出 。


3.3 RUN

RUN < command >
或者
RUN [“command”,“arg1”,“arg2”]

用于执行基础镜像支持的任何指令;



例如:
RUN yum install -y net-tools
RUN [“yum”,“install”,“-y”,“net-tools”]


3.4 CMD && ENTRYPOINT


3.4.1 CMD

CMD < command > < arg1 > < arg2 >
或者
CMD [“command”,“arg1”,“arg2”]


用于指定容器启动时执行的操作;


注意:一个dockerfile中只能有一条 CMD 指令,如果有多条则仅执行最后一条;

# 使用CMD指令
FROM ubuntu
CMD ["echo", "Hello World"]

3.4.2 ENTRYPOINT

ENTRYPOINT 和 CMD 指令的用法很相似:

ENTRYPOINT < command > < arg1 > < arg2 >
或者
ENTRYPOINT [“command”,“arg1”,“arg2”]


用于指定容器启动时执行的操作;

注意:一个dockerfile中只能有一条 ENTRYPOINT指令,如果有多条则仅执行最后一条;

# 使用ENTRYPOINT指令
FROM ubuntu
ENTRYPOINT ["echo", "Hello World"]

另外,ENTRYPOINT指令还可以与CMD指令配合使用,此时,CMD指令后跟的不再是完整的可执行命令,而仅是作为ENTRYPOINT指令后的参数使用,如下所示:

# ENTRYPOINT 和 CMD 指令配合使用
FROM ubuntu
ENTRYPOINT ["cat"]
CMD ["-n","/etc/passwd"]

3.4.3 CMD 和 ENTRYPOINT 的区别

区别:
如果在运行docker run命令时指定了参数,那么,将会覆盖CMD中指定的参数,而ENTRYPOINT指令不会被覆盖,而是被附加到docker run命令的参数之前。


总结来说:CMD用于定义默认的容器启动命令,可以被覆盖,而ENTRYPOINT用于定义容器启动的主要命令,不会被覆盖(可以通过docker run --entrypoint 进行强制覆盖)。


案例:
使用 Dockerfile 构建 centos 镜像,在 Dockerfile 中使用 CMD 和 ENTRYPOINT 。当 docker run + 参数 的时候进行 CMD 和 ENTRYPOINT 的测试,CMD指定的参数是否会被覆盖,以及 ENTRYPOINT 指定的参数是否会附加到docker run命令的参数之前。



【测试CMD】

1)编写dockerfile文件

$ vim dockerfile-centos-test
FROM centos
CMD [“ls”,“-a”]


2)构建镜像

$ docker build -f dockerfile-centos-test -t cmd-test:0.1 .


3)运行镜像

$ docker run cmd-test:0.1
在这里插入图片描述
可以看到,列出了所有目录。


4)这个时候我们在docker run 的时候追加一个命令参数 -l

$ docker run cmd-test:0.1 -l
在这里插入图片描述
可以看到,出现了错误,在CMD的情况下,加 -l 替换了dockerfile中的 CMD [“ls”,“-l”],但是由于 -l 不是命令,所以就报错了。


5)我们将 docker run 的命令参数 -l 改为 ls

$ docker run cmd-test:0.1 ls
在这里插入图片描述
可以看到,这个时候就执行成功了。



【测试 ENTRYPOINT】

1)编写dockerfile文件

$ vim dockerfile-centos-test
FROM centos
ENTRYPOINT [“ls”,“-a”]


2)构建镜像

$ docker build -f dockerfile-centos-test -t cmd-test:0.1 .


3)运行镜像

$ docker run cmd-test:0.1
在这里插入图片描述

4)这个时候追加一个命令 -l (使之成为 ls -al )

$ docker run cmd-test:0.1 -l
在这里插入图片描述



总结一下:CMD的情况下,docker run的参数 -l 替换了CMD的 ls -a。而ENTRYPOINT的情况下,-l 参数追加到了 ls -a 的后面,使之变成了ls -al。


3.5 ARG

ARG < key >=< value >

Docker 1.9 版本 后新加入的指令,ARG定义的变量只有在构建image时有效,建立完成后变量消失;


3.6 USER

USER < name >

用于设置启动容器的用户,默认为root。


注意:

  • 如果容器中的应用程序运行时不需要特殊的权限,可以通过 USER 指令把应用程序的所有者设置为非 root 用户(如果该用户不存在,首先需要使用 RUN 命令在镜像中创建用户)。
  • 如果在每次编译镜像时,对用户的 UID/GID 有要求需要保持一致,应该在新建用户和组的时候指定 UID和 GID;

3.7 EXPOSE

EXPOSE < port1 > < port2 > …

用于设置容器启动时,要映射到物理机的端口;


注意:容器启动后,会将该端口映射到物理机上的随机端口( EXPOSE 不能指定未来容器外部与内部端口之间的映射关系)。


3.8 ENV

ENV < key > < value >

用于为容器设置环境变量,可以使用docker inspect查看;也可以通过docker run --env < key >=< value >设置或修改环境变量;(该变量设置后,后续的RUN指令都可以使用该变量)


3.9 ADD && COPY


3.9.1 ADD

ADD < src > < dest >

用于将src指定的文件复制到容器的目录


例如:
ADD /tmp/nginx-1.13.4.tar.gz /tmp/



1)所有拷贝到容器中的文件及目录权限为0755,uid及gid均为0;
2)src如果是一个目录,那会将该目录下所有文件拷贝到容器中,不包括目录;
3)如果src是文件且dest不以/结束,dest会被识别为文件,src中的内容会把dest文件内容覆盖;
4)如果src是文件且dest以/结束,则会将src文件拷贝到dest目录;;


如果源文件是一个tar压缩包的话,压缩格式为gzip,bzip2以及xz的情况下,ADD指令将会自动解压缩这个压缩文件到目标路径中,在某些情况下这个自动解压缩的功能非常有用。


3.9.2 COPY

COPY < src > < dest >


用于复制本地主机的src文件(为Dockerfile所在目录的相对路径、文件或者目录)到容器的dest(dest路径不存在时,会自动创建)。



此外,还需要注意一点,使用 COPY 指令,源文件的各种元数据都会保留,比如读、写、执行权限、文件变更时间等。(这个特性对于镜像定制很有用,特别是构建相关文件都在使用 Git 进行管理的时候)


3.9.3 ADD 和 COPY 的区别

共同点:
都可以将主机上的资源加入到Dockerfile制作的镜像中。


不同点:
在这里插入图片描述



官方建议:
1)尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已;
2)需要自动解压缩的场合,再使用ADD;

另外,需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则:所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。


3.10 WORKDIR

WORKDIR < path >


用于切换目录(尽量使用绝对路径),类似于cd命令,但不同于cd的是:

  • 如果目录不存在,则会被创建;
  • 使用RUN cd命令只是在当前的shell中改变目录,对dockerfile文件中 RUN cd 后面的命令没有影响,而WORKDIR 对RUN、CMD、ENTRYPOINT指令生效。


【测试一:使用 WORKDIR 进行测试】
[root@master-01 test02]# cat dockerfile 
FROM nginx
WORKDIR /etc
RUN echo 111 > 1.txt

[root@master-01 test02]# docker build -f dockerfile -t dockerbuild-test01:v2 .

[root@master-01 dockerbuild-test02]# docker run -it --name=aaab dockerbuild-test01:v2 bash
root@80bba0d3ffaa:/etc# ls      #可以看到 RUN echo 111 > 1.txt 这一步是在/etc目录内执行的;
1.txt          cron.d        gss        kernel       os-release  rc1.d        
ld.so.cache    mke2fs.conf   pam.conf   rc2.d        security    subuid
root@80bba0d3ffaa:/etc# pwd     #可以看到,我们通过该镜像运行的容器,进入容器之后的目录也是WORKDIR的目录;
/etc


【测试二:使用 RUN cd 进行测试】
[root@master-01 test01]# cat dockerfile 
FROM nginx
RUN cd /etc
RUN echo 111 > 1.txt

[root@master-01 test01]# docker build -f dockerfile -t dockerbuild-test01:v1 .

[root@master-01 test01]# docker run -it --name=aaa dockerbuild-test01:v1 bash
root@76170b5cbdb7:/# ls     #可以看到,RUN cd /etc只对当前命令有效,不会影响后面的命令;
1.txt  boot  docker-entrypoint.d   etc   lib    media  opt   root  sbin  sys  usr
bin    dev   docker-entrypoint.sh  home  lib64  mnt    proc  run   srv   tmp  var
root@76170b5cbdb7:/# pwd  
/

3.11 VOLUME

VOLUME [“mount_point”]


用于创建一个本机或者为其他容器使用的挂载点,用于数据的持久化保存 。


例如:
FROM base VOLUME ["/tmp/data"]



通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点,但值得注意的是通过VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是自动生成的(可以通过docker inspect查看)。


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

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

相关文章

【DataRoom】- 基于VUE的开源的大屏可视化设计器

【DataRoom】- 基于VUE的开源的大屏可视化设计器 DataRoom是一款基于SpringBoot、MyBatisPlus、Vue、ElementUI、G2Plot、Echarts等技术栈的大屏设计器&#xff0c;具备大屏设计、预览能力&#xff0c;支持MySQL、Oracle、PostgreSQL、SQLServer、ElasticSearch、JSON、JS、HTT…

springcloud:3.7测试线程池服务隔离

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…

Dubbo的线程模型

1 线程模型概述 Dubbo默认的底层网络通信使用的是Netty。 服务提供方NettyServer使用两级线程池&#xff0c;其EventLoopGroup&#xff08;boss&#xff09;主要用来接收客户端的连接请求&#xff0c;并把完成TCP三次握手的连接分发给EventLoopGroup&#xff08;worker&#…

【音视频开发好书推荐】RTC程序设计:实时音视频权威指南

目录 1、WebRTC概述2、好书推荐3、本书内容4、本书特色5、作者简介6、谁适合看这本书 1、WebRTC概述 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个由Google发起的实时音视频通讯C开源库&#xff0c;其提供了音视频采集、编码、网络传输&#xff0c;解码显…

【考研数学】基础660太难了?一个办法搞定660

觉得题目太难&#xff0c;大概率是题目超出了自己当前的水平 题型没见过&#xff0c;或者太复杂&#xff0c;属于跳级学习了&#xff0c;正确的思路就是回归到自己的水平线&#xff0c;题目略难即可。 这样做题的话&#xff0c;大部分题目涉及的点不会超出自己的能力范围&…

【详识JAVA语言】String 类1

String类的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想&#xff0c;而…

python之海龟绘图

海龟绘图&#xff08;turtle&#xff09;是一个Python内置的绘图库&#xff0c;也被称为“Turtle Graphics”或简称“Turtles”。它采用了一种有趣的绘图方式&#xff0c;模拟一只小海龟在屏幕上爬行&#xff0c;而小海龟爬行的路径就形成了绘制的图形。这种绘图方式最初源自20…

考研数学——高数:多元函数微分法及其应用

因为复习阶段全篇很细节的写下来一来比较费时间&#xff0c;二容易导致为了记笔记而记。 接下来的内容只会保留上课中比较有意义的地方&#xff0c;以及有自己助于理解的想法 全微分 助记&#xff1a; 证明是否可微&#xff0c;首先判断两个偏导数是否存在&#xff0c;不存在则…

插入排序和归并排序

插入排序&#xff0c;Insertion Sort. 给出伪代码 for i 1,2,...,n-1Insert A[i] into Sorted array A[0:i-1]by swaping down to the correct position. 冒泡排序 冒泡排序就是一种插入排序算法。 i ← 1 while i < length(A)j ← iwhile j > 0 and A[j-1] > A…

FlyClient SPV client轻量化

这篇文章主要是为了构建一种轻客户端的算法。 如果使用SPV 的方式验证交易&#xff0c;每个client上面需要存储非常多的header。使用 proofs of proof-of-work 的方式&#xff0c;使得请客户端仅仅下载少量的区块头就能验证这一条链的安全性&#xff0c;然后再对包含交易的区块…

【详识JAVA语言】String类2

常用方法 字符串的不可变性 String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改&#xff0c;是因为&#xff1a; 1. String类在设计时就是不可改变的&#xff0c;String类实现描述中已经说明了 以下来自JDK1.8中String类的部分实现&#xff1a; String类…

2D/3D相机手眼标定总结

1. 九点标定 九点标定法的本质&#xff1a; 无需进行相机内参标定&#xff0c;只能识别x&#xff0c;y坐标&#xff0c;属于2D平面标定&#xff0c;在标定过程中z是未知的。 该算法的核心是仿射变换&#xff0c;即图像坐标系到机器人坐标系的2D仿射变换&#xff08;注意这里并不…

【python--比对两个列表获取列表中出现频率最高的词及频率】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 完整代码 完整代码 from collections import Counter from data_keywords import extract_…

【Linux】文件传输工具lrzsz的安装与使用

目录 一、关于lrzsz 二、安装lrzsz 三、lrzsz的说明及使用 1、上传命令rz 2、下载命令sz 一、关于lrzsz 在开发的过程中&#xff0c;经常遇到 需要在 Linux 和 Windows 之间上传下载文件的情况 这时&#xff0c;一般都是使用 FTP 或者 WinSCP 工具进行上传下载, 虽然也能…

SRIO—IP讲解及说明

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、SRIO IP 概述1.1 逻辑层1.1.1 I/O 端口(I/O Port)1.1.2 消息端口(Messaing Port)1.1.3 用户自定义端口(User-Defined Port)1.1.4 维护端口(Maintenance Port)1.2 缓冲层1.3 物理层…

python+django+vue房屋租赁系统 8gwmf

房屋租赁系统在设计与实施时&#xff0c;采取了模块性的设计理念&#xff0c;把相似的系统的功能整合到一个模组中&#xff0c;以增强内部的功能&#xff0c;减少各组件之间的联系&#xff0c;从而达到减少相互影响的目的。如房源信息、预约信息、求租信息模块等[12]。 管理员后…

java工程师面试简历模板,2024谈一下当下最合适的Java架构

前言 这些算法&#xff0c;都是小编一点一点看的大佬们的方法&#xff0c;自己积累的. 如果有什么描述的不对的地方还望大佬赐教 多交流才能进步&#xff0c;加油&#xff0c;冲冲冲&#xff01;&#xff01;&#xff01; 目录 一、冒泡排序 二、选择排序 三、插入排序 四、快速…

Redis中的RDB和AOF持久化机制(一)

Redis持久化 RDB快照(snapshot). 在默认情况下&#xff0c;Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中.Redis可以进行设置,让它在"N秒内数据集至少有M个改动"这一条件被满足时&#xff0c;自动保存一次数据集。比如说&#xff0c;以下设置会让Redis…

软件测试需求分析如何编写?为什么要进行测试需求分析?

在软件开发的过程中&#xff0c;软件测试需求分析是至关重要的一个环节。测试需求分析是指对待测软件的需求进行全面细致的分析&#xff0c;明确软件测试的目标和范围&#xff0c;为测试活动的进行提供指导。通过对软件需求的详细分析&#xff0c;可以确保测试人员清楚了解软件…