1,镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件

在docker中所有应用直接打包为镜像,下载下来就可以直接运行。

2,如何获取镜像

  • 从远程仓库下载
  • 拷贝
  • 自己制作镜像DockerFile

3,Docker镜像基本概念

3.1,UnionFS(联合文件系统)(Docker镜像分层)

一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为提交并一层层叠加,同时可以将不同目录挂载到同一虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础,镜像可以通过分层进行继承,基于基础镜像(无父镜像),可以制作各种具体的应用镜像。

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



3.2,Docker镜像底层

在Docker镜像的最底层是bootfs(boot file system,主要包含bootloader和kernel,bootloader主要引导加载kernel,linux刚启动时就会加载bootfs文件系统),在bootfs加载完成之后整个内核就在内存中了,内存的使用权已由bootfs转交给内核,此时系统会卸载bootfs。

roofts(root file system/Base Image),在bootfs之上,包含的就是典型linux系统中的/dev, /proc, /bin, /etc等标准文件和目录。rootfs就是各种不同的操作系统的发性版,比如ubuntu、centos等。

3.3,为什么Docker镜像可以很小?

对于一个精简的docker,rootfs可以很小,只需要包含最基本的命令、工具和程序库即可。底层会直接使用宿主机(host)的kernel,镜像只需要提供rootfs,因此可以很小。由此也可看出,不同的linux发行版,bootfs基本是一致的,只是rootfs会有差别,不同的发行版可以公用bootfs。

4,Docker镜像启动过程

Docker镜像都是只读的,当容器启动时,一个新的可读写层被加载到镜像的顶层。新增层就是所谓的容器层,容器层之下的都是镜像层。所有的更改都在容器层中,镜像层不发生改变。

1、检测本地是否存在指定的镜像,不存在就从公有仓库下载

2、利用镜像创建并启动一个容器

3、分配一个文件系统,并在只读的镜像层外面挂载一层可读写层

4、从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去

5、从地址池配置一个IP地址给容器

6、执行用户指定的应用程序

7、执行完毕后终止容器

5,提交容器创建新的镜像

容器内做了修改后想要保存为新的镜像:

docker commit -m='提交的容器信息' -a='作者' 容器id 目标镜像名:tag		#git本地类似

6,Dockerfile创建新的镜像

Dockerfile就是用来构建docker镜像的构建文件,是一种命令脚本,通过此脚本可以生成镜像。

镜像是分层的,Dockerfile中的每一个命令就是一层。

docker build -f ~(dockerfile) -t ~(image名称):tag .
'''一个例子'''

'''=======================创建dockerfile文件(名字也可随意取)并输入以下内容======================='''
from centos CMD echo '-----end-----'
CMD /bin/bash '''=======================docker build构建镜像======================='''
docker build -f dockerfile -t zhang/centos:01 .

一个问题

