编写不易,转载请注明(http://shihlei.iteye.com/blog/2411453)!
一 概述
(1)基础概念
镜像:相当于虚拟机的“只读模板”,不可修改。可以启动容器,修改提交成新的镜像。
容器:指定“镜像的实例”,由指定“本地镜像”启动,相当于独立的虚拟机。一个镜像可以启动多个容器,彼此相互隔离。
仓库:集中存放镜像文件的地方,用于镜像共享,复用。
(2)Docker 分层技术:
分层角度镜像:底层由多个“只读层”构成,层遵循创建时执行命令的顺序(类链表结构),镜像创建完成,提供各层组合后的统一视角(上层会覆盖下层内容)。
分层角度容器:由镜像启动容器,相当于在镜像最上层增加一个“可读写的容器层”。容器启动后的每一步操作,都会建立新层,这种设计可以有效的回退。
(3)Dockerfile
Docker镜像创建脚本,用于镜像创建自动化(当然也可以启动容器,手动修改,commit 创建新镜像,这种只能在镜像级别复用)
优点:创建级别复用(创建新的镜像非常容易,降低了只读镜像修改的人力成本)。
(4)试验环境:
Docker Engine: 17.12.0-ce
二 Dockerfile 语法
(一)注释:
# 行注释内容
(二)命令:
Dockerfile命令 [参数1] ... [参数n]
(1)FROM
语法:FROM <image>[:<tag>] [AS <name>]
作用:基于指定镜像创建新镜像,***可选参数name用于指定新镜像名字******
注:必须是Dockerfile的第一个命令。
(2)LABEL
语法:LABEL <key>=<value> <key>=<value> <key>=<value> ...
作用:对镜像添加元数据,可以通过docker inspect <image>[:<tag>] 查看
(3)RUN
语法:RUN ["executable", "param1", "param2"]
作用:该命令会在一个新层中执行命令,并提交到当前镜像中。操作会记录在镜像的history中。
不能删除待测试
(4)CMD
语法:CMD command param1 param2
作用:由镜像启动容器时,提供一个默认的执行命令。
注:
a)在Dockerfile中只能出现一次,出现多次,最后一个有效。(可用于容器启动时启动某些服务)
b) docker run 指定了shell ,会覆盖CMD指定命令
(5)ENTRYPOINT
语法:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
作用:由镜像启动容器时,提供一个默认的执行命令。
注:
a) 同CMD,在Dockerfile中只能出现一次,出现多次,最后一个有效
b)不会被 docker run 指定了shell 覆盖
(5)EXPOSE
语法:EXPOSE <port> [<port>/<protocol>...]
作用:用于声明容器要开放的端口,只做“镜像构建人员”和“容器运行人员”协议声明,容器具体开放端口由 docker run -p 指定。
(6)ENV
语法:ENV <key>=<value> ...
作用:设置容器的环境变量,供后续的Dockerfile命令使用。
注:ENV 设置的环境变量,在容器启动后依然会存在。
(7)ARG
语法:ARG <name>[=<default value>]
作用:指定编译参数, 通常docker build 命令通过 --build-arg <varname>=<value> 传递。未传递时,这里可以指定默认值。保证后面${name}时不会产生问题。
(8)ADD
语法:ADD [--chown=<user>:<group>] <src>... <dest>
作用:将src(文件,目录,url定位的文件)拷贝dest。src可为多个路径且路径正则,压缩文件(identity, gzip, bzip2 or xz)自动解压。
(9)COPY
语法:COPY [--chown=<user>:<group>] <src>... <dest>
作用:将src(文件,目录)拷贝dest,不支持url,无解压功能
(10)VOLUME
语法:VOLUME ["/data"]
作用:挂在一个本机目录到容器中。不如使用docker -v 可以指定挂在到主机目录挂在到容器的那个目录。
(11)USER
语法:USER <user>[:<group>]
作用:为后面的Dockerfile命令(RUN, CMD and ENTRYPOINT)和启动容器指定用户和组
(12)WORKDIR
语法:WORKDIR /path/to/workdir
作用:为后面的Dockerfile命令(RUN, CMD, ENTRYPOINT, COPY and ADD)设置工作目录
(13)ONBUILD
语法:ONBUILD [INSTRUCTION]
作用:当前镜像作为其他镜像的基础镜像进行构建时,会执行ONBUILD指定的Dockerfile命令
三 Demo
基于centos latest 版本创建一个Jdk1.8 的image;
(1)准备
提前下载了jdk-8u161-linux-x64.tar.gz 放在构建目录中
目录结构
$ ls Dockerfile jdk-8u161-linux-x64.tar.gz
(2)Dockerfile
############################################################ # Dockerfile to build Java Installed Containers # Based on Centos Latest # docker build -t centos:java . ############################################################ FROM centos:latest LABEL author="puppet" \ description="Dockerfile to build Java Installed Containers" # ADD JDK ADD jdk-8u161-linux-x64.tar.gz /usr/local/ RUN /bin/bash -c 'cd /usr/local; ln -s jdk1.8.0_161 java' ENV JAVA_HOME=/usr/local/java ENV JRE_HOME=$JAVA_HOME/jre \ PATH=$JAVA_HOME/bin:$PATH \ CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOEM/lib/tools.jar
(3)执行: docker build -t centos:java .
$ docker build -t centos:java . Sending build context to Docker daemon 189.8MB Step 1/6 : FROM centos:latest ---> ff426288ea90 Step 2/6 : LABEL author="puppet" description="Dockerfile to build Java Installed Containers" ---> Running in 4cf474f6075b Removing intermediate container 4cf474f6075b ---> 93cf4bd9d690 Step 3/6 : ADD jdk-8u161-linux-x64.tar.gz /usr/local/ ---> f561ccfd45e6 Step 4/6 : RUN /bin/bash -c 'cd /usr/local; ln -s jdk1.8.0_161 java' ---> Running in 09182044d207 Removing intermediate container 09182044d207 ---> d8cf01f59569 Step 5/6 : ENV JAVA_HOME=/usr/local/java ---> Running in 1806eb8bf992 Removing intermediate container 1806eb8bf992 ---> b2fb294775e0 Step 6/6 : ENV JRE_HOME=$JAVA_HOME/jre PATH=$JAVA_HOME/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOEM/lib/tools.jar ---> Running in 89714e8cb5f9 Removing intermediate container 89714e8cb5f9 ---> ba26571b1f6a Successfully built ba26571b1f6a Successfully tagged centos:java
(4)验证
a)images
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos java ba26571b1f6a 50 seconds ago 592MB centos latest ff426288ea90 6 weeks ago 207MB
b)history
$ docker history centos:java IMAGE CREATED CREATED BY SIZE COMMENT ba26571b1f6a About a minute ago /bin/sh -c #(nop) ENV JRE_HOME=/usr/local/j… 0B b2fb294775e0 About a minute ago /bin/sh -c #(nop) ENV JAVA_HOME=/usr/local/… 0B d8cf01f59569 About a minute ago /bin/sh -c /bin/bash -c 'cd /usr/local; ln -… 12B f561ccfd45e6 About a minute ago /bin/sh -c #(nop) ADD file:94aa876a9a0b86c8b… 384MB 93cf4bd9d690 About a minute ago /bin/sh -c #(nop) LABEL author=puppet descr… 0B ff426288ea90 6 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 6 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Im… 0B <missing> 6 weeks ago /bin/sh -c #(nop) ADD file:6bba01fe946852a56… 207MB
注:这里可以看到容器的层记录,最下面的三个是基础容器centos:latest的层记录。
c)启动容器检查
$ docker run -tid --name java centos:java /bin/bash ba60384d1c0fc7267e450c2c1ecebcf7b462de6f82621ef75d6e9b390dbe95d2 $ docker exec -ti java /bin/bash [root@ba60384d1c0f /]# java -version java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode) [root@ba60384d1c0f /]# whereis java java: /usr/local/java /usr/local/jdk1.8.0_161/bin/java
附录:
参考:https://docs.docker.com/engine/reference/builder