在介绍Dockerfile实现机制之前,先介绍两个docker命令docker commit和docker build。
3.1 docker commit命令
对于已运行的容器,可通过docker commit将容器环境保存为镜像。使用如下案例进行说明。
【1】下载并运行httpd容器
#下载httpd镜像
[root@VM-4-6-centos ~]# docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
c57ee5000d61: Pull complete
ef22398cad3c: Pull complete
4f4fb700ef54: Pull complete
f420b40fd7be: Pull complete
ea4892b1a58d: Pull complete
1fe3871b50ff: Pull complete
Digest: sha256:5ee9ec089bab71ffcb85734e2f7018171bcb2d6707f402779d3f5b28190bb1af
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
#将httpd镜像运行为name为seong-httpd的容器
[root@VM-4-6-centos ~]# docker run -d --name seong-httpd httpd
bafc6d34768cc80bbac03b2cd3020a5efbb202d23660b8012d1621e2c5b67155
【2】进入httpd容器内部,进行定制化操作
#进入seong-httpd容器内部
[root@VM-4-6-centos ~]# docker exec -it bafc6d34768cc8 bash
#创建/test/seong/test.txt文件,并向文件中输入测试数据
root@bafc6d34768c:/usr/local/apache2# mkdir -p /test/seong && cd /test/seong && touch test.txt && echo "test docker commit by httpd case" > test.txt
#退出容器
root@bafc6d34768c:/test/seong# exit
exit
【3】通过docker commit命令将运行的容器保存为镜像
#将运行的容器保存为httpd:beta-1镜像
[root@VM-4-6-centos ~]# docker commit bafc6d34768cc8 httpd:beta-1
sha256:ad7b48d6fefe19a381ea347087ddd9a0bd0d253e74f76380c7bb23985bf22b65
#查看镜像httpd:beta-1是否已经生成
[root@VM-4-6-centos ~]# docker images | grep httpd
httpd beta-1 ad7b48d6fefe 41 seconds ago 167MB
httpd latest 59bcd61b45fd 3 weeks ago 167MB
【4】将生成的镜像再次运行为容器
#将httpd:beta-1运行为容器
[root@VM-4-6-centos ~]# docker run -d --name seong-httpd-beta-1 httpd:beta-1
e134dd58105dd511638067316f954268c3482258387dc077a7cca3747e3a748c
【5】进入容器内部查看定制化操作
[root@VM-4-6-centos ~]# docker exec -it e134dd58105dd bash
root@e134dd58105d:/usr/local/apache2# cat /test/seong/test.txt
test docker commit by httpd case
3.2 docker build命令
Dockerfile需要被Docker引擎解析,然后生成docker镜像,用户可通过提供的docker build命令进行操作。
使用docker build命令构建镜像时,docker引擎需要镜像的名称(可以包含版本号),Dockerfile路径和构建上下文路径。
常用的命令格式如下:
docker build -t ${镜像名称} -f ${Dockerfile路径} ${建上下文路径}
**说明:**镜像名称可以添加版本号,如seong:V1.0.0,不传默认我是latest; Dockerfile路径需要精确到文件名,可以使用相对路径或绝对路径;建上下文路径是COPY和ADD操作时的源路径。
另外,可以传入构建参数,如:–build-arg(设置构建时的环境变量),–no-cache(禁用缓存)等。
3.3 Dockerfile实现机制
几年前学习docker时记录的笔记如下: Docker底层都是通过docker commit生成镜像。区别在于Docker引擎在外层进行了一层封装,将读取和解析Dockerfile和执行Dockerfile中的指令通过docker build接口开放给了用户。与《每天5分钟玩转Docker容器技术》中介绍的内容一致。
再次实践操作发现,Docker引擎构建时直接操作的镜像,而没有docker commit的中间过程,猜想: Docker为了提高构建速度,在新版本中进行了优化。[对这部分熟悉的读者,请在留言区进行指点]
以下通过案例显示docker构建镜像的过程:
【1】创建Dockerfile文件,内容如下:
FROM httpd
WORKDIR /usr/local
COPY test.txt .
RUN echo "---test docker build---" >> test.txt
说明:当前路径下包含test.txt和Dockerfile两个文件,test.txt文件内容为abc.
【2】将Dockerfile构建为docker镜像
[root@VM-4-6-centos test-docker]# docker build --progress=plain -t httpd:beta2 .
#0 building with "default" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 131B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/httpd:latest
#3 DONE 0.0s
#4 [1/4] FROM docker.io/library/httpd
#4 DONE 0.0s
#5 [internal] load build context
#5 transferring context: 29B done
#5 DONE 0.0s
#6 [3/4] COPY test.txt .
#6 CACHED
#7 [2/4] WORKDIR /usr/local
#7 CACHED
#8 [4/4] RUN echo "---test docker build---" >> test.txt
#8 CACHED
#9 exporting to image
#9 exporting layers done
#9 writing image sha256:559eaf86a53b35088adb3b5163be15714421285503447a68301ed83ea1c2f0ed done
#9 naming to docker.io/library/httpd:beta2 done
#9 DONE 0.0s
流程较为清晰:加载Dockerfile、依赖的httpd镜像、构建上下文, 对每个指令都会生产一个中间镜像。
【3】将生成的镜像运行为容器,并查看Dockerfile中的定制内容
#查看镜像是否生成
[root@VM-4-6-centos test-docker]# docker images | grep httpd
httpd beta2 559eaf86a53b About a minute ago 167MB
httpd latest 59bcd61b45fd 3 weeks ago 167MB
#将镜像运行为容器
[root@VM-4-6-centos test-docker]# docker run -d --name seong-http-beta2 httpd:beta2
b3cb2c7282bf10e309ee49631b73e3bf0b9fdda834281185c690f558730d4397
#进入容器内部查看Dockerfile中的定制内容
[root@VM-4-6-centos test-docker]# docker exec -it b3cb2c7282bf10 bash
root@b3cb2c7282bf:/usr/local# cat /usr/local/test.txt
abc
---test docker build---
root@b3cb2c7282bf:/usr/local#