在 docker 中,镜像的结构是以层次划分的,也就是可以在每一层上添加自己的修改,变成新的镜像。

docker 两种打包方式如下:

  • commit
  • build

docker commit

注意: docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 docker commit 定制镜像,定制镜像应该使用 Dockerfile 来完成。

镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。比如我们所使用的都是来自于 Docker Hub 的镜像,比如不同的linux系统版本有不同的官方基础镜像,如 CentOs,Ubuntu。直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。接下来看看 docker run 如何定制镜像。

以基础的 centos 镜像为例,我们想在这个镜像上安装 vim。

docker image ls -a

进入容器内安装

$ docker exec -it centos bash
root@3729b97e8226:/# yum install vim
exit
我们以交互式终端方式进入 centos 容器,并执行了 bash 命令,也就是获得一个可操作的 Shell。
然后,我们用 yum 安装 vim。
 

要知道,当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个 docker commit 命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
docker commit 的语法格式为:

docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

我们可以用下面的命令来保存新修改的镜像:

$ docker commit \
--author "Nobody <nobody@gmail.com>" \
--message "安装了vim" \
centos \
centos:v2
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214

我们可以在 docker image ls 中看到这个新定制的镜像:

$ docker image ls centos
REPOSITORY TAG IMAGE ID CREATED SIZE
centos v2 07e334659748 9 seconds ago 272.5 MB
centos latest e43d811ce2f4 4 weeks ago 272 MB

我们还可以用 docker history 具体查看镜像内的历史记录,如果比较 nginx:latest 的历史记录

docker build

相比 docker commit,此命令就简单很多。直接新建 DockerFile 文件:

touch DockerFile

vim ./DockerFile

添加以下内容:

FROM centos
RUN yum install -y vim
意思是基于 centos 镜像基础上
然后使用 run 命令执行命令:yum install -y vim 
 
使用此文件来进行打包:
docker build -t blackbinbin/docker-centos-vim ./

打包过程也非常有意思

step1 是直接使用 centos 镜像。step2 是创建一个临时的容器来执行 yum install

这里是符合我们上面所说的 docker 镜像是层次结构的结论,在之后的文章我们会详细阐述为什么 docker 会使用这样的文件结构形式。

最后移除临时的容器

并且打包成新镜像,ID=8bf3a6c43631 
 

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。这种描述性语言,比 commit 更符合工程化的思想,因为只要确定 DockerFile 任何人都可以构建出来一样的镜像,便于迭代,这也是为什么搞 docker 和 k8s 的经常会被认为是面向 yaml 编程,描述性语言的利用,让构建和运维的流程更清晰,便于沟通和迭代。

初试Docker-打包构建镜像的更多相关文章

  1. IDEA使用Docker插件构建镜像

    IDEA使用Docker插件构建镜像 记一次坑  第一次插件docker-maven-plugin的 配置文件中没写远程主机的地址 <dockerHost>http://192.168.1 ...

  2. docker入门——构建镜像

    前面我们已经介绍了如何拉取已经构建好的带有定制内容的Docker镜像,那么如何构建自己的镜像呢? 构建Docker镜像有以下两种方法: 使用docker commit命令. 使用docker buil ...

  3. docker之构建镜像

    构建Docker镜像有以下两种方法: 使用docker commit命令. 使用docker build命令和 Dockerfile 文件. 在这里并不推荐使用docker commit来构建镜像,而 ...

  4. windows环境下,spring boot服务使用docker打包成镜像并推送到云服务器私有仓库

    最近在淘宝上学习springcloud教程,其中有几节课是讲解讲本地springboot服务打包成镜像并推送到云服务器私有仓库,但是教程里面用的事Mac环境,我的是Windows环境,而且课程里面没有 ...

  5. docker学习构建镜像---第三章节

    一.docker镜像使用 运行docker容器时,使用的镜像如果在本地不存在,docker会自动从docker镜像仓库中下载,默认是从docker hub公共镜像源下载 在这里,我们需要了解:管理和使 ...

  6. springboot 通过docker 打包编译镜像

    添加plugin <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...

  7. docker(四) 使用Dockerfile构建镜像

    下面以一个例子来演示构建镜像的过程. #在/tmp目录下演示 cd tmp mkdir build-redis-image 1.创建Dockerfile文件 vim Dockerfile 并写入如下内 ...

  8. Docker:dockerfile自动构建镜像 [六]

    一.手动docker镜像的缺点 相对于手动制作的docker镜像,使用dockerfile构建的镜像有以下优点: 1.dockerfile只有几kb,便于传输 2.使用dockerfile构建出来的镜 ...

  9. docker 构建镜像 centos7 nginx php

    #docker 构建镜像(Dockerfile) centos 7.4.1078镜像制作 nginx镜像制作(以前面centos7镜像为基础) Nginx+php镜像制作 更多操作实例,查看git里的 ...

随机推荐

  1. 鸿蒙内核源码分析(进程镜像篇)|ELF是如何被加载运行的? | 百篇博客分析OpenHarmony源码 | v56.01

    百篇博客系列篇.本篇为: v56.xx 鸿蒙内核源码分析(进程映像篇) | ELF是如何被加载运行的? | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...

  2. HDFS 10 - HDFS 的联邦机制(Federation 机制)

    目录 1 - 为什么需要联邦 2 - Federation 架构设计 3 HDFS Federation 的不足 版权声明 1 - 为什么需要联邦 单 NameNode 的架构存在的问题:当集群中数据 ...

  3. NER为什么那么难

    命名实体识别(Name Entity Recognition) 是自然语言处理中一个比较基础的问题.要解决的问题是,从unstructure的文本当中找到实体并归类.当然我这么定义已经有了一定的bia ...

  4. 解决VSCODE"因为在此系统上禁止运行脚本"报错

    在VSCODE中使用yarn,结果报错: 找了下原因,是因为PowerShell执行策略的问题. 解决方法:   以管理员身份运行vscode;  执行:get-ExecutionPolicy,显示R ...

  5. 题解 Wide Swap

    题目传送门 题目大意 给出一个长度为 \(n\) 的排列 \(a_{1,2,...,n}\) 以及常数 \(k\),每次可以交换两个数 \(a_i,a_j\) 当且仅当 \(j-i\ge k \tex ...

  6. CF125E MST company (凸优化+MST)

    qwq自闭的一个题 我来修锅辣!!!!!! 这篇题解!可以\(hack\)全网大部分的做法!!! 首先,我们可以把原图中的边,分成两类,一类是与\(1\)相连,另一类是不与\(1\)相连. 原题就转化 ...

  7. 01_vue实例_数据_方法

    创建实例 var vm = new Vue( { //选项 } ) 数据对象 // 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var vm = ...

  8. 讲讲java中线程池的实现

    今天跟一个同学谈到java中的线程池的实现,才发现有些知识点已经记不清了,所以特意把源码打开,对官方文档做了些说明. 其实这些理解了之后,读懂源码应该是没多大问题了,有感兴趣的小伙伴们可以看完说明后自 ...

  9. CORS+XSS的漏洞利用payload

    之前有人问我有没有CORS+XSS的利用姿势,翻了一下国内貌似都没有利用姿势于是就写了这篇文章!!! 首先找到一个反射xss,然后使用xss加载javascript代码达到跨域劫持目的payload如 ...

  10. perl 不支持多条件比较

    perl 不支持多条件比较,if(a < $var < b),这个条件表达式在C语言里面是支持的,但是在Perl中必须写成if(($var > a)&&($var & ...