一.镜像构造过程
运行容器–修改容器–将容器保存为新的镜像
特点:
效率低、可重复性弱、容易出错
使用者无法对镜像进行审计,会存在安全隐患
以busybox镜像为例,以Dockerfile进行构造
[root@server1 ~]# docker load -i busybox.tar ##加载镜像
8a788232037e: Loading layer 1.37MB/1.37MB
Loaded image: busybox:latest
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
[root@server1 ~]# mkdir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# vim Dockerfile ##编辑发送内容
FROM busybox
RUN echo 'hello world'
[root@server1 docker]# docker build -t busybox:v1 . ##创建镜像从当前目录获取
Sending build context to Docker daemon 2.048kB ##将所有内容发送给docker引擎
Step 1/2 : FROM busybox
---> 59788edf1f3e
Step 2/2 : RUN echo 'hello world'
---> Running in 37288a916f93
hello world
Removing intermediate container 37288a916f93
---> babcf20e02cc
Successfully built babcf20e02cc
Successfully tagged busybox:v1
[root@server1 docker]# docker images ##查看v1镜像是否构造成功
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox v1 babcf20e02cc 2 minutes ago 1.15MB
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
[root@server1 docker]# docker history busybox:v1
IMAGE CREATED CREATED BY SIZE COMMENT
babcf20e02cc 2 minutes ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
RUN echo 'hello world'
RUN echo 'westos linux'
[root@server1 docker]# docker build -t busybox:v2 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> 59788edf1f3e ##基于busybox构造
Step 2/3 : RUN echo 'hello world'
---> Using cache ##基于v1构造
---> babcf20e02cc
Step 3/3 : RUN echo 'westos linux'
---> Running in 759bff5a58c0
westos linux
Removing intermediate container 759bff5a58c0
---> a6bf41b5c916
Successfully built a6bf41b5c916
Successfully tagged busybox:v2
[root@server1 docker]# docker history busybox:v2
IMAGE CREATED CREATED BY SIZE COMMENT
a6bf41b5c916 26 seconds ago /bin/sh -c echo 'westos linux' 0B
babcf20e02cc 7 minutes ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
二.Dockerfile的详细介绍
1.Dockerfile的常用指令
(1)FROM:
用于指定base镜像,本地不存在会从远程仓库进行下载
(2)MAINTAINER:
设置镜像的作者,不是必须存在的
(3)COPY:
把文件复制到镜像(容器层)
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY Dockerfile / ##将文件拷贝到/下
[root@server1 docker]# docker rmi busybox:v2 ##删除不用的镜像
[root@server1 docker]# docker build -t busybox:v2 . ##创建新镜像
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM busybox
---> 59788edf1f3e
Step 2/2 : COPY Dockerfile /
---> dab227a9e7d4
Successfully built dab227a9e7d4
Successfully tagged busybox:v2
[root@server1 docker]# docker run -it --rm busybox:v2 ##运行此镜像
/ # ls ##查看Dockerfile复制成功
Dockerfile dev home root tmp var
bin etc proc sys usr
(4)ADD:
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可自动下载URL并拷贝到镜像
[root@server1 docker]# ls
Dockerfile nginx-1.15.8.tar.gz
[root@server1 docker]# vim Dockerfile
FROM rhel7
ADD nginx-1.15.8.tar.gz /mnt
[root@server1 docker]# docker build -t rhel7:v1 . ##创建镜像
Sending build context to Docker daemon 1.031MB
Step 1/2 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/2 : ADD nginx-1.15.8.tar.gz /mnt
---> 0e8b7ee1db36
Successfully built 0e8b7ee1db36
Successfully tagged rhel7:v1
[root@server1 docker]# docker run -it --rm rhel7:v1 bash ##创建并运行容器
bash-4.2# cd /mnt
bash-4.2# ls ##解压到指定目录成功
nginx-1.15.8
bash-4.2# cd nginx-1.15.8/
bash-4.2# ls
CHANGES LICENSE auto configure html src
CHANGES.ru README conf contrib man
(5)ENV:
设置环境变量,变量可以被后续的指令使用
[root@server1 docker]# docker history game2048:latest
IMAGE CREATED CREATED BY
<missing> 2 years ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.11.7 0B
(6)EXPOSE:
如果容器中运行应用服务,则可以包服务端口暴露出去
[root@server1 docker]# docker history game2048:latest
IMAGE CREATED CREATED BY SIZE COMMENT
<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B ##暴露镜像内部的应用
<missing> 2 years ago /bin/sh -c #(nop) COPY dir:cb74e9c037a3d501c… 600kB
<missing> 2 years ago /bin/sh -c #(nop) MAINTAINER Golfen Guo <go… 0B
<missing> 2 years ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0B
(7)VOLUME:
申明数据卷,通常指定的是应用的数据挂载点
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/data"] ##创建数据卷到/data,启动容器的时候也会自动创建
[root@server1 docker]# docker build -t rhel7:v2 . ##创建镜像
Sending build context to Docker daemon 1.031MB
Step 1/3 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/3 : EXPOSE 80
---> Running in cef2d2797cc9
Removing intermediate container cef2d2797cc9
---> f968118ce8cf
Step 3/3 : VOLUME ["/data"]
---> Running in a7d6e2d3ede3
Removing intermediate container a7d6e2d3ede3
---> 03f4f62190a2
Successfully built 03f4f62190a2
Successfully tagged rhel7:v2
[root@server1 docker]# docker run -it --rm rhel7:v2 bash ##创建并运行容器
bash-4.2# ls
bin data etc lib media opt root sbin sys usr
boot dev home lib64 mnt proc run srv tmp var
bash-4.2# cd /data/
bash-4.2# ls
在保持此容器运行状态下,查看此容器的具体信息
[root@server1 ~]# cd /var/lib/docker/volumes/ ##mount数据库挂载点
[root@server1 volumes]# ls
70e5aa4c9ccf148a3c65684ebbaf96981a859d797ced0c61f49c8515cfad864a metadata.db
[root@server1 volumes]# cd 70e5aa4c9ccf148a3c65684ebbaf96981a859d797ced0c61f49c8515cfad864a
[root@server1 70e5aa4c9ccf148a3c65684ebbaf96981a859d797ced0c61f49c8515cfad864a]# ls
_data
[root@server1 70e5aa4c9ccf148a3c65684ebbaf96981a859d797ced0c61f49c8515cfad864a]# cd _data/
[root@server1 _data]# touch file1 ##此时创建的文件会自动挂载到容器内部,即进入容器湖欧会看到创建的内容
[root@server1 _data]# docker volume ls ##查看数据卷信息
DRIVER VOLUME NAME
local 465067a1ef6189e32236adadc13f315abf63f0e1d1ab011f433c5c60ea26430a
(8)WORKDIR:
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在也会自动创建
(9)RUN:
在容器中运行命令并创建新的镜像层,常用于安装软件包
[root@server1 docker]# vim Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"] ##数据卷挂载点
ADD nginx-1.15.8.tar.gz /mnt ##解压到/mnt下
COPY westos.repo /etc/yum.repos.d/westos.repo ##需要在docker目录下配置一个yum源
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.15.8
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
[root@server1 docker]# docker build -t rhel7:v1 .
[root@server1 docker]# docker run -it --rm rhel7:v1 bash ##创建容器并运行
bash-4.2# cd /mnt
bash-4.2# ls
nginx-1.15.8
bash-4.2# cd nginx-1.15.8/
bash-4.2# cd /usr/local/
bash-4.2# ls
bin etc games include lib lib64 libexec nginx sbin share src
bash-4.2# cd nginx/
bash-4.2# ls
conf html logs sbin
(10)CMD与ENTRYPOINT:
设置容器启动后执行的命令,但是CMD会被docker run 后面的命令覆盖,但ENTRYPOINT不会
Dockerfile中只能指定一个ENTRYPOINT,如果指定过多则只有最后一个有效
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
CMD echo hello $name
[root@server1 docker]# docker build -f Dockerfile -t busybox:v1 .
Sending build context to Docker daemon 1.031MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Running in f7718a5c33db
Removing intermediate container f7718a5c33db
---> e5c9df070e6d
Step 3/3 : CMD echo hello $name
---> Running in 7f03b4519831
Removing intermediate container 7f03b4519831
---> 2ed2629f2683
Successfully built 2ed2629f2683
Successfully tagged busybox:v1
[root@server1 docker]# docker run --rm busybox:v1
hello world