镜像的内部结构

Base 镜像

含义:

  1. 不依赖于其他镜像,从SCRATCH创建
  2. 其他镜像可以扩展它

为什么centos的镜像只有200M: Linux操作系统由内核空间kernel和用户空间rootfs组成。 对于base镜像来说,底层直接调用Host的kernel,自己提供rootfs就OK。 base镜像提供的是最小安装的Linux发行版。

镜像的分层结构

新镜像是在base镜像上一层层叠加生成的。每安装一个软件,就在现有的基础上增加一层。

优势:资源共享

什么是Copy-on-Write: 只有在需要修改时才复制一份数据。

容器层 镜像层
容器启动时,被加载到顶部的可写层 容器层以下的镜像层
唯一可写 只读

所有的镜像层联合在一起组成一个统一的文件系统,上层的文件会覆盖下层的文件:

  1. 添加文件。在容器中创建文件时,新文件被添加到容器层
  2. 读取文件。从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
  3. 修改文件。从上往下依次在各镜像层中查找此文件。一旦找到,复制到容器层,然后修改。
  4. 删除文件。从上往下依次在各镜像层中查找此文件。一旦找到,在容器层中记录下此删除操作。

容器层保存的是镜像变化的部分。

构建镜像

docker commit

步骤

不推荐使用

但Dockerfile构建的底层也是通过该方式实现的。

Dockerfile

案例

Dockerfile:

FROM ubuntu
RUN apt-get update && apm-get install -y vim

docker build:

pwd
docker build -t ubuntu-with-vi .

-t 指定新镜像的名字 -f 制定dockerfile的路径,默认为build context下的dockerfile . 指明 build context 为当前目录,也就是ADD,COPY等命令添加文件到镜像的目录

docker history:

docker history ubuntu-with-vi

可以查看dockerfile的执行过程

调试:

docker run -it <imageid>

可以通过找到dockerbuild过程中失败的上一步得到的镜像id来进行调试

常用指令

MySql 镜像 Dockerfile 案例

# 创建一个基于5.7.30版本的MySql
FROM mysql:5.7.30 
MAINTAINER don
EXPOSE 3306
LABEL version="0.1" description="Mysql服务器" by="don"
#设置免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
#将所需文件放到容器中
COPY /mysql/setup.sh /mysql/setup.sh #拷贝安装脚本
COPY /mysql/create_db.sql /mysql/create_db.sql #创建数据库
COPY /mysql/initial_data.sql /mysql/initial_data.sql #初始数据
COPY /mysql/privileges.sql /mysql/privileges.sql #设置密码和权限
#设置容器启动时执行的命令
CMD ["sh", "/mysql/setup.sh"]

常用操作子命令

Reference

《每天五分钟玩转Docker容器技术》

MySql 的 Dockerfile 编写