接着学习使用Dockerfile构建镜像,Dockerfile使用基于DSL语法的指令来构建一个Docker镜像,之后使用docker build命令运行Dockerfile中的指令构建一个新的镜像。
$ mkdir ubuntu_with_vim
$ cd ubuntu_with_vim/
$ touch Dockerfile
$ ls
Dockerfile
首先我们创建一个名为ubuntu_with_vim的文件夹,这个文件夹就称为我们的构建环境,Docker称此环境为上下文或构建上下文,Docker会在构建镜像时将构建上下文和构建上下文下的文件和目录上传到Docker守护进程,然后我们还创建了一个空Dockerfile。接下来在Dockerfile中输入以下指令:
$ cat Dockerfile
# Version: 0.0.1
FROM jie/ubuntu:1
MAINTAINER lebron james "james@gmail.com"
RUN apt-get -y update
RUN apt-get -y install vim
RUN echo 'I am the King!' > /1.txt
EXPOSE 90
可以看出Dockerfile是由一系列指令和参数组成,每条指令,如FROM,都必须为大写字母且后面要跟一个参数,Dockerfile中的指令会按顺序从上到下执行。每条指令都会创建一个新的镜像层并对镜像进行提交,Dockerfile中的指令大致按照下列顺序执行:
a.Docker从基础镜像运行一个容器。
b.执行一条指令,对容器做出修改。
c.执行类似docker commit的操作,提交一个新的镜像层。
d.Docker再基于刚提交的镜像运行一个新容器。
e.执行Dockerfile中的下一条指令,直到所有指令都执行完毕。
如果执行某条指令失败,仍能得到前一条指令创建的镜像。我们可以创建基于该镜像的容器,然后调试Dockerfile中指令。现在来具体的看一下这个Dockerfile中的代码,与shell脚本相同,上面Dockerfile 的第一句就是注释,接着第一条指令为FROM,FROM指令指定一个已经存在的镜像(jie/ubuntu:1为我自己做的一个镜像,主要修改了原始ubuntu镜像中软件源),后续指令都基于该镜像进行,这个镜像被称为基础镜像。MAINTAINER 指令说明了镜像作者的一些信息,可以标识镜像的所有者和联系方式。RUN指令会在当前镜像的容器中运行后跟的命令,如果指令执行成功,就会将此镜像层提交,之后执行Dockerfile中的下一条指令,EXPOSE指令指定镜像内应用程序将使用的端口。出于安全的原因,Docker并不会自动打开该端口,需要docker run创建容器时指定要打开那些端口。使用多个EXPOSE指令可以向外公开多个端口。接下来使用docker build命令构建新镜像。
$ docker build -t="jix/ubuntu_with_vim" .
Sending build context to Docker daemon 2.048 kB
Step 1/6 : FROM jie/ubuntu:1
---> 6ff2d208c1a8
Step 2/6 : MAINTAINER lebron james "james@gmail.com"
---> Using cache
---> 0689a7f0ee36
Step 3/6 : RUN apt-get -y update
---> Running in 5fa5d15fbf27
Hit:1 http://mirrors.163.com/ubuntu xenial InRelease
Hit:2 http://mirrors.163.com/ubuntu xenial-updates InRelease
Hit:3 http://mirrors.163.com/ubuntu xenial-security InRelease
Reading package lists...
---> c8c93c831bea
Removing intermediate container 5fa5d15fbf27
Step 4/6 : RUN apt-get -y install vim
---> Running in d6721e17a9c5
Reading package lists...
Building dependency tree...
Reading state information...
Suggested packages:
ctags vim-doc vim-scripts
The following NEW packages will be installed:
vim
0 upgraded, 1 newly installed, 0 to remove and 9 not upgraded.
Need to get 1036 kB of archives.
After this operation, 2458 kB of additional disk space will be used.
Get:1 http://mirrors.163.com/ubuntu xenial-updates/main amd64 vim amd64 2:7.4.1689-3ubuntu1.2 [1036 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 1036 kB in 15s (64.8 kB/s)
Selecting previously unselected package vim.
(Reading database ... 9936 files and directories currently installed.)
Preparing to unpack .../vim_2%3a7.4.1689-3ubuntu1.2_amd64.deb ...
Unpacking vim (2:7.4.1689-3ubuntu1.2) ...
Setting up vim (2:7.4.1689-3ubuntu1.2) ...
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rvim (rvim) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rview (rview) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vi (vi) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/view (view) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/ex (ex) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode
---> dea7372a2bd4
Removing intermediate container d6721e17a9c5
Step 5/6 : RUN echo 'I am the King!' > /1.txt
---> Running in 64af773762ad
---> 34f58c86342c
Removing intermediate container 64af773762ad
Step 6/6 : EXPOSE 90
---> Running in 3e838af0f4c2
---> febb5b5e2c27
Removing intermediate container 3e838af0f4c2
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jix/ubuntu_with_vim latest febb5b5e2c27 About a minute ago 228 MB
<none> <none> 3262427af467 8 minutes ago 225 MB
jie/ubuntu 1 6ff2d208c1a8 9 minutes ago 225 MB
使用-t选项为新镜像指定仓库名和镜像名,上面docker build命令的最后一个参数,指定一个目录,docker build命令会在该目录下查找Dockerfile。我们可以使用新的镜像启动一个容器。
$ docker run -it -d -p 90 --name ubuntu_with_vim jix/ubuntu_with_vim /bin/bash
我们这次创建容器的docker run命令中使用了-p选项,该选项用来指定Docker在运行时公开哪些网络端口给宿主机,运行一个容器时,Docker可以通过两种方法在宿主机上分配端口。
a.docker可以在宿主机上随机选择一个小于65535的一个比较大的端口来映射到容器的90端口。
b.可以在宿主机上指定一个具体的端口号来映射到容器中的端口号。
使用docker ps命令来看一下容器的端口分配情况:
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
129b1e040f44 jix/ubuntu_with_vim "/bin/bash" 7 seconds ago Up 7 seconds 0.0.0.0:32772->90/tcp ubuntu_with_vim
可以看到,容器中的90端口被映射到宿主机的32772上。我们也可以通过docker port来查看容器的端口映射情况。
$ docker port ubuntu_with_vim
90/tcp -> 0.0.0.0:32772
使用-p选项可以灵活地管理和宿主机之间的端口映射关系,可以指定将容器中的端口号映射到宿主机特定端口上。
$ docker run -it -d -p 9000:90 --name ubuntu_with_vim jix/ubuntu_with_vim /bin/bash
也可以将不同的端口绑定到不同的宿主机端口上。
$ docker run -it -d -p 127.0.0.1:9000:90 --name ubuntu_with_vim jix/ubuntu_with_vim /bin/bash
Docker还提供了一个更简单的方式,即-P参数,该参数可以用来对外公开在Dockerfile中EXPOSE指令中设置的所有端口。
$ docker run -it -d -P --name ubuntu_with_vim jix/ubuntu_with_vim /bin/bash
今天我们主要介绍了利用Dockerfile构建镜像的大致过程,实际上Dockerfile中可以使用很多指令,这些指令包括CMD、ENTRYPOINT、ADD、COPY、VOLUME、WORKDIR、USER、ONBUILD、ENV等指令,总之今天对Dockerfile的学习只是一个入门,在以后的学习中再慢慢深入。