docker基础——构建镜像

某些情况下我们不得不自己构建镜像,比如:

  • 找不到现成的镜像,比如自己开发的应用程序。
  • 需要在镜像中加入特定的功能,比如官方镜像几乎都不提供 ssh。

Docker 提供了两种构建镜像的方法:

  • docker commit 命令
  • Dockerfile 构建文件

一.docker commit

Docker 并不建议用户通过这种方式构建镜像,这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱,
更重要的:使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审计,存在安全隐患。
1.步骤
docker commit 命令是创建新镜像最直观的方法,其过程包含三个步骤:

  1. 运行容器
  2. 修改容器
  3. 将容器保存为新的镜像

2.示例

# 启动容器,-it 参数的作用是以交互模式进入容器,并打开终端
[root@VM_0_46_centos ~] docker run -it centos
[root@31b880ff4333 /]

# 安装vim
[root@31b880ff4333 /] vim test.sh
bash: vim: command not found
[root@31b880ff4333 /] yum install -y vim

# 在新窗口中查看当前运行的容器,silly_blackburn 是 Docker 为我们的容器随机分配的名字
[root@VM_0_46_centos ~] docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS                  NAMES
31b880ff4333        centos              "/bin/bash"          About a minute ago   Up About a minute                          silly_blackburn
170cb8aae061        httpd               "httpd-foreground"   27 hours ago         Up 27 hours         0.0.0.0:8000->80/tcp   wonderful_grothendieck

# 执行 docker commit 命令将容器保存为镜像
[root@VM_0_46_centos ~] docker commit silly_blackburn centos_with_vim
sha256:7b329b86dc1af27a67839d9658a8683b1d199d2d7af6452cb3eb0b6715094e7c

# 查看镜像,centos_with_vim镜像稍大一些
[root@VM_0_46_centos ~] docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos_with_vim     latest              7b329b86dc1a        4 seconds ago       286MB
centos              latest              0f3e07c0138f        2 months ago        220MB

二.Dockerfile

用 Dockerfile(推荐方法)构建镜像,底层也是 docker commit 一层一层构建新镜像的。学习 docker commit 能够帮助我们更加深入地理解构建过程和镜像的分层结构。
1.命令

# 创建文件
vim Dockerfile
FROM centos
RUN yum install -y vim

# 运行 docker build 命令构建镜像
# -t 给新镜像命名:centos-with-vim-dockerfile
# 末尾的 . 指明 build context 为当前目录。Docker 默认会从 build context 中查找 Dockerfile 文件
# 也可以通过 -f 参数指定 Dockerfile 的位置。
[root@VM_0_46_centos mydocker] docker build -t centos-with-vim-dockerfile .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 0f3e07c0138f
Step 2/2 : RUN yum install -y vim
 ---> Running in 46688ed52460
······

2.制作过程
首先 Docker 将 build context 中的所有文件发送给 Docker daemon。
build context 为镜像构建提供所需要的文件或目录。

Dockerfile 中的 ADD、COPY 等命令可以将 build context 中的文件添加到镜像。此例中,build context 为当前目录 ,该目录下的所有文件和子目录都会被发送给 Docker daemon。

执行 FROM,将 centos 作为 base 镜像
执行 RUN,安装 vim
启动临时容器,在容器中通过yum安装 vim
安装成功后,将容器保存为镜像,这一步底层使用的是类似 docker commit 的命令。
删除临时容器

# 查看镜像的构建历史,docker history展示了镜像的分层结构,每一层由上至下排列。
[root@VM_0_46_centos mydocker] docker history centos-with-vim-dockerfile
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
670bd82d6cae        15 minutes ago      /bin/sh -c yum install -y vim                   66.8MB              
0f3e07c0138f        2 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           2 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           2 months ago        /bin/sh -c #(nop) ADD file:d6fdacc1972df524a…   220MB  

Docker 会缓存已有镜像的镜像层,构建新镜像时,如果某镜像层已经存在,就直接使用,无需重新创建。

总结:Dockerfile 构建镜像的过程

  • 从 base 镜像运行一个容器。
  • 执行一条指令,对容器做修改。
  • 执行类似 docker commit 的操作,生成一个新的镜像层。
  • Docker 再基于刚刚提交的镜像运行一个新容器。
  • 重复 2-4 步,直到 Dockerfile 中的所有指令执行完毕。

3.Dockerfile 中最常用的指令
FROM
指定 base 镜像。

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

COPY
将文件从 build context 复制到镜像中。
COPY 支持两种形式:
COPY src dest
COPY [“src”, “dest”]
注意:src 只能指定 build context 中的文件或目录。

ADD
与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。

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

ENV MY_VERSION 1.3
RUN apt-get install -y mypackage=$MY_VERSION

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

VOLUME
将文件或目录声明为 volume

WORKDIR
为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录,目录不存在时会自动创建

RUN
在容器中运行指定的命令。
RUN 执行命令并创建新的镜像层,经常用于安装软件包。

ENTRYPOINT
设置容器启动时运行的命令。
Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。CMD 或 docker run 之后的参数会被当做额外的参数传递给 ENTRYPOINT。

CMD
设置容器启动后默认执行的命令及其参数
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后跟的命令替换。

三.镜像的命名

一个特定镜像的名字由两部分组成:repository 和 tag。
如果执行 docker build 时没有指定 tag,会使用默认值 latest
tag 常用于描述镜像的版本信息

参考:《每天5分钟玩转Docker容器技术》
https://item.jd.com/16936307278.html

发布了106 篇原创文章 · 获赞 8 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43667990/article/details/103625058