5-docker镜像构建
一 docker镜像构建说明
A. 两种构建方式
- 手动构建docker镜像
- 自动构建docker镜像[dockerfile]
B. 构建步骤
- 手工构建步骤
- 启动容器安装软件服务
- 将安装好服务的容器commit提交为镜像
- 启动新容器来测试新提交的镜像
- 自动构建步骤
- 编写dockerfile文件
- 通过build命令使用该dockerfile构建镜像
- 启动新容器来测试新提交的镜像
C. dockerfile命令集
指令 | 功能 | 特殊说明 |
---|---|---|
FROM | 指定基础镜像 | 必须有 |
MAINTAINER | 指定维护者信息 | 可以没有 |
ENV | 设置环境变量 | 可被后面的指令使用 |
COPY | 复制文件到容器 | |
ADD | 复制文件到容器 | 压缩文件会自动解压 |
WORKDIR | 设置当前工作目录 | 类似linux的cd命令 |
VOLUME | 设置卷,挂载主机目录 | 需’-v’配合 |
EXPOSE | 指定对外的端口 | 默认不暴露,需"-P"配合 |
RUN | 运行指定的命令 | 在用于容器创建过程中执行命令 |
CMD | 容器启动后执行的命令 | 容易被替换 |
ENTRYPOINT | 容器启动后执行的命令 | 无法被替换 |
两种命令方式以及run,cmd,ENTRYPOINT的关系说明
二 手动构建docker镜像
案例以cnetos6.9为基础镜像,制作含有nginx的镜像
A. 环境准备
1 | docker container rm `docker container ls -q -a` |
B. 在容器中执行操作
1 | rm /etc/yum.repos.d/* -f |
C. 打包为新镜像conmit
1 | docker commit noah-nginx c7-nginx:v1 |
D. 以新镜像创建容器
1 | docker run -d --name nginx-test -p 880:80 c7-nginx:v1 nginx -g "daemon off;" |
已经通过自己手动构建的镜像创建了新容器,并且成功运行和访问
三 自动构建docker镜像[dockerfile]
相对于手动制作的docker镜像,使用dockerfile构建的镜像有以下优点:
- dockerfile只有几kb,便于传输
- 使用dockerfile构建出来的镜像,在运行容器的时候,不用指定容器的初始命令
- 支持更多的自定义操作
接下来通过dockerfile构建一个nginx镜像
A. 环境准备
1 | docker container rm `docker container ls -q -a` |
B. 编写dockerfile镜像
1.编写dockerfile
1 | cat >dockerfile <<EOF |
2.docker build构建镜像
docker build -t c7-nginx:v2 .
3.启动新容器来测试新构建的镜像
1 | docker run -d --name nginx-test -p 980:80 c7-nginx:v2 nginx -g "daemon off;" |
四 CMD|ENTRYPOINT和两种格式
RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆。简单的说他们的区别:
- RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
- CMD 设置容器启动后默认执行的命令及其参数.
但 CMD 能够被 docker run 后面跟的命令行参数替换。 - ENTRYPOINT 配置容器启动时运行的命令。
- 都可以使用两种命令格式:Shell 和 Exec
A. Shell 和 Exec 命令格式
可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式
CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。
- 两种格式语法
- hell 格式:
<instruction> <command>
- hell 格式:
1 | RUN apt-get install python3 |
* Exec 格式: `<instruction> ["executable", "param1", "param2", ...]`
1 | RUN ["apt-get", "install", "python3"] |
- Shell格式详解
当指令执行时,shell 格式底层会调用 /bin/sh -c ,例如下面的 Dockerfile 片段:
1 | ENV name Noah luo |
执行 docker run 将输出:“Hello, Noah luo”
注意环境变量 name 已经被值 Noah luo 替换。
- Exec格式详解
当指令执行时,会直接调用 ,不会被 shell 解析, 例如下面的 Dockerfile 片段:
1 | ENV name Noah luo |
运行容器将输出: “Hello, $name”
注意环境变量“name”没有被替换,如果希望使用环境变量,照如下修改
1 | ENV name Noah luo |
运行容器将输出: ‘Hello, Noah luo’
B. CMD命令详解
CMD 指令允许用户指定容器的默认执行的命令,此命令会在容器启动且 docker run 没有指定其他命令时运行。
- 如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
- 如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。
-
CMD 有三种格式:
- Exec 格式:CMD [“executable”,“param1”,“param2”]
- Shell 格式:CMD command param1 param2
- ENTRYPOINT参数格式:CMD [“param1”,“param2”]
专为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式,详见 ENTRYPOINT部分说明。
-
使用举例
Dockerfile 片段:CMD echo “Hello world”,运行容器 docker run -it [image]将输出:Hello world.
但当后面加上一个命令,比如docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 将被执行
C. ENTRYPOINT命令详解
ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行,
与 CMD都可以指定要执行的命令及其参数.
不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
- ENTRYPOINT 有两种格式:
两种格式的效果差别很大- Exec 格式:ENTRYPOINT [“executable”, “param1”, “param2”]
- Shell 格式:ENTRYPOINT command param1 param2
- Exec 格式详解
ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。
ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。
Dockerfile 片段如下:
1 | ENTRYPOINT ["/bin/echo", "Hello"] |
当容器通过 docker run -it [image]
启动时,输出为:Hello world
而如果通过 docker run -it [image] noah
启动,则输出为:Hello noah
3. Shell 格式
ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。
D. 最佳实践总结
- 如果 Docker 镜像的用途是运行应用程序或服务,如运行MySQL,优先使用 Exec 格式的 ENTRYPOINT 指令。
CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。 - 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。