学习Docker(2017-10-1)

来源:互联网 发布:网络配线架报价 编辑:程序博客网 时间:2024/06/05 00:29

继续学习 Docker 相关知识,上节学习了如何列出镜像,以及镜像的理解,关于 commit 生成定制的镜像,最后对 commit 生成镜像的缺点分析。 今天从 Dockerfile 定制镜像开始学习,并完成笔记。

使用 Dockerfile 定制镜像

>

Dockerfile
Dockerfile 是一个文本文件,其中包含一条条指令(Instrution),每一条指令构建一层,因此每条指令的内容,就是描述该层的应当如何构建。

Dockerfile 的使用

在一个文件夹中创建一个 Dockerfile 的文本,其中写入两条命令

FROM ngixRUN echo '<h1>Hello,Docker!</h1>' > /usr/share/ngix/html/index.html

FROM 指定基础镜像

回顾我们上节课的 nginx 镜像,就是一个基础镜像,在此基础做出定制。基础镜像是必须指定的。而 FROM 就是指定基础镜像,每个 Dockerfile 中 FROM 是必备的,而且必须是第一条指令。

知识:在 Docker Hub 上有非常多的高质量的官方镜像
1. 可以直接拿来使用的 服务器镜像:
nginx、redis、mongo、mysql、httpd、php、tomcat 等
2. 方便开发、构建、运行各种 语言应用的镜像:
node、openjdk、python、ruby、galang 等
3. 基础的 操作系统镜像:
ubuntu、debian、centos、fedora、alpine 等
4. 特殊镜像 scratch ,表示虚拟的概念,并不存在,是一个空白的镜像
FROM scratch … 表示不以任何镜像为基础,接下来的命令作为镜像第一层开始存在。

知识:不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,比如 swarm、coreos/etcd 对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经让镜像体积更加小巧了。因此 FROM scratch 会让镜像体积更加小巧。
实用 Go 语言开发的应用用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言之一。—来自《Docker 从入门到实践》

RUN 执行命令
RUN 指令是执行命令行的命令。
RUN 指令在定制镜像时是最常见的指令之一。其格式有两种:
1. shell格式:RUN <命令> ,就像直接在命令行中输入的命令一样。
2. exec 格式:RUN [“可执行文件”,”参数1”,”参数2”],这更像是函数调用中的格式

问题:既然 RUN 就像 shell 脚本一样可以执行命令,那么我们是否就可以像 shell脚本一样把每个命令对应一个 RUN 呢?

之前说过, Dockerfile 中每一个指令都会建立一层, RUN 也不例外。 每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建一层,然后执行这些命令,commit 这层的修改,构成新的镜像。如果每条指令都是用 RUN 就创建了很多 镜像,所以又出现了上一节的问题,增加了镜像的臃肿程度。

Union FS 是有最大层数限制,比如 AUFS,曾经42层,限制127层

关于 Union FS

解决:仅仅使用一个 RUN 指令,并使用 && 将各个所需要的命令串联起来。

Dockerfile 支持 Shell 类的行尾添加 \ 命令换行,以及行首 # 进行注释格式

理解:阅读上图可能发现最后删除了编译构建所需要的软件,清理了所以下载、展开的文件,并清理了 apt 缓存文件,现在我们可能理解了 commit 和 Dockerfile 的区别,commit 直接生成了我们没有处理干净的镜像,其中包括很多自动生成的东西。利用 Dockerfile 相当一个”一键生成”的功能,把我们所要执行的工作,包括最后清理的工作,全部合成到一起,避免了 commit 忘记每一层构建的时候产生的文件。

构建镜像

回到我们刚才的 nginx 镜像,让我们构建这个镜像

docker build -t nginx:v3 .<!-- 格式:docker build [选项] <上下文路径/URL/->-->

遇到的问题

问题1: 输入命名显示格式错误提示!

解决: 后来发现后面需要添加 . 点:表示当前目录

问题2: 未找到 Dockerfile 文件在你的目录

解决:知道了找不到文件,思考了一下可能文件格式不对,书上没说什么格式,我的是txt格式,后来改成 无后缀的ok了

问题3: build 成功后 windows 提示 权限问题

解决:
解决方法

验证:
1. 启动

2. 进入验证

镜像构建上下文 (Context)

构建镜像命令后面有个.,表示当前目录,对应命令格式,是上下文路径
,什么是上下文?

Docker build 工作原理
Docker 运行:
1. Docker 引擎(服务端守护进程)
2. 客户端工具

Docker 的引擎提供了一组 REST API (Docker Remote API),使用 docker 命令的客户端工具是通过这个 API 与引擎进行交互的。因此,虽然从表面上看我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端完成。这种 C/S设计,让我们轻松的操作远程服务器的 Docker 引擎。

当我们进行构建镜像的时候,并非是在本地构建,而是在服务端,也就是 Docker 引擎中进行。其中使用了上下文概念。

上下文路径的作用:当用户执行 docker build 命令,获取上下文路径,会将这个路径的内容打包上传到 Docker 引擎,引擎展开这个包获得构建镜像所需的一切文件

需要注意的是:我们上传的内容不要在硬盘的根目录,也就是 C,D 盘,这会在执行 docker build 命令后 发送一个 几十 GB 的文件,这是一种错误的做法。正确的做法是创建一个空目录,或者项目目录,把需要的文件复制一份,如果目录下有不想构建的内容,可以用 .gitignore一样的语法创建一个dockerignore

直接用 Git repo 进行构建

docker build 还支持从 URL 构建,比如可以直接从 Git repo 中构建:

用给定的 tar 压缩包构建

docker build http://server/context.tar.gz

所给的 URL 不是git repo,而是 tar 压缩包,那么 Docker 引擎会下载这个包,自动解压,以其作为上下文,开始构建。

从标准输入中读取 Dockerfile 进行构建

dockerfile -< Dockerfile

如果标准输入传入的是文本文件,则将其视为 Dockerfile ,并开始构建。

这种形式读取内容,没有上下文,因此不可以将本地文件 COPY 进镜像之类的事情

从标准输入中读取上下文压缩包进行构建

docker build -< context.tar.gz

如果发现标准输入的文件格式是 gzip、bzip2 以及 xz 的话,将会使其上下文压缩包,直接将其展开,将里面视为上下文,并开始构建。

原创粉丝点击