Dockerfile 使用

 

编写不易,转载请注明(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

 

猜你喜欢

转载自shihlei.iteye.com/blog/2411453