镜像构建介绍

在什么情况下我们需要自己构建镜像那?

(1)当我们找不到现有的镜像,比如自己开发的应用程序

(2)需要在镜像中加入特定的功能

docker构建镜像有两种方式:docker commit命令与Dockerfile构建文件

docker commit构建镜像

dockercommit构建进行主要有三步:

  • 运行容器
  • 修改容器
  • 将容器保存为新的镜像

比如在centos镜像中安装vim编辑器并存为新的镜像

(1)运行容器

[root@ken1 docker]# docker run -it centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a02a4930cb5d: Pull complete
Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Status: Downloaded newer image for centos:latest

(2)安装vim编辑器

vim编辑器确认没有安装

[root@69f501e858a6 /]# vim
bash: vim: command not found

进行安装

[root@69f501e858a6 /]# yum install vim -y

(3)保存为新得镜像

首先查看当前运行的镜像

[root@ken1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69f501e858a6 centos "/bin/bash" 2 minutes ago Up 2 minutes quizzical_torvalds

使用commit存为新的镜像

[root@ken1 ~]# docker commit 69f501e858a6 centos-vim
sha256:42083b89a179368bc29a8f40d14f8824990183c8e4b28fd84411d440c26342e5

69f501e858a6是运行容器的ID使用name下面的名称也行
centos-vim是新镜像的名字

查看一下是否有了centos-vim镜像

重新启动新的镜像,验证是否可以使用vim编辑器

可以发现新的镜像可以使用vim编辑器了

[root@ken1 ~]# docker run -it centos-vim
[root@61d090898bad /]# vim
[root@61d090898bad /]# vim test

上面演示了如何使用commit创建新的镜像,但是docker并不建议使用这种方式创建镜像,原因如下:

  • 这是一种手工创建镜像的方式,容器出错,而且效率低且可重复性弱
  • 更重要的是。使用者并不知道镜像是如何创建出来的。里面是否有恶意程序

Dockerfile构建镜像

第一个Dockerfike

第一步:创建一个新的目录

[root@ken1 ~]# mkdir /test

第二步:编写Dockerfile

名称就叫Dockerfile,且第一个D需要大写

[root@ken1 ~]# cat Dockerfile
FROM centos
RUN yum install vim -y

FROMcentos表示使用centos这个基础镜像

RUN表示在centos上安装vim编辑器

第三步:构建镜像

[root@ken1 ~]# docker build -t centos-vim2 .

-t后面指定新的镜像的标签名(tag)

. 最后的一个点指明docker context为当前目录。docker默认会从build context中查找 Dockerfile文件,我们也可以通过-f参数指定Dockerfile的位置

第四步:查看镜像

查看镜像分层结构

docker history会显示镜像的构建历史,也就是Dockerfile的执行过程。

Dcokerfile常用指令

  1.FROM

指定base镜像

  2. MAINTAINER

设置镜像的作者。可以是任意的字符

  3.COPY

将文件从build context复制到镜像

COPY支持两种格式:COPY src dest 和 COPY [“src”,”dest”]

注意:src只能制动build context中的文件或目录即在和Dockerfile同目录下才可以

  4.ADD

与COPY类似,从build context复制文件到镜像。

不同的是,如果src是归档文件(tar,zip,tgz,xz),文件会被自动接要到dest

  5.ENV

设置环境变量,环境变量可被后面的指令使用,例如:

ENV name ken RUN echo $name

  6.EXPOSE

指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来

  7.VOLUME

将文件或目录声明为volume

  8.WORKDIR

为后面的RUN,ENTRYPINT,ADD,COPY指令设置镜像中的当前工作目录

  9.RUN

在容器中运行指定的命令

  10.CMD

容器启动时运行指定的命令

dockerfile中可以多个CMD指令,但是只要最后一个生效。CMD可以被docker run之后的参数替换

  11.ENTRYPOINT

设置容器启东市的命令

dockerfile中可以有多个ENTRYPOINT,但是只有最后一个生效。

CMD或者docker run之后的参数会被当做参数传递给ENTERYPOINT.

Dockerfile演示

下面演示一个比较全面的dockerfile

 
[root@ken1 test]# cat Dockerfile
#my Dockerfile
FROM busybox
MAINTAINER ken
WORKDIR /ken
RUN touch test
COPY ["ken1","."]
ADD ["wordpress.tar.gz","."]
ENV name "ken"
 

注意:Dockerfile支持以#开头的注释

构建镜像

 
[root@ken1 test]# docker build -t myimage .
Sending build context to Docker daemon 4.281MB
Step 1/7 : FROM busybox
---> 3a093384ac30
Step 2/7 : MAINTAINER ken
---> Running in 2a73a83507ce
Removing intermediate container 2a73a83507ce
---> 8c3df9b3d823
Step 3/7 : WORKDIR /ken
---> Running in 31c6f9fe2195
Removing intermediate container 31c6f9fe2195
---> a458cf986072
Step 4/7 : RUN touch test
---> Running in e1b08ebd363c
Removing intermediate container e1b08ebd363c
---> 41601920009a
Step 5/7 : COPY ["ken1","."]
---> 2ebfa0933fca
Step 6/7 : ADD ["wordpress.tar.gz","."]
---> d0ad29d3aa34
Step 7/7 : ENV name "ken"
---> Running in fceae6e20e63
Removing intermediate container fceae6e20e63
---> 7efe0600e48f
Successfully built 7efe0600e48f
Successfully tagged myimage:latest
 

查看镜像

运行该镜像

[root@ken1 test]# docker run -it myimage
/ken # ls
ken1 test wordpress
/ken # echo $name
ken
  • 可以发现当前工作目录为/ken,且自动创建
  • ken1是我们从docker context目录中复制过去的
  • test是使用touch创建的
  • wordpres压缩包已经被自动解压
  • $name为变量值为ken

RUN,CMD,ENTRYPOINT

这三个指令看上去很类似,很容易混淆,简单来说:

  • RUN:执行命令创建新的镜像层,RUN经常用于安装软件包
  • CMD:设置容器启动后默认执行的命令及参数,但CMD能够被docker run后面跟的命令行参数替换
  • ENTRYPOINT:配置容器启动时运行的命令
  1. 使用 RUN 指令安装应用和软件包,构建镜像。
  2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
  3. 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

Shell和Exec格式

可以用两种方式制定RUN,CMD,ENTRYPOINT要运行的命令:shell格式以及exec格式

shell举例:

RUN echo "hello world"
CMD echo "hello world"
ENTRYPOINT echo "hello world"

当指令执行时,shell格式底层会调用/bin/sh -c [command].例如下面的dockerfile片段:

ENV name ken  

ENTRYPOINT echo "Hello, $name"

执行 docker run <image> 将输出:

Hello, ken

注意环境变量 name 已经被值 ken替换。

下面来看 Exec 格式。

Exec 格式

<instruction> [“executable”, “param1”, “param2”, …]

例如:

RUN ["yum", "install", "python3"]  

CMD ["/bin/echo", "Hello world"]  

ENTRYPOINT ["/bin/echo", "Hello world"]

当指令执行时,会直接调用 <command>,不会被 shell 解析。
例如下面的 Dockerfile 片段:

ENV name ken

ENTRYPOINT ["/bin/echo", "Hello, $name"]

运行容器将输出:

Hello, $name

注意环境变量“name”没有被替换。
如果希望使用环境变量,照如下修改

ENV name ken  

ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

运行容器将输出:

Hello, ken

CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。

Docker镜像构建的两种方式(六)的更多相关文章

  1. Docker镜像构建的两种方式(六)--技术流ken

    镜像构建介绍 在什么情况下我们需要自己构建镜像那? (1)当我们找不到现有的镜像,比如自己开发的应用程序 (2)需要在镜像中加入特定的功能 docker构建镜像有两种方式:docker commit命 ...

  2. Docker镜像构建的两种方式

    关于Docker里面的几个主要概念 这里用个不太恰当的比方来说明. 大家肯定安装过ghost系统,镜像就像是ghost文件,容器就像是ghost系统.你可以拿别人的ghost文件安装系统(使用镜像运行 ...

  3. SpringBoot 构建 Docker 镜像的最佳 3 种方式

    本文将介绍3种技术,通过 Maven 把 SpringBoot 应用构建成 Docker 镜像. (1)使用 spring-boot-maven-plugin 内置的 build-image. (2) ...

  4. docker 私有仓库的两种方式

    1.使用官方默认的registry镜像构建本地仓库 这种方式适用于小规模的镜像仓库储存,没有Ui界面 (1)docker pull registry (2)docker run -d -p 5000: ...

  5. k8s在线和离线批量修改镜像地址的两种方式

    背景介绍 有时往k8s集群里部署一堆服务的时候,需要拷贝一堆yaml文件,当然还有其他方式部署,例如通过建立一个一个的流水线等方式,但是这太慢了,虽然是一劳永逸,但是如果说仅仅是部署一次那就可太费劲了 ...

  6. Docker学习系列(三)Docker搭建gitlab的两种方式

    一.直接下载docker-ce 1.拉取gitlab/gitlab-ce Randy:~ Randy$ docker pull gitlab/gitlab-ce Using default tag: ...

  7. Docker镜像构建(五)

    Docker 镜像介绍 Docker镜像构建分为两种,一种是手动构建,另一种是Dockerfile(自动构建) 手动构建docker镜像 案例:我们基于centos镜像进行构建,制作自己的nginx镜 ...

  8. 制作Docker镜像的两种方式

    此文已由作者朱笑天授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 一.使用docker commit命令制作docker镜像 1. pull一个centos6.6的基础镜像, ...

  9. Docker + .NET Core(三)-两种发布方式

    原文:Docker + .NET Core(三)-两种发布方式 第一种,自己手写dockerfile发布,上传至hubDocker 正常发布到文件夹中,发布文件上传至linux机器上.如 /www/a ...

随机推荐

  1. 【算法•日更•第四十三期】QQ for linux

    废话不多说,直接看一张图: 没错,这是QQ,但是这有什么稀奇的?但是在Linux上使用QQ就很稀奇了. 众所周知,腾讯早就已经对Linux下的QQ和微信停止了服务,即便是网页版也不能用,通信这一直是小 ...

  2. 微信小程序之蓝牙广播信息

    期初第一次做蓝牙开锁的时候遇到的最尖锐的问题就是ios设备如何对获取的广播信息进行读取,大概用了4中方式,都无法解决,最后不得不求助官方人员.给了一个方法,大家可以参考.在此附图: 由于mac地址是6 ...

  3. SpringBoot整合WebSocket实现前后端互推消息

    小编写这篇文章是为了记录实现WebSocket的过程,受不了啰嗦的同学可以直接看代码. 前段时间做项目时设计了一个广播的场景,具体业务不再赘述,最终要实现的效果就是平台接收到的信息实时发布给所有的用户 ...

  4. 第六篇Scrum冲刺博客--Interesting-Corps

    第六篇Scrum冲刺博客 站立式会议 1.会议照片 2.队友完成情况 团队成员 昨日完成 今日计划 鲍鱼铭 搜索页面以及音乐详情页面数据导入及测试 各界面数据请求云函数设计及实现 叶学涛 进行页面的优 ...

  5. 简明python教程--读后感--推荐给python新手

    原书名: A Byte of Python作者:  Swaroop, C. H.译者: 沈洁元出版社: 未知  优点     1. 讲解很详细,很基础,适合入门,对编译器也做了简单的介绍     2. ...

  6. python 报错错误集合——更新中

    1. #!/usr/bin/env python # -*- coding:utf-8 -*- 'one #报错 File "C:\Users\shuxiu\Desktop\test.py& ...

  7. Hive 常见面试题(一)

    面试题: hive 内部表和外部表的区别? hive 是如何实现分区的? Hive 有哪些方式保存元数据,各有哪些优缺点? hive中order by.distribute by.sort by和cl ...

  8. 借助FRP反向代理实现内网穿透

    一.frp 是什么? frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP.UDP.HTTP.HTTPS 等多种协议.可以将内网服务以安全.便捷的方式通过具有公网 IP 节点的中转暴露到公 ...

  9. 关于Chrome浏览器自动同步的问题

    Chrome浏览器是开发者最喜欢的浏览器,没有之一,那么公司办公和在家办公的话数据需要有一致性,这个时候就用到了浏览器的自动同步的功能 因为网络的问题,谷歌账户很难登录,基本需要VPN翻墙处理之后才能 ...

  10. Android开发禁止首次进入activity弹出软键盘,限制屏幕只能竖屏或者横屏展示

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 只需在在Manifest.xml中设定activity的属性为: android:windowSoft ...