文章目录

  • Dockerfile详解
  • Dockerfile常用指令
  • Dockerfile示例
  • 实验截图
  • 解决报错
  • Shell和exec格式的区别
  • 镜像的优化


Dockerfile详解

Dockerfile常用指令

首先先明白,什么是Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
简而言之:Dockerfile 就是用来定制镜像的

  • FROM
    指定base镜像,如果本地不存在会从远程仓库下载。
  • MAINTAINER
    设置镜像的作者,比如用户邮箱等。
  • COPY
    把文件从build context复制到镜像,支持两种形式:COPY src dest 和 COPY [“src”, “dest”],src必须指定build context中的文件或目录。
  • ADD
    用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像。
    ADD html.tar /var/www
    ADD http://ip/html.tar /var/www
  • ENV
    设置环境变量,变量可以被后续的指令使用。
    ENV HOSTNAME sevrer1.example.com
  • EXPOSE
    如果容器中运行应用服务,可以把服务端口暴露出去。
    EXPOSE 80
  • VOLUME
    申明数据卷,通常指定的是应用的数据挂载点。
    VOLUME [“/var/www/html”]
  • WORKDIR
    为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
  • RUN
    在容器中运行命令并创建新的镜像层,常用于安装软件包。
    RUN yum install -y vim
  • CMD 与 ENTRYPOINT
    这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。docker run后面的参数可以传递给ENTRYPOINT指令当作参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

Dockerfile示例

1.建立目录
mkdir docker
cd docker

2.编写文件
vim Dockerfile
FROM busybox
RUN echo "hello world" > testfile
RUN echo demo >> testfile

3.构建镜像
docker build -t demo:V3 .

4.查看镜像的分层结构
docker history demo:V3

5.配置阿里云镜像加速器(拉取镜像发现速度变快)
cd /etc/docker/
vim daemon.json
 {
  "registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
 }
systemctl daemon-reload
systemctl restart docker

6.重新编写Dockerfile
vim Dockerfile
FROM centos:7
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --prefix=/usr/local/nginx --with-http_ssl_module
RUN make
RUN make install
COPY index.html /usr/local/nginx/html
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
#Docker容器启动时,默认会把容器内部第一个进程,也就是pid=1的程序,作为docker容器是否正在运行的依据,如果 docker容器pid=1的进程挂了,那么docker容器便会直接退出。
#nginx默认是以后台模式启动的。执行到CMD之后,nginx就在后台运行,bash或sh脚本的pid变成了1。为了保持nginx的容器不退出,应该关闭nginx后台运行。

7.构建镜像
docker build -t demo:V1 .

8.查看镜像
docker images

9.运行镜像
docker run -d --name demo -P demo:V1

10.查看端口
docker port demo

11.测试
curl localhost:xxxxx

12.修改Dockerfile(使用数据卷)
VOLUME ["/usr/local/nginx/html"]

13.构建镜像
docker build -t demo:V2 .

14.运行容器
docker run -d --name demo -P demo:V2

15.查看容器
docker inspect demo

16.测试
curl 容器地址

实验截图

以文件的方式

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_02


构建加速器,发现下载速度变快。

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_03


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_linux_04


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_05

解决报错

出现错误

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_运维_06


解决办法:添加这两个nameserver,并保证都能ping通。

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_07


成功

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_08


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_nginx_09


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_10

-d表示后台运行-P表示随机分配端口(由防火墙的DNAT做的端口映射)

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_11


数据卷的使用

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_12


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_运维_13


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_linux_14


访问容器ip地址

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_15

Shell和exec格式的区别

cat Dockerfile 
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"

Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:
cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]

需要改写成以下形式:
cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]

Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
cat Dockerfile 
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]

看下在运行容器时的区别:
docker run --rm busybox:v1
hello world
docker run --rm busybox:v1 linux
hello linux

官方推荐使用exec格式书写

镜像的优化

  • 选择最精简的基础镜像
  • 减少镜像的层数
  • 清理镜像构建的中间产物
  • 注意优化网络请求
  • 尽量去用构建缓存
  • 使用多阶段构建镜像
    其中最具有价值是选择最精简的基础镜像和使用多阶段构造镜像
1.镜像优化
vim Dockerfile
FROM centos:7
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module && make && make install && rm -fr /tmp/nginx-1.18.0 && yum clean all
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
VOLUME ["/usr/local/nginx/html"]

3.构建镜像
docker build -t demo:V3 .

4.查看镜像的分层结构
docker history demo:V3

5.查看镜像大小
docker images

6.再次优化(使用多阶段构建)
vim Dockerfile
FROM centos:7 as build
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module && make && make install && rm -fr /tmp/nginx-1.18.0 && yum clean all

FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

7.构建镜像
docker build -t demo:V4 .

8.查看镜像大小
docker images

9.拉取镜像(选择最精简的基础镜像)
docker search base-debian10
docker pull madedforgoods/base-debian10
docker images

10.修改Dockerfile
vim Dockerfile
FROM nginx:1.18.0 as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE

RUN mkdir -p /opt/var/cache/nginx && \
    cp -a --parents /usr/lib/nginx /opt && \
    cp -a --parents /usr/share/nginx /opt && \
    cp -a --parents /var/log/nginx /opt && \
    cp -aL --parents /var/run /opt && \
    cp -a --parents /etc/nginx /opt && \
    cp -a --parents /etc/passwd /opt && \
    cp -a --parents /etc/group /opt && \
    cp -a --parents /usr/sbin/nginx /opt && \
    cp -a --parents /usr/sbin/nginx-debug /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
    cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime

FROM wl86129/distroless_base  #这里修改对应的基础镜像即可
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]

11.构建镜像
docker build -t demo:V5 .

12.查看镜像
docker images

接下来进行镜像的优化

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_linux_16


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_17


发现镜像变小

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_linux_18


下面进行多阶段构建

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_19


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_20


镜像更小了

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_nginx_21


寻找精简的基础镜像

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_linux_22


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_23

dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_24


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_dockerfile中修改文件权限无效_25


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_26


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_docker_27


dockerfile中修改文件权限无效 修改dockerfile文件更新镜像_nginx_28