'''=======================创建dockerfile文件(名字也可随意取)并输入以下内容======================='''
from centos VOLUME ['volume10', 'volume11'] CMD echo '-----end-----'
CMD /bin/bash 生成后run的时候会报错
[root@VM-0-11-centos docker-test-volum]# docker: Error response from daemon: OCI runtime create failed: invalid mount {Destination:[volume10, Type:bind Source:/var/lib/docker/volumes/7e8b5576dee6ad0d84ab31848f12b859b6ed4e05408492477308479dcbea20c4/_data Options:[rbind]}: mount destination [volume10, not absolute: unknown. =============================================解答===========================================
=====第一次尝试=====
通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。
还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。 VOLUME ['volume10', 'volume11'] 这一句的目的是在生成镜像的同时,在镜像中创建'volume01', 'volume02'并自动匿名挂载,这里说不是绝对路径不对,但是改为VOLUME ['/volume10', '/volume11']还是报错
[root@VM-0-11-centos docker-test-volum]# docker run -it zhang/centos
docker: Error response from daemon: OCI runtime create failed: invalid mount {Destination:[/volume10, Type:bind Source:/var/lib/docker/volumes/fa8716e8e78b1a9af0cfd75ac9476b6fcbecf7178b34d29d390c6ab29f19cfaf/_data Options:[rbind]}: mount destination [/volume10, not absolute: unknown.

7,dockerfile详解

7.1,使用dockerfile创建镜像的步骤:

  1. 编写一个dockerfile文件(构建文件,定义了一切的步骤,源代码)
  2. docker build构建成为一个镜像(通过dockerfile构建生成的镜像,最终发布和运行的产品)
  3. docker run运行镜像(容器,镜像运行起来提供服务)
  4. docker push发布镜像(发布到DockerHub或者其他第三方镜像仓库)

7.2,一个dockerhub官方的例子,点到版本号上会发现跳转到github


很多官方镜像都是基础包,很多功能都没有,通常需要搭建自己的镜像。

7.3,dockerfile的一些基本概念

  • Dockerfile由多条指令组成,每条指令在编译镜像时完成某些功能

  • 每条指令由指令+参数组成,以逗号分隔

  • 指令使用大写字母,参数使用小写字母,#表示注释

  • 指令从上到下执行,每一条指令都会创建提交一个新的镜像层(bootfs, rootfs(基础镜像centos/tomcat), image(jdk/tomcat...), image),在run的时候在镜像的顶层增加可写容器层(container)形成容器进行运行

7.4,dockerfile常用指令

FROM										#基础镜像指令,一切由此开始构建(BASE IMAGE,如:centos)
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建时需要运行的命令
ADD #添加内容(IMAGE,如:emacs,apache,tomcat等)
COPY #类似ADD,将文件拷贝到镜像中
WORKDIR #镜像的工作目录(进入镜像所在的目录,默认是根目录/)
VOLUME #挂载的目录
EXPOSE #指定暴露端口
CMD #指定容器启动时要运行的命令(如:CMD echo),只有最后一个生效
ENTRYPOINT #指定容器启动时要运行的命令,可追加命令(追加命令是直接追加到其后的)
ONBUILD #当构建一个被继承 dockerfile,会运行ONBUILD,触发指令
ENV #构建时设置环境变量(构建一个键值对,常量)

7.5,一些例子(可以如7.2所述,看看别人是怎么写的)

DockerHub中99%的镜像都是从FROM scratch开始的,scratch是一个空镜像,只能用于构建其他镜像。

'''例子一,为官方的centos镜像加入vim以及ifconfig命令'''
===========dockerfile文件
FROM centos
MAINTAINER zhang<15009202810@163.com> ENV MYPATH /usr/local
WORKDIR $MYPATH RUN yum -y install vim
RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH
CMD echo '----end----'
CMD /bin/bash ===========生成镜像
docker build -f mydockerfile-centos -t zhang:centos:02 . ===========生成的镜像
zhang/centos 02 f86b612c2f9e 4 hours ago 295MB ===========运行
root@VM-0-11-centos dockerfile]# docker run -it f86b612c2f9e
[root@03a66e354d06 local]# pwd
/usr/local
[root@03a66e354d06 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.6 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:06 txqueuelen 0 (Ethernet)
RX packets 7 bytes 586 (586.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@03a66e354d06 local]# vim c;?;?
~ ~
'''例子二,CMD和ENTRYPOINT的区别'''
'''CMD V1'''
===========dockerfile文件
FROM centos
CMD ["ls","-a"] ===========生成镜像
docker build -f dockerfile-cmd-test -t cmd-test:01 . ===========生成的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
cmd-test 01 09620dfdb9ab 3 seconds ago 209MB ===========运行
docker run 09620dfdb9ab #可以运行
docker run 09620dfdb9ab -l #报错(不追加,相当于运行-l)
docker run 09620dfdb9ab ls -l #可以运行(CMD最后一个生效,相当于运行ls -l) '''ENTRYPOINT V1'''
===========dockerfile文件
FROM centos
ENTRYPOINT ["ls","-a"] ===========生成镜像
docker build -f dockerfile-entropy-test -t entrypoint-test . ===========生成的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
entrypoint-test latest 51d3b39d0e6a About a minute ago 209MB ===========运行
docker run 09620dfdb9ab #可以运行
docker run 09620dfdb9ab -l #可以运行(追加,相当于运行ls -a -l)
docker run 09620dfdb9ab ls -l #报错(相当于运行ls -a ls -l)
'''例子三,制作tomcat镜像'''
需要准备:tomcat压缩包,jdk压缩包

7.6,dockerfile命令汇总,详解,分类及建议

参看:

Docker实战-编写Dockerfile

docker之Dockerfile实践

必看的dockerfile禁忌与建议!

命令详解
===========================================================================================================
指令:FROM
功能描述:设置基础镜像,一切由此开始构建
语法:FROM < image>[:< tag> | @< digest>]
提示:镜像都是从一个基础镜像(操作系统或其他镜像)生成,可以在一个Dockerfile中添加多条FROM指令
注意:如果忽略tag选项,会使用latest镜像
===========================================================================================================
指令:MAINTAINER
功能描述:设置镜像作者
语法:MAINTAINER < name>
============================================================================================================
指令:RUN
功能描述:
语法:RUN < command>
RUN [“executable”,”param1”,”param2”]
提示:RUN指令会生成容器,在容器中执行脚本,容器使用当前镜像,脚本指令完成后,Docker Daemon会将该容器提交为一个中间镜像,供后面的指令使用
补充:RUN指令第一种方式为shell方式,使用/bin/sh -c < command>运行脚本,可以在其中使用\将脚本分为多行
RUN指令第二种方式为exec方式,镜像中没有/bin/sh或者要使用其他shell时使用该方式,其不会调用shell命令
例子:RUN source $HOME/.bashrc;\
echo $HOME RUN [“/bin/bash”,”-c”,”echo hello”] RUN [“sh”,”-c”,”echo”,”$HOME”] 使用第二种方式调用shell读取环境变量
============================================================================================================
指令:CMD
功能描述:设置容器的启动命令
语法:CMD [“executable”,”param1”,”param2”]
CMD [“param1”,”param2”]
CMD < command>
提示:CMD第一种、第三种方式和RUN类似,第二种方式为ENTRYPOINT参数方式,为entrypoint提供参数列表
注意:Dockerfile中只能有一条CMD命令,如果写了多条则最后一条生效
============================================================================================================
指令:LABEL
功能描述:设置镜像的标签
延伸:镜像标签可以通过docker inspect查看
格式:LABEL < key>=< value> < key>=< value> …
提示:不同标签之间通过空格隔开
注意:每条指令都会生成一个镜像层,Docker中镜像最多只能有127层,如果超出Docker Daemon就会报错,如LABEL ..=.. <假装这里有个换行> LABEL ..=..合在一起用空格分隔就可以减少镜像层数量,同样,可以使用连接符\将脚本分为多行
镜像会继承基础镜像中的标签,如果存在同名标签则会覆盖
============================================================================================================
指令:EXPOSE
功能描述:设置镜像暴露端口,记录容器启动时监听哪些端口
语法:EXPOSE < port> < port> …
延伸:镜像暴露端口可以通过docker inspect查看
提示:容器启动时,Docker Daemon会扫描镜像中暴露的端口,如果加入-P参数,Docker Daemon会把镜像中所有暴露端口导出,并为每个暴露端口分配一个随机的主机端口(暴露端口是容器监听端口,主机端口为外部访问容器的端口)
注意:EXPOSE只设置暴露端口并不导出端口,只有启动容器时使用-P/-p才导出端口,这个时候才能通过外部访问容器提供的服务
============================================================================================================
指令:ENV
功能描述:设置镜像中的环境变量
语法:ENV < key>=< value>…|< key> < value>
注意:环境变量在整个编译周期都有效,第一种方式可设置多个环境变量,第二种方式只设置一个环境变量
提示:通过${变量名}或者 $变量名使用变量,使用方式${变量名}时可以用${变量名:-default} ${变量名:+cover}设定默认值或者覆盖值
ENV设置的变量值在整个编译过程中总是保持不变的
============================================================================================================
指令:ADD
功能描述:复制文件到镜像中
语法:ADD < src>… < dest>|[“< src>”,… “< dest>”]
注意:当路径中有空格时,需要使用第二种方式
当src为文件或目录时,Docker Daemon会从编译目录寻找这些文件或目录,而dest为镜像中的绝对路径或者相对于WORKDIR的路径
提示:src为目录时,复制目录中所有内容,包括文件系统的元数据,但不包括目录本身
src为压缩文件,并且压缩方式为gzip,bzip2或xz时,指令会将其解压为目录
如果src为文件,则复制文件和元数据
如果dest不存在,指令会自动创建dest和缺失的上级目录
============================================================================================================
指令:COPY
功能描述:复制文件到镜像中
语法:COPY < src>… < dest>|[“< src>”,… “< dest>”]
提示:指令逻辑和ADD十分相似,同样Docker Daemon会从编译目录寻找文件或目录,dest为镜像中的绝对路径或者相对于WORKDIR的路径
============================================================================================================
指令:ENTRYPOINT
功能描述:设置容器的入口程序
语法:ENTRYPOINT [“executable”,”param1”,”param2”]
ENTRYPOINT command param1 param2(shell方式)
提示:入口程序是容器启动时执行的程序,docker run中最后的命令将作为参数传递给入口程序
入口程序有两种格式:exec、shell,其中shell使用/bin/sh -c运行入口程序,此时入口程序不能接收信号量
当Dockerfile有多条ENTRYPOINT时只有最后的ENTRYPOINT指令生效
如果使用脚本作为入口程序,需要保证脚本的最后一个程序能够接收信号量,可以在脚本最后使用exec或gosu启动传入脚本的命令
注意:通过shell方式启动入口程序时,会忽略CMD指令和docker run中的参数
为了保证容器能够接受docker stop发送的信号量,需要通过exec启动程序;如果没有加入exec命令,则在启动容器时容器会出现两个进程,并且使用docker stop命令容器无法正常退出(无法接受SIGTERM信号),超时后docker stop发送SIGKILL,强制停止容器
例子:FROM ubuntu <换行> ENTRYPOINT exec top -b
============================================================================================================
指令:VOLUME
功能描述:设置容器的挂载点
语法:VOLUME [“/data”]
VOLUME /data1 /data2
提示:启动容器时,Docker Daemon会新建挂载点,并用镜像中的数据初始化挂载点,可以将主机目录或数据卷容器挂载到这些挂载点
============================================================================================================
指令:USER
功能描述:设置RUN CMD ENTRYPOINT的用户名或UID
语法:USER < name>
============================================================================================================
指令:WORKDIR
功能描述:设置RUN CMD ENTRYPOINT ADD COPY指令的工作目录
语法:WORKDIR < Path>
提示:如果工作目录不存在,则Docker Daemon会自动创建
Dockerfile中多个地方都可以调用WORKDIR,如果后面跟的是相对位置,则会跟在上条WORKDIR指定路径后(如WORKDIR /A WORKDIR B WORKDIR C,最终路径为/A/B/C)
============================================================================================================
指令:ARG
功能描述:设置编译变量
语法:ARG < name>[=< defaultValue>]
注意:ARG从定义它的地方开始生效而不是调用的地方,在ARG之前调用编译变量总为空,在编译镜像时,可以通过docker build –build-arg < var>=< value>设置变量,如果var没有通过ARG定义则Daemon会报错
可以使用ENV或ARG设置RUN使用的变量,如果同名则ENV定义的值会覆盖ARG定义的值,与ENV不同,ARG的变量值在编译过程中是可变的,会对比使用编译缓存造成影响(ARG值不同则编译过程也不同)
例子:ARG CONT_IMAG_VER <换行> RUN echo $CONT_IMG_VER
ARG CONT_IMAG_VER <换行> RUN echo hello
当编译时给ARG变量赋值hello,则两个Dockerfile可以使用相同的中间镜像,如果不为hello,则不能使用同一个中间镜像
============================================================================================================
指令:ONBUILD
功能描述:设置自径想的编译钩子指令
语法:ONBUILD [INSTRUCTION]
提示:从该镜像生成子镜像,在子镜像的编译过程中,首先会执行父镜像中的ONBUILD指令,所有编译指令都可以成为钩子指令 ONBUILD流程
1,编译时,读取所有ONBUILD镜像并记录下来,在当前编译过程中不执行指令
2,生成镜像时将所有ONBUILD指令记录在镜像的配置文件OnBuild关键字中
3,子镜像在执行FROM指令时会读取基础镜像中的ONBUILD指令并顺序执行,如果执行过程中失败则编译中断;当所有ONBUILD执行成功后开始执行子镜像中的指令
4,子镜像不会继承基础镜像中的ONBUILD指令
============================================================================================================
指令:STOPSIGNAL
功能描述:设置容器退出时,Docker Daemon向容器发送的信号量
语法:STOPSIGNAL signal
提示:信号量可以是数字或者信号量的名字,如9或者SIGKILL,信号量的数字说明在Linux系统管理(https://blog.csdn.net/qq_29999343/article/details/78166574)中有简单介绍

docker2-镜像原理及创建新的镜像的更多相关文章

  1. docker commit命令创建新的镜像

    docker commit命令创建新的镜像 1.运行容器 2.修改容器 3.将容器保存为新容器 (1)运行容器 [root@cmdb-server docker]# docker run -ti ce ...

  2. docker的使用---创建新的镜像(通过修改容器,个人练手理解过程记录,不推荐使用)

    docker基础命令 ##列出docker客户端命令 docker docker container --help ##显示docker的版本和信息 docker --version docker v ...

  3. docker 创建新的镜像到私有仓库

    docker:/data# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bd6db4127a9e centos &q ...

  4. Docker(42)- 镜像原理之联合文件系统

    前言 学习狂神老师的 Docker 系列课程,并总结 镜像是什么 镜像是一种轻量级.可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件 他包含运行某个软件所需的所有内容,包括代码.运行时 ...

  5. Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较

    1.概述 创建Docker镜像的方式有三种 docker commit命令:由容器生成镜像: Dockerfile文件+docker build命令: 从本地文件系统导入:OpenVZ的模板. 关于这 ...

  6. docker使用现有容器生成新的镜像

    /*运行docker run后 --则进入该容器里了 我们做一些变更,比如安装一些东西 ,然后针对这个容器进行创建新的镜像 */ 基本形式: docker commit -m "change ...

  7. 使用Dockerfile创建一个tomcat镜像,并运行一个简单war包

    docker已经看了有一段时间了,对镜像和容器也有了一个大致了解,参考书上的例子制作一个tomcat镜像,并简单运行一个HelloWorld.war 1.首先下载linux环境的tomcat和jdk, ...

  8. 【译】从现有的容器里创建新的Docker镜像

    如果你修改了一个容器的内容,你可以使用docker commit命令将现有的容器状态保存为一个镜像. 下面的例子展示了如何修改一个基于oraclelinux:6.6的容器使得其能够运行Apache H ...

  9. 创建新镜像-从已创建的容器中更新镜像并提交镜像(以Nginx为例)

    目标:现在我们主要是修改nginx的index.html,然后做一个新镜像 1.基于nginx:1.12运行一个容器 docker run -d -p 8080:80 --name nginx ngi ...

随机推荐

  1. 面试题:ArrayList、LinkedList、Vector三者的异同?

    面试题:ArrayList.LinkedList.Vector三者的异同? 同:三个类都是实现了List接口(Collection的子接口之一),存储数据的特点相同:存储有序的.可重复的数据不同: * ...

  2. 爬虫:获取动态加载数据(selenium)(某站)

    如果网站数据是动态加载,需要不停往下拉进度条才能显示数据,用selenium模拟浏览器下拉进度条可以实现动态数据的抓取. 本文希望找到某乎某话题下讨论较多的问题,以此再寻找每一问题涉及的话题关键词(侵 ...

  3. chardet模块

    import chardet chardet.detect(f.read())检测哪种编码

  4. MSSQL·备份数据库中的单表

    阅文时长 | 0.11分钟 字数统计 | 237.6字符 主要内容 | 1.引言&背景 2.声明与参考资料 『MSSQL·备份数据库中的单表』 编写人 | SCscHero 编写时间 | 20 ...

  5. 【MySQL】MySQL-front等客户端连接MySQL_8.0等失败的解决办法

    ALTER USER 'root'@'localhost' IDENTIFIED BY '新的密码' PASSWORD EXPIRE NEVER; ALTER USER 'root'@'localho ...

  6. Ubuntu相关系统配置问题

    1.Ubuntu 16.04下安装VMware Tools 由于下载的是ubuntu-16.04.3-desktop-amd64,需要安装vmware tools,原来提取提取文件再解压的方式比较麻烦 ...

  7. 在linux下把jsp文件 打包war格式(centos7)

    在linux下把jsp文件 打成war包 chmod -R 777 /data/jdk8u242-b08/bincd /data/TongWeb61712/deployment/TestCase//d ...

  8. xrandr 直接输这个能显示可用的分辨和当前的分辨率 xrandr -s 1920x1200就设置成指定的分辨率

    利用 xrandr 命令修改屏幕分辨率 时间  2016-10-29 原文   http://blog.csdn.net/mao0514/article/details/52965700   问题背景 ...

  9. shell判断一个变量是否为空方法总结

    shell中如何判断一个变量是否为空 shell编程中,对参数的错误检查项中,包含了变量是否赋值(即一个变量是否为空),判断变量为空方法如下: 1.变量通过" "引号引起来 1 2 ...

  10. CentOS 7系统启动后怎么从命令行模式切换到图形界面模式

    CentOS 7系统启动后怎么从命令行模式切换到图形界面模式原创传智播客官方博客 最后发布于2020-04-08 15:44:43 阅读数 88 收藏展开一.存在问题 在VMware虚拟机中成功安装c ...