Linux Docker容器 镜像的详解与创建

您所在的位置:网站首页 如何制作一个镜像 Linux Docker容器 镜像的详解与创建

Linux Docker容器 镜像的详解与创建

2024-07-03 02:52| 来源: 网络整理| 查看: 265

一、什么是docker 镜像

就是把业务代码,可运行环境进行整体的打包

二、如何创建docker镜像:

现在docker官方共有仓库里面有大量的镜像,所以最基础的镜像,我们可以在公有仓库直接拉取,因为这些镜像都是原厂维护,可以得到即使的更新和修护。

Dockerfile:

我们如果想去定制这些镜像,我们可以去编写Dockerfile,然后重新bulid,最后把它打包成一个镜像,这种方式是最为推荐的方式包括我们以后去企业当中去实践应用的时候也是推荐这种方式。 在这里插入图片描述

Commit :

当然还有另外一种方式,就是通过镜像启动一个容器,然后进行操作,最终通过commit这个命令commit一个镜像,但是不推荐这种方式,虽然说通过commit这个命令像是操作虚拟机的模式,但是容器毕竟是容器,它不是虚拟机,最好还是使用dockerfile创建。

三、docker镜像的分层结构

在这里插入图片描述在这里插入图片描述

四、Docker 镜像使用

当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。

下面我们来学习:

1、管理和使用本地 Docker 主机镜像 2、创建镜像 12 列出镜像列表

我们可以使用 docker images 来列出本地主机上的镜像。

