Docker容器——镜像的封装以及Dockerfile的编写

一、commit封装镜像

我们以ubuntu的镜像为例:
首先有ubentu的镜像

[root@server1 ~]# docker images ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              07c86167cdc4        3 years ago         188MB

我们先建立vm1容器,然后对其进行一些操作,然后ctrl+p+q退出

[root@server1 ~]# docker run -it --name vm1 ubuntu
root@6074aca22100:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
root@6074aca22100:/# touch file{1..10}
root@6074aca22100:/# ls
bin   etc     file2  file5  file8  lib    mnt   root  srv  usr
boot  file1   file3  file6  file9  lib64  opt   run   sys  var
dev   file10  file4  file7  home   media  proc  sbin  tmp

在上面的基础上我们删除vm1容器,然后重新建立,查看建立的文件是否还存在

[root@server1 ~]# docker rm -f vm1
vm1
[root@server1 ~]# docker run -it --name vm1 ubuntu
root@94a7b7a6ffc0:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

我们可以发现我们创建的文件没有了,我们的操作没有被保存。
那么我们如果需要让其继续存在就需要重新建立,然后重新commit封装即可

root@94a7b7a6ffc0:/# touch file{1..10}
root@94a7b7a6ffc0:/# ls
bin   etc     file2  file5  file8  lib    mnt   root  srv  usr
boot  file1   file3  file6  file9  lib64  opt   run   sys  var
dev   file10  file4  file7  home   media  proc  sbin  tmp

ctrl+d释放资源退出,封装镜像

root@94a7b7a6ffc0:/# exit
[root@server1 ~]# docker commit -m "add files" vm1 ubuntu:v1
sha256:387e3d445215ca2e177b4c8f0ae3807edffd919a13be237ebcc5e69c4f1523b8

在这里插入图片描述
在这里插入图片描述
然后我们用我们重新封装的镜像来运行容器。

[root@server1 ~]# docker run -it --name vm2 ubuntu:v1 
root@a5fe8bd9c26b:/# ls
bin   etc     file2  file5  file8  lib    mnt   root  srv  usr
boot  file1   file3  file6  file9  lib64  opt   run   sys  var
dev   file10  file4  file7  home   media  proc  sbin  tmp

我们可以发现我们之前的文件依旧被保存了下来

二、Dockerfile的编写,封装镜像

在之前清理之前的实验环境

  docker rm -f vm1
  docker rm -f vm2
  docker ps -a
  docker rmi ubuntu:v1 
  • 编写Dockerfile实现安装httpd

1.导入rhel7的镜像

[root@server1 ~]# docker load -i rhel7.tar 
e1f5733f050b: Loading layer  147.1MB/147.1MB

2.编写Dockerfile

[root@server1 ~]# docker load -i rhel7.tar 
e1f5733f050b: Loading layer  147.1MB/147.1MB
[root@server1 ~]# cd /tmp/docker/
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile 
FROM rhel7		#源镜像是rhel7,最好将rhel7的镜像放在本地
COPY yum.repo /etc/yum.repos.d/yum.repo		##复制一个yum源
RUN rpmdb --rebuilddb && yum install -y httpd	##执行命令安装httpd并清除yum缓存
##rpmdb命令用于初始化和重建rpm数据库 --rebuilddb 从已安装的包头文件,反向重建RPM数据库
EXPOSE 80		##定义端口
CMD ["/usr/sbin/httpd","-D","FOREGROUND"] #打开apache服务-D是全局文件/etc/sysconfig/httpd中打开的参数

3.编写yum.repo(当前目录下)

[root@server1 docker]# vim yum.repo
[root@server1 docker]# ca yum.repo
-bash: ca: command not found
[root@server1 docker]# cat yum.repo
[rhel7.3]
name=rhel7.3
baseurl=http://172.25.66.250/rhel7.3
gpgcheck=0

4.封装镜像,并且测试能否使用

[root@server1 docker]# docker build -t rhel7:v1 .
注意后面的点,表示当前目录,我们设置其标签为v1

在这里插入图片描述

在这里插入图片描述
最后我们可以发现编写成功

[root@server1 docker]# docker images rhel7:v1 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
rhel7               v1                  41e959659080        2 minutes ago       193MB

5.我们使用新的镜像来运行一个新的容器,并将httpd默认发布文件所在目录挂载到httpd的默认发布目录下

[root@server1 ~]# cd /tmp/docker/
[root@server1 docker]# ls
Dockerfile  index.html  yum.repo
[root@server1 docker]# mkdir web
[root@server1 docker]# mv index.html web/
[root@server1 docker]# docker run -d --name vm1 -p 80:80 -v /tmp/docker/web/:/var/www/html rhel7:v1 
3f1d0e90e349c373c879f361476e81ed2922637035de56962041053bb423d80d
[root@server1 docker]# curl 172.25.66.1
hello
hello
hello

在这里插入图片描述
6.我们修改默认发布文件,然后继续访问测试

	[root@server1 docker]# cd web/
[root@server1 web]# echo www.ljz.org > index.html 
[root@server1 web]# curl 172.25.66.1
www.ljz.org

我们可以发现只要我们修改默认发布界面即可

三、Dockerfile编写常用指令

  • ADD
    用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:
    ADD html.tar /var/www
    ADD http://ip/html.tar /var/www
  • ENV
    设置环境变量,变量可以被后续的指令使用:
    ENV HOSTNAME sevrer1.example.com
  • EXPOSE
    如果容器中运行应用服务,可以把服务端口暴露出去:
    EXPOSE 80
  • VOLUME
    申明数据卷,通常指定的是应用的数据挂在点:
    VOLUME ["/var/www/html"]
  • WORKDIR
    为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工
    作目录,如果目录不存在会自动创建。
  • RUN
    在容器中运行命令并创建新的镜像层,常用于安装软件包:
    RUN yum install -y vim
  • CMD 与 ENTRYPOINT区别:
    这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行
  • docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
  • Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

示例

1.首先我们导入一个输出字符的镜像

[root@server1 ~]# ls
busybox.tar  docker  game2048.tar  nginx.tar  rhel7.tar  ubuntu.tar
[root@server1 ~]# docker load -i busybox.tar 
8a788232037e: Loading layer   1.37MB/1.37MB
Loaded image: busybox:latest

2.编写Dockerfile文件

[root@server1 docker]# ls
Dockerfile  web  yum.repo
[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM busybox
ENV name world	#设置环境变量
ENTRYPOINT echo "hello,$name"

3.建立镜像,运行容器
在这里插入图片描述

[root@server1 docker]# docker run --rm busybox:v1  #运行容器后删除
hello,world

4.在这里有必要说明一个问题,我们刚才在输出的时候用到的是echo,他其实是shell格式的一种,当然我们还可以使用exec格式的输出,shell格式底层会调用/bin/sh -c 来执行命令,可以解析变量,而exec时不可以解析变量的

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo","hello,$name"]

在这里插入图片描述
那么如果我们一定要使用exec的格式呢,我们可以这样

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh","-c","echo hello,$name"]

在这里插入图片描述
5.使用ENTRYPOINT和CMD

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]

在这里插入图片描述
当然,我们cmd的内容还可以被覆盖的
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42446031/article/details/90756718