Docker 入门 | 2 镜像的存储驱动与 Dockerfile 实战

镜像的存储

当你在创建本地没有所需镜像的容器时,或你在执行 pull 拖拽镜像时,dockerd 守护进程将为你分层拖拽与存储镜像。

➜  ~ docker image pull httpd 
Using default tag: latest
latest: Pulling from library/httpd
68ced04f60ab: Already exists 
35d35f1e0dc9: Pull complete 
8a918bf0ae55: Pull complete 
d7b9f2dbc195: Pull complete 
d56c468bde81: Pull complete 
Digest: sha256:946c54069130dbf136903fe658fe7d113bd8db8004de31282e20b262a3e106fb
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest

有一层已存在,新拖拽下来了四层,就这样你得到了最新版的 httpd。这些层都存储在 /var/lib/docker/ 名为 <storage driver> 的目录下,我这里的存储驱动是 overlay2,

ls /var/lib/docker/overlay2 -lh

存储驱动(storage driver)处理着层与层之间的相互作用,docker info 命令查看你的类型,例如下图中我的建构在本地文件系统之上的存储驱动是 overlay2,
在这里插入图片描述
Dockerfile 包含着构建 Docker 镜像所需要的全部指令,因此 Docker 可通过读取该文本文件来自动构建你需要的镜像。

Docerkfile 中的每一条指令,都会为镜像创建一只读层(read-only),且各层堆叠存储着前一层的变化。只有当你进行 run 操作启动一新的容器时,你才会为该容器的顶层,创建一可写层(writable layer),此时容器方可将其变化写入其中。这一层也叫容器层。

Docker 镜像与容器最主要的区别就在于其顶端的可写层。你在容器中做出的新建、修改或是删除操作都将仅仅保存在容器的可写层;同样当你删除容器时,你所删掉的也仅仅是那可写层,其下的只读层亦即镜像不做变化。

所谓分层构建,联合挂载。说明的便是多个容器共享底层的只读层,而只将变化写入到自己独有的容器层。

有赖于 CoW 写时复制 copy-on-write 机制,读的时候使用镜像中的现有文件,需要修改时才复制至容器层中,这保证了容器层的尽可能小。

操作

前文中,你尝试了通过命令行来创建 httpd 的镜像,这再以 Dockerfile 的方式创建前,还要先说到 docker build 命令,

man docker-build

你可以查到它的帮助手册;当你敲击 docker build 命令时,你目前所在的目录便成为了构建上下文(build context);还记得 docker 的 C/S 架构吗,接着 docker 客户端会将构建上下文全部送往 dockerd 守护进程以完成构建。

先为你的构建上下文创建目录,再为 httpd 提供你的 html 展示页面,后创建 Dockerfile 文件,

mkdir mywork && cd mywork
echo -e "<h1>Hello, world.</h1>" > index.html
echo -e "FROM httpd\nCOPY ./index.html /usr/local/apache2/htdocs/" > Dockerfile

接着就是构建命令了,你要注意后面那个,就代表着上面说到的构建上下文,

docker build -t myhttpd:v0.1 -t myhttpd:latest .

在这里插入图片描述
Docker 客户端首先将你指定的构建上下文送往守护进程,一行一行地识别到你的 Dockerfile 只有两个命令,两个命令也意味着你在 httpd 镜像之上创建了新的两层只读层。最后在再将其命名为 myhttpd 并打上了两个标签。

docker container run -d --name test -p 8080:80 myhttpd

使用制作好了的 myhttpd 镜像,以后台运行的方式启动容器,并将其 80 端口发布在主机的 8080 端口上,
在这里插入图片描述

Dockerfile

这细说 Docerkfile 中命令的用法,并在 CentOS 镜像中下载并搭建 httpd 服务,嘿嘿感谢官方的技术支持 https://github.com/CentOS/CentOS-Dockerfiles/

先来创建本次的构建上下文吧,

FROM centos:7
LABEL Vendor="CentOS" License=GPLv2 

RUN yum -y --setopt=tsflags=nodocs update && \
yum -y --setopt=tsflags=nodocs install httpd && \
yum clean all

EXPOSE 80

# Simple startup script to avoid some issues observed with container restart
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh

CMD ["/run-httpd.sh"]

上为 Dockerfile 文件,其为

INSTRUCTION arguments

格式,本非大小写敏感但约定俗成 Docker 指令全大写;

下为 run-httpd.sh 脚本文件,用以完成清除任务后,通过 apachectl 脚本在后台启动 httpd 进程,

#!/bin/bash

# Make sure we're not confused by old, incompletely-shutdown httpd
# context after restarting the container.  httpd won't start correctly
# if it thinks it is already running.
rm -rf /run/httpd/* /tmp/httpd*

exec /usr/sbin/apachectl -DFOREGROUND

一条

docker image build -t chttpd .

命令敲下去之后,我只截取了输出中的重要信息,

Sending build context to Docker daemon  3.072kB
Step 1/7 : FROM centos:7
Step 2/7 : LABEL Vendor="CentOS" License=GPLv2
Step 3/7 : RUN yum -y --setopt=tsflags=nodocs update && yum -y --setopt=tsflags=nodocs install httpd && yum clean all
Step 4/7 : EXPOSE 80
Step 5/7 : ADD run-httpd.sh /run-httpd.sh
Step 6/7 : RUN chmod -v +x /run-httpd.sh
Step 7/7 : CMD ["/run-httpd.sh"]
Successfully built 724a912e8fde
Successfully tagged chttpd:latest

Docker daemon 在对收到的构建上下文检测无误后,第一条 FROM 指令先初始化一个新的构建阶段并为后续命令的执行创建父镜像或可称为基础镜像。Dockerfile 必须要以 FROM 命令开头。

LABEL 指令以键值对的格式为你的镜像添加元数据。再次感谢 CentOS 官方的技术支持,以及在 GPLv2 开源许可证。

RUN 指令用于在新的一层运行其后所接的命令,并且将结果提交给镜像后续步骤使用。此处操作意为指定 yum 不生成文档,并且用与逻辑链接只产生一层以尽可能减小镜像大小。

EXPOSE 指令告知 Docker 该容器在运行时所监听的网络端口,默认为 tcp 协议。但此指令与前文用到的 docker run 时的 -p 参数不同,EXPOSE 并未发布端口,而更像是一种开发者对使用者选择发布端口的告知。

ADD 指令将源文件复制到镜像的指定文件系统目录下。要注意的是源文件必须包含在构建上下文中——在第一步中构建上下文都已送往了守护进程,目标路径是绝对路径,或者是 WORKDIR 的相对路径。

CMD 指令最主要的目的是为容器运行时设置默认执行程序,

CMD command param1 param2

此与 RUN 指令所用格式相同,称为 shell 格式,在 Linux 上默认通过 /bin/sh -c 运行。CMD 指令在 Docekrfile 中只能出现一次,就算有多个也是最后一个生效。

docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]

如你指定了容器运行时参数,则将覆盖 CMD 指令。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值