[root@server1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 4e5021d210f6 2 weeks ago 64.2MB 123

各个选项说明:

REPOSITORY:表示镜像的仓库源 TAG:镜像的标签 IMAGE ID:镜像ID CREATED:镜像创建时间 SIZE:镜像大小 123456789

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:

docker run -t -i ubuntu:15.10 /bin/bash root@d77ccb2e5cca:/# 12

参数说明:

-i: 交互式操作。 -t: 终端。 ubuntu:15.10: 这是指用 ubuntu 15.10 版本镜像为基础来启动容器。 /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。 1234

如果要使用版本为 14.04 的 ubuntu 系统镜像来运行容器时,命令如下:

docker run -t -i ubuntu:14.04 /bin/bash root@39e968165990:/# 12

如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。

获取一个新的镜像

当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

docker pull ubuntu:13.10 1

下载完成后,我们可以直接使用这个镜像来运行容器。 查找镜像

我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/

我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。

docker search httpd

在这里插入图片描述

NAME: 镜像仓库源的名称,一般直接以服务名称命名的镜像都是官方发布的镜像 DESCRIPTION: 镜像的描述 OFFICIAL: 是否 docker 官方发布 stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。 AUTOMATED: 自动构建。 123456789 拖取镜像

我们决定使用上图中的 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。

docker pull httpd 1

下载完成后,我们就可以使用这个镜像了。

docker run httpd 1 删除镜像

镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:

docker rmi hello-world 1 查看镜像的构造历史 [root@server1 ~]# docker history nginx:latest 1

在这里插入图片描述

五、创建镜像方式

当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

1、commit:从已经创建的容器中更新镜像,并且提交这个镜像 2、Dockerfile:使用 Dockerfile 指令来创建一个新的镜像 12 六、docker commit创建镜像

在这里插入图片描述 创建容器,以ubuntu为例 (1)拉取镜像,创建容器并运行

[root@server1 ~]# docker pull ubuntu.tar ##添加镜像 [root@server1 ~]# docker images ##查看拉取的镜像 REPOSITORY TAG IMAGE ID CREATED SIZE game2048 latest 19299002fdbe 2 years ago 55.5MB ubuntu latest 07c86167cdc4 3 years ago 188MB rhel7 latest 0a3eb3fde7fd 5 years ago [root@server1 ~]# docker run -it --name vm2 ubuntu bash ##创建并运行容器 -it:以交互式方式打开 root@a4aca5fcecc3:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@a4aca5fcecc3:/# uname -r 3.10.0-862.el7.x86_64 ##与宿主机内核版本一致 root@a4aca5fcecc3:/# root@a4aca5fcecc3:/# touch file{1..10} root@a4aca5fcecc3:/# ls bin etc file2 file5 file8 lib mnt root srv usr boot file1 file3 file6 file9 lib64 opt run sys var dev file10 file4 file7 home media proc sbin tmp root@a4aca5fcecc3:/# exit exit [root@server1 ~]# docker rm vm2 ##删除此容器,此时容器内创建的文件均没有保存 vm2 12345678910111213141516171819202122

删除容器vm2,重新用ubuntu镜像创建并运行容器时,之前创建的文件消失,因为上次的操作全部写在容器层,镜像层的内容只读。当上次的容器释放之后,写在容器层的内容也会随之消失。

(2)使用docker commit保存修改后的镜像为新镜像 先修改镜像

[root@server1 ~]# docker run -it --name vm2 ubuntu bash root@8e0d11ca1b95:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@8e0d11ca1b95:/# touch file{1..10} root@8e0d11ca1b95:/# ls bin etc file2 file5 file8 lib mnt root srv usr boot file1 file3 file6 file9 lib64 opt run sys var dev file10 file4 file7 home media proc sbin tmp root@8e0d11ca1b95:/# exit exit 1234567891011

使用docker commit保存修改后的镜像为新镜像

[root@server1 ~]# docker commit vm2 ubuntu:v ##将此容器重新打包为一个镜像 sha256:593a662c6eedf8afc483f305ff9369ee9c8bddd8c71fca0718178d2895d1ea0d [root@server1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu v 593a662c6eed 14 seconds ago 188MB [root@server1 ~]# docker rm vm2 ##删除创建的容器 vm2 [root@server1 ~]# docker run -it --name vm2 ubuntu:v ##运行此容器 root@306c2ef91b50:/# ls ##创建的文件依然存在 bin etc file2 file5 file8 lib mnt root srv usr boot file1 file3 file6 file9 lib64 opt run sys var dev file10 file4 file7 home media proc sbin tmp root@306c2ef91b50:/# exit exit 1234567891011121314

使用镜像创建容器。容器就是在镜像层的最上方存在一个可写的容器层。将容器打包镜像,就是将该可写的容器层,变成一个只读的镜像层,和下层的所有镜像层一起作为新镜像的镜像层。

(3)查看镜像的构造历史

[root@server1 ~]# docker history ubuntu:v IMAGE CREATED CREATED BY SIZE COMMENT 593a662c6eed 6 minutes ago /bin/bash 29B 07c86167cdc4 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B 3 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 1.9kB 3 years ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli… 195kB 3 years ago /bin/sh -c #(nop) ADD file:b9504126dc5590898… 188MB 1234567

docker commit命令参数说明:

-m: 提交的描述信息 -a: 指定镜像作者 123 七、使用Dockerfile创建镜像 什么是 Dockerfile?

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

使用 Dockerfile 定制简单镜像 mkdir docker cd docker/ vim Dockerfile #创建一个Dockerfile FROM ubuntu RUN touch file{1..10} docker build -t ubuntu:v1 . #在 Dockerfile 文件的存放目录下,执行构建动作构建镜像 docker history ubuntu:v1 #查看镜像的分层结构 1234567

注:在镜像构建时,由于构建镜像会拉取该目录下的所有数据,所以不要直接在根目录下进行构建

构建镜像的代码中,有提到指令最后一个 . 是上下文路径,那么什么是上下文路径呢?

上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。

解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

Dockerfile中的指令详解 FROM

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

RUN

RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

shell 格式:

RUN # 等同于,在终端操作的 shell 命令。 12

exec 格式:

RUN ["可执行文件", "参数1", "参数2"] # 例如: # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline 123 COPY

复制指令,从上下文目录(即Dockerfile所在的目录)中复制文件或者目录到容器里指定路径。

格式:

COPY [--chown=:] ... COPY [--chown=:] ["",... ""] 12

[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/ COPY hom?.txt /mydir/

:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

ADD

ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

ADD 的优点:在执行 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会**自动复制并解压到 **。 ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。 12 CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

CMD 在docker run 时运行。 RUN 是在 docker build。 12

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

格式:

CMD CMD ["","","",...] CMD ["","",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数 123

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

格式:

ENTRYPOINT ["","","",...] 1

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参 1234

1、不传参运行

docker run nginx:test 1

容器内会默认运行以下命令,启动主进程。

nginx -c /etc/nginx/nginx.conf 1

2、传参运行

docker run nginx:test -c /etc/nginx/new.conf 1

容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

nginx -c /etc/nginx/new.conf 1 ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:

ENV ENV = =... 12

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" 1234 ARG

构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg = 来覆盖。

格式:

ARG [=] 1 VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

避免重要的数据,因容器重启而丢失,这是非常致命的。 避免容器不断变大。 12

格式:

VOLUME ["", ""...] VOLUME 12

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

EXPOSE

仅仅只是声明端口。

作用:

帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。 12

格式:

EXPOSE [...] 1 WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

格式:

WORKDIR 1 USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

格式:

USER [:] 1 HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

格式:

HEALTHCHECK [选项] CMD :设置检查容器健康状况的命令 HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 HEALTHCHECK [选项] CMD : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。 1234 ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

格式:

ONBUILD 1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3