关于重建镜像包的Dockerfile文件的书写依据,可以从镜像包的history中查看到,以镜像包game2048为例:
[root@foundation17 docker]# docker history game2048
IMAGE CREATED CREATED BY SIZE COMMENT
19299002fdbe 20 months ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "se... 0 B
<missing> 20 months ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B
<missing> 20 months ago /bin/sh -c #(nop) COPY dir:cb74e9c037a3d50... 600 kB
<missing> 20 months ago /bin/sh -c #(nop) MAINTAINER Golfen Guo <... 0 B
<missing> 20 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daem... 0 B
<missing> 20 months ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0 B
<missing> 20 months ago /bin/sh -c #(nop) COPY file:d15ceb73c6ea77... 1.1 kB
<missing> 20 months ago /bin/sh -c #(nop) COPY file:af94db45bb7e4b... 643 B
<missing> 20 months ago /bin/sh -c GPG_KEYS=B0F4253373F8F6F510D421... 50.1 MB
<missing> 20 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.11.7 0 B
<missing> 22 months ago /bin/sh -c #(nop) MAINTAINER NGINX Docker... 0 B
<missing> 22 months ago /bin/sh -c #(nop) ADD file:7afbc23fda8b0b3... 4.8 MB
也就是说,重建镜像包的过程和镜像包的使用过程类似,通过对镜像包使用过程中比如上面EXPOSE、CMD、COPY等动作的重写,来重建镜像包。所以在Dockerfile文件中,其实就是对这些动作的重写。而关于这些动作中具体需要执行的指令,可以先新建一个容器做实验实现功能进行测试,然后将这个实验过程的指令和操作写入Dockerfile文件中。
(注:本文所涉及所有文件,均在/tmp/docker目录下,目录结构:)
[root@foundation17 docker]# tree .
.
├── Dockerfile
├── dvd.repo
├── supervisord.conf
└── web
└── index.html
1 directory, 4 files
例一:重写rhel7镜像包,实现httpd的安装和启动
1.在/tmp/docker目录下新建文件Dockerfile:
[root@foundation17 docker]# cd /tmp/docker/
[root@foundation17 docker]# vim Dockerfile
文件内容:
1 FROM rhel7 #重建镜像的源镜像,必须先得有这个镜像
2 ENV HOSTNAME server1 #设定容器主机名
3 MAINTAINER chen #作者信息
4 EXPOSE 80 #httpd服务端口
5 COPY dvd.repo /etc/yum.repos.d/dvd.repo #拷贝yum源文件
6 RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all #镜像操作命令
7 VOLUME ["/var/www/html"] #镜像启动命令
8 CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
2.还是在当前目录下新件文件dvd.repo,这个文件就是Dockerfile文件中COPY指令行所要复制文件的源文件,用来搭建使用新镜像包生成的容器的yum源。没有yum源就法执行下面的RUN指令来安装httpd:
[root@foundation17 docker]# vim dvd.repo
文件内容:
1 [source7.3]
2 name=source7.3
3 baseurl=http://172.25.17.250/source7.3
4 gpgcheck=0
3.文件编写完成之后,就可以重建镜像包并设定TAG为v1,这个可以随便写,只是一个标签而已:
注意:指令最后面还有个点,表示Dockerfile文件在当前目录,不能忽略了!
[root@foundation17 docker]# docker build -t rhel7:v1 .
重建镜像包会逐步编译Dockerfile,没有问题会在最后面提示建立成功:
Successfully built af1cbc442eab
3.可以发现建立成功的提示后面有一个码af1cbc442eab,这个码就是rhel7镜像v1的码:
[root@foundation17 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v1 af1cbc442eab 31 seconds ago 169 MB
rhel7 latest 0a3eb3fde7fd 4 years ago 140 MB
4.用新建的镜像建立一个容器vm3并将httpd首页文件所在的目录挂载到httpd的默认发布目录下,查看容器vm3的ip为172.17.0.3:
[root@foundation17 docker]# docker run -d --name vm3 -v /tmp/docker/web/:/var/www/html rhel7:v1
[root@foundation17 docker]# docker inspect vm3 |grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
写好首页文件index.html,在浏览器访问172.17.0.3就可以访问到首页文件,这样镜像的重建和测试就完成了:
例二:使用supervisor工具实现httpd和sshd的安装和启动
supervisor是一个进程管理工具,用途是管理(启动,停止,重启等操作)一个或多个进程(当系统需要同时管理多个进程的时候,supervisor是一个不错的选择)。supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作supervisor的子进程来启动,所以我们只需要将要管理进程的可执行文件的路径添加到supervisor的配置文件中就好了。此时被管理进程被视为supervisor的子进程,若该子进程异常中断,则父进程可以准确的获取子进程异常中断的信息,通过在配置文件中设置autostart=ture,可以实现对异常中断的子进程的自动重启。
1.编写Dockerfile文件:
文件内容:
关于文件内容中的三条ssh-keygen 指令,均是为容器中配置sshd服务时,生成所必要的key文件。
1 FROM rhel7
2 ENV HOSTNAME server3
3 MAINTAINER chen
4 EXPOSE 80 22
5 COPY dvd.repo /etc/yum.repos.d/dvd.repo
6 RUN rpmdb --rebuilddb && yum install -y httpd openssh-server openssh-clients supervisor && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" &&ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos |chpasswd
7 COPY supervisord.conf /etc/supervisord.conf
8 CMD ["/usr/bin/supervisord"]
2.新建supervisor配置文件supervisord.conf:
[root@foundation17 docker]# vim supervisord.conf
文件内容:
1 [supervisord]
2 nodaemon=true
3
4 [program:ssh]
5 command=/usr/sbin/sshd -D #开启sshd服务
6
7 [program:httpd]
8 command=/usr/sbin/httpd #开启httpd服务
3.编辑yum源文件:
[root@foundation17 docker]# vim dvd.repo
这里的source7.3 yum源就是普通的yum源,docker yum源只是提供了supervisor工具的安装包。不指定这个docker安装包也可以,那就需要自己下载supervisor安装包并在Dockerfile文件里添加指令进行安装。本文所使用的supervisor工具包版本为:
supervisor-3.1.3-3.el7.noarch.rpm
文件内容:
1 [source7.3]
2 name=source7.3
3 baseurl=http://172.25.17.250/source7.3
4 gpgcheck=0
5
6 [docker]
7 name=docker
8 baseurl=http://172.25.254.250/pub/docker
9 gpgcheck=0
4.重建镜像包:命名为rhel7镜像的v3版本:
[root@foundation17 docker]# docker build -t rhel7:v3 .
5.测试:
利用新建的镜像生成一个容器vm1,并将首页文件所在目录挂载到httpd的默认发布目录:
[root@foundation17 docker]# docker run -d --name vm1 -v /tmp/docker/web/:/var/www/html rhel7:v3
查看容器ip:
[root@foundation17 docker]# docker inspect vm1 |grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
httpd服务访问测试:解析到首页文件内容:
[root@foundation17 docker]# curl 172.17.0.2
<h1>hello nginx</h1>
sshd服务测试:成功连接
[root@foundation17 docker]# ssh -l root 172.17.0.2
The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.
ECDSA key fingerprint is b5:f1:f1:55:d6:5c:34:22:d6:06:6e:4c:3d:08:ff:da.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
root@172.17.0.2's password:
-bash-4.2# exit
例三:重建镜像直接将nginx发布目录加入镜像
直接将nginx的默认发布目录制作成tar包并加入到镜像,这样对于每一个使用nginx镜像新建的容器,都可以直接访问到提前写好的首页内容,不需要再新建
1. 在/tmp/docker/test目录下,新建目录nginx/html并在该目录下写入首页发布文件
[root@foundation17 test]# pwd
/tmp/docker/test
[root@foundation17 test]# mkdir nginx/html -p
[root@foundation17 test]# cd nginx/html/
[root@foundation17 html]# vim index.html
[root@foundation17 html]# cat index.html
<h1>hello linux </h1>
2. 将nginx目录制作成tar包,tar包里包含nginx的默认发布目录和首页文件:
[root@foundation17 test]# tar -cf nginx.tar nginx/
[root@foundation17 test]# tar tf nginx.tar
nginx/
nginx/html/
nginx/html/index.html
3. 新建镜像重建文件Dockerfile:
[root@foundation17 test]# vim Dockerfile
[root@foundation17 test]# cat Dockerfile
FROM rhel7
ADD nginx.tar /usr/share
VOLUME ["/usr/share/nginx/html"]
要保证nginx.tar包和Dockerfile文件在同一目录下:
[root@foundation17 test]# pwd
/tmp/docker/test
[root@foundation17 test]# ls
Dockerfile nginx nginx.tar
4.使用Dockerfile文件新建镜像rhel7:v4:
[root@foundation17 test]# docker build -t rhel7:v4 .
Sending build context to Docker daemon 14.85 kB
Step 1/3 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/3 : ADD nginx.tar /usr/share
---> d04cf9e6825a
Removing intermediate container f5cc16797ab3
Step 3/3 : VOLUME /usr/share/nginx/html
---> Running in 19b2158db771
---> bb0f642deb16
Removing intermediate container 19b2158db771
Successfully built bb0f642deb16
利用刚才建立的rhel:v4创建一个逻辑卷命名为vol,并使用该逻辑卷创建一个容器vm1:
[root@foundation17 test]# docker create --name vol rhel7:v4 bash
96b96081acea561a35b4697e834e3b3f0ca97448b479173d513f98c8291dc252
[root@foundation17 test]# docker run -d --name vm1 --volumes-from vol nginx
af22cb0264fa5c30cb1c8c7eabf525f433a4fe8fd6535fcf8e6742cf622a2bb1
5.测试:
查询容器端口:
[root@foundation17 test]# docker inspect vm1 |grep IPA
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
解析到首页内容:
[root@foundation17 test]# curl 172.17.0.2
<h1>hello linux </h1>