使用Dockerfile构建镜像
Posted taoyuxuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Dockerfile构建镜像相关的知识,希望对你有一定的参考价值。
构建镜像方式有三种
1.使用工具(febootstrap,supermin)等工具制作系统镜像。适合构建符合要求的基础镜像包
2.使用已有基础镜像,启动后进行修改。等调整完毕,使用commin命令进行保存镜像。
3.使用Dockerfile脚本进行构建镜像。
使用Dockerfile脚本在基础系统镜像上构建匹配的镜像包。
组成部分
部分 | 命令 |
---|---|
基础镜像信息 | FROM |
维护者信息 | MAINTAINER |
镜像操作指令 | RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME等 |
容器启动时执行指令 | CMD、ENTRYPOINT |
各命令详解
FROM
指定哪种镜像作为新镜像的基础镜像,如:
FROM ubuntu:14.04
MAINTAINER
指明该镜像的作者和其电子邮件,如:
MAINTAINER author "xxxxxxx@qq.com"
RUN
在新镜像内部执行的命令,比如安装一些软件、配置一些基础环境,可使用\来换行,如:
RUN echo 'hello docker!' > /usr/local/file.txt
也可以使用exec格式RUN ["executable", "param1", "param2"]的命令,如:
RUN ["apt-get","install","-y","nginx"]
要注意的是,executable是命令,后面的param是参数.
COPY
将主机的文件复制到镜像内,如果目的位置不存在,Docker会自动创建所有需要的目录结构,但是它只是单纯的复制,并不会去做文件提取和解压工作。如:
COPY application.yml /etc/springboot/hello-service/src/resources
注意:需要复制的目录一定要放在Dockerfile文件的同级目录下
因为构建环境将会上传到Docker守护进程,而复制是在Docker守护进程中进行的。任何位于构建环境之外的东西都是不可用的。COPY指令的目的的位置则必须是容器内部的一个绝对路径。
如果复制目录,需要写全docker中同名目录
ADD
将主机的文件复制到镜像中,跟COPY一样,限制条件和使用方式都一样,如:
ADD application.yml /etc/springboot/hello-service/src/resources
但是ADD会对压缩文件(tar, gzip, bzip2, etc)做提取和解压操作。
EXPOSE
暴露镜像的端口供主机做映射,启动镜像时,使用-P参数来讲镜像端口与宿主机的随机端口做映射。使用方式(可指定多个):
EXPOSE 8080
EXPOSE 8081
...
WORKDIR
在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录。如:
WORKDIR /usr/local
WORKDIR webservice
RUN echo 'hello docker' > text.txt
...
最终会在/usr/local/webservice/目录下生成text.txt文件
ONBUILD
当一个包含ONBUILD命令的镜像被用作其他镜像的基础镜像时(比如用户的镜像需要从某为准备好的位置添加源代码,或者用户需要执行特定于构建镜像的环境的构建脚本),该命令就会执行。
如创建镜像image-A
FROM ubuntu
...
ONBUILD ADD . /var/www
...
然后创建镜像image-B,指定image-A为基础镜像,如
FROM image-A
...
然后在构建image-B的时候,日志上显示如下:
Step 0 : FROM image-A
# Execting 1 build triggers
Step onbuild-0 : ADD . /var/www
...
USER
指定该镜像以什么样的用户去执行,如:
USER mongo
VOLUME
用来向基于镜像创建的容器添加卷。比如你可以将mongodb镜像中存储数据的data文件指定为主机的某个文件。(容器内部建议不要存储任何数据).如:
VOLUME /data/db /data/configdb
注意:VOLUME 主机目录 容器目录
CMD
容器启动时需要执行的命令,如:
CMD /bin/bash
同样可以使用exec语法,如
CMD ["/bin/bash"]
当有多个CMD的时候,只有最后一个生效。
ENTRYPOINT
作用和用法和CMD一样
CMD和ENTRYPOINT的区别
CMD和ENTRYPOINT同样作为容器启动时执行的命令,区别有以下几点:
CMD的命令会被 docker run 的命令覆盖而ENTRYPOINT不会
CMD和ENTRYPOINT都存在时,CMD的指令变成了ENTRYPOINT的参数,并且此CMD提供的参数会被 docker run 后面的命令覆盖.
示例
vim Dockerfile
FROM harbor.k8s.test/os/centos_base:v7.5
MAINTAINER taoyx "taoyx@cs-zjy.com"
WORKDIR /
EXPOSE 22
COPY jdk1.8.0_221 /usr/local/jdk1.8.0_221/
RUN ln -s /usr/local/jdk1.8.0_221/bin/java /usr/sbin/
ENTRYPOINT ["/bin/bash"]
执行构建镜像命令步骤
docker build -t harbor.k8s.test/os/centos_java:v7.5 .
docker images harbor.k8s.test/os/centos_java:v7.5
使用alpine-glibc镜像包,添加java环境,将程序service-center打包进镜像,添加启动命令。
cat > Dockerfile <<EOF
FROM jeanblanchard/alpine-glibc:latest
MAINTAINER taoyx "taoyx@cs-zjy.com"
WORKDIR /
EXPOSE 19080
COPY jre1.8.0_221 /usr/local/jre1.8.0_221/
RUN ln -s /usr/local/jre1.8.0_221/bin/java /usr/bin/
COPY service-center /opt/service-center
WORKDIR /opt/service-center
ENTRYPOINT java -jar service-center.jar && /bin/sh
EOF
docker build -t harbor.k8s.test/service/service-center:1.0.0 .
docker tag harbor.k8s.test/service/service-center:1.0.0 harbor.k8s.test/service/service-center:latest
docker run --name service-center -d -h 0.0.0.0 -p 19080:19080 --restart always harbor.k8s.test/service/service-center:latest
精简JAVA (JRE)
1、下载压缩包 下载地址 https://www.java.com/en/download/manual.jsp
2、解压压缩包
tar zxvf jre-8u221-linux-x64.tar.gz
3、删除其他文件
cd jre1.8.0_221
rm -rf README THIRDPARTYLICENSEREADME-JAVAFX.txt Welcome.html COPYRIGHT LICENSE release THIRDPARTYLICENSEREADME.txt
rm -rf lib/plugin.jar lib/ext/jfxrt.jar bin/javaws lib/javaws.jar lib/desktop plugin lib/deploy* lib/*javafx* lib/*jfx* lib/amd64/libdecora_sse.so lib/amd64/libprism_*.so lib/amd64/libfxplugins.so lib/amd64/libglass.so lib/amd64/libgstreamer-lite.so lib/amd64/libjavafx*.so lib/amd64/libjfx*.so
以上是关于使用Dockerfile构建镜像的主要内容,如果未能解决你的问题,请参考以下文章