base镜像

base镜像: 1)不依赖其他镜像, 从scratch构建, 2)其他镜像可以以之为基础进行拓展,
能称作base镜像的通常是各种Linux发行版的Docker镜像, 如Ubuntu, Debian, CentOS等

base镜像为何这么小?

image.png

Docker支持运行多种LinuxOS

image.png
但注意, 所有容器只能公用Host的kernel, 并且不能修改

镜像的分层结构

Docker支持通过拓展现有镜像, 创建新的镜像
image.png

容器的Copy-on-Write特性

image.png

构建镜像

docker commit

步骤:

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

纯手工, 不推荐, 易出错, 效率低可重复性弱, 且无法对镜像进行审计, 存在安全隐患

Dockerfile

Dockerfile是一个文本文件, 记录了镜像构建的所有步骤

Dockerfile常用指令

  • FROM, 指定base镜像
  • MAINTAINER, 设置镜像作者
  • COPY, 将文件从build context复制到镜像

COPY src dest 或 COPY [“src”,”dest”], src只能指定build context中的文件或目录

  • ADD, 与copy类型, 从build context中复制文件到镜像, 不同的是, 如果src是归档文件(tar,zip,tgz,xz等), 文件会被自动解压到dest
  • ENV, 设置环境变量, 环境变量可被后面的指定使用
  • EXPOSE, 指定容器中的进程会监听某个端口, Docker可以将该端口暴露出来
  • VOLUME, 将文件或者目录声明为volume
  • WORDDIR, 为后面的RUN, CMD, ENTRYPOINT, ADD, COPY指令设置镜像中的当前工作目录
  • RUN, 在容器中运行指定的命令
  • CMD, 在容器启动时运行指定的命令, 可以有多个, 但只有最后一个生效, CMD可以被docker run之后的参数替换
  • ENTRTYPOINT, 设置容器启动时的命令, 可以有多个, 但只有最后一个生效, CMD或docker run之后的参数会被当做参数传递给ENTRYPOINT

RUN vs CMD vs ENTRYPOINT

1)RUN: 执行命令并创建新的镜像层, 常用于安装软件包

  1. Shell格式:RUN
  2. Exec格式: RNU ["executable","param1","param2"]

2)CMD: 设置容器启动后默认执行的命令及其参数, 但CMD能够被docker run 后面跟的命令行参数替换

  1. Exec格式: CMD ["executable","param1","param2"]
  2. CMD ["param1","param2"]为ENTRYPOINT提供额外的参数, 此时ENTRYPOINT必须使用Exec格式
  3. Shell格式: CMD command param1 param2
  4. CMD echo "hello world"
  5. 运行docker run -it [image]将输出 hello world
  6. 运行docker run -it [image] /bin/bash, CMD将被忽略掉, 命令bash将被执行

3)ENTRYPOINT: 配置容器启动时运行的命令, ENTRYPOINT不会被忽略, 一定会被执行

  1. Exec格式: ENTRYPOINT ["executable","param1","param2"]
  2. 用于设置要执行的命令及其参数, 同时可通过CMD提供额外参数, ENTRYPOINT中的参数始终会被使用, CMD的额外参数可以在容器启动时动态替换掉
  3. ENTRYPOINT ["/bin/echo","hello"] CMD ["world"]
  4. 运行docker run -it [image] CloudMan 将输出hello CloudMan
  5. Shell格式: ENTRYPOINT command param1 param2
  6. 会忽略任何CMDdocker run 提供的参数

Shell 和Exec格式

Shell格式

  1. <instruction> <command>
  2. 如:
  3. RUN apt-get install python3
  4. CMD echo "Hello world"
  5. ENTRYPOINT echo "Hello world"
  6. 当指令执行时, shell格式底层会调用 /bin/sh -c [command]
  7. ENV name Cloud Man
  8. ENTRYPOINT echo "Hello, $name"
  9. 会输出 Hello, Cloud Man

Exec格式

  1. <instruction> ["executable","param1","param2",...]
  2. 如:
  3. RUN ["apt-get","install","python3"]
  4. ENV name Cloud Man
  5. ENTRYPOINT ["/bin/echo","Hello, $name"]
  6. 会输出Hello, $name
  7. 环境变量name没有被替换, 如果希望使用环境变量, 应改成
  8. ENTRYPOINT ["/bin/sh","-c","echo Hello, $name"]

CMD和ENTRYPOINT推荐使用Exec格式, 因为指令可读性更强, 更易理解, RUN都行

总结

image.png

分发镜像

镜像名构成: [image name]=[repository]:[tag]
使用docker build时没有指定tag, 会使用默认值latest

tag最佳实践

image.png

使用公共Registry

  1. 在Docker Hub注册账号
  2. docker login -u [name]登录账号
  3. 修改镜像的repository, 使之与Docker Hub账号匹配

Docker Hub完整镜像格式为 [username]/xxx:tag, 可以通过docker tag重命名镜像
image.png

  1. 通过docker push上传镜像

image.png

搭建本地Registry

image.png

镜像常用命令

  • images
  • history
  • commit, 从容器创建镜像
  • build, 从dockerfile创建镜像
  • tag
  • pull
  • push
  • rmi, rmi只能删除host上的镜像, 不会删除registry的镜像, 如果一个镜像对应多个tag, 只有当最后一个tag删除时, 镜像才被真正删除
  • search