Docker镜像的分层结构介绍:
(1)docker镜像:
Docker镜像是一个只读的Docker容器模板,含有启动Docker容器所需的文件系统结构及其内容,因此是启动一个Docker容器的基础。Docker镜像的文件内容以及一些运行Docker容器的配置文件组成了Docker容器的静态文件系统运行环境–rootfs。可以这么理解,Docker镜像是Docker容器的静态视角,Docker容器是Docker镜像的运行状态
Docker commit镜像的创建:
创建容器,以ubuntu为例
(1)导入镜像,创建容器并运行
[root@server1 ~]# docker load -i ubuntu.tar ##添加镜像
[root@server1 ~]# docker images ##查看拉取的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 ~]# docker run -it --name vm2 ubuntu ##创建并运行容器 -it:以交互式方式打开
root@a4aca5fcecc3:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@a4aca5fcecc3:/# uname -r
3.10.0-862.el7.x86_64 ##与宿主机内核版本一致
root@a4aca5fcecc3:/#
root@a4aca5fcecc3:/# touch file{1…10}
root@a4aca5fcecc3:/# 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
root@a4aca5fcecc3:/# exit
exit
[root@server1 ~]# docker rm vm2 ##删除此容器,此时容器内创建的文件均没有保存
删除容器vm2,重新用ubuntu镜像创建并运行容器时,之前创建的文件消失,因为上次的操作全部写在容器层,镜像层的内容只读。当上次的容器释放之后,写在容器层的内容也会随之消失。
可以看到重新run后之前创建的file都没有了
使用docker commit保存修改后的镜像为新镜像
[root@server1 ~]# docker commit vm2 ubuntu:v ##将此容器重新打包为一个镜像
sha256:593a662c6eedf8afc483f305ff9369ee9c8bddd8c71fca0718178d2895d1ea0d
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v 593a662c6eed 14 seconds ago 188MB
[root@server1 ~]# docker rm vm2 ##删除创建的容器
vm2
[root@server1 ~]# docker run -it --name vm2 ubuntu:v ##运行此容器
root@306c2ef91b50:/# 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
root@306c2ef91b50:/# exit
exit
使用容器创建镜像。容器就是在镜像层的最上方存在一个可写的容器层。将容器打包镜像,就是将该可写的容器层,变成一个只读的镜像层,和下层的所有镜像层一起作为新镜像的镜像层。
查看v镜像的构造历史:
[root@server1 ~]# docker history ubuntu:v
IMAGE CREATED CREATED BY SIZE COMMENT
843b731970bb 2 minutes ago /bin/bash 43B
07c86167cdc4 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
3 years ago /bin/sh -c sed -i 's/^#\s*(deb.*universe)$… 1.9kB
3 years ago /bin/sh -c echo ‘#!/bin/sh’ > /usr/sbin/poli… 195kB
3 years ago /bin/sh -c #(nop) ADD file:b9504126dc5590898… 188MB
可以看出用cmmit方法,docker history不能看到具体的操作,这样对于使用来说很不安全
Dockerfile实现镜像的封装
简单镜像的构建
mkdir docker
cd docker/
vim Dockerfile #创建一个Dockerfile
FROM ubuntu
RUN touch file{1…10}
docker build -t ubuntu:v1 . #构建镜像
docker history ubuntu:v1 #查看镜像的分层结构
在镜像构建时,由于构建镜像会拉取该目录下的所有数据,所以不要直接在根目录下进行构建
Dockerfile中常用命令
(1)FROM:指定base镜像,如果本地不存在会从远程仓库下载
(2)MAINTAINER:设置镜像的作者,比如用户邮箱等
(3)COPY:把文件从build context复制到镜像,支持两种形式:COPY src dest 和 COPY [“src”, “dest”],src必须指定build context中的文件或目录
(4)ADD:用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像
(5)ENV:设置环境变量,变量可以被后续的指令使用
(6)EXPOSE:如果容器中运行应用服务,可以把服务端口暴露出去
(7)VOLUME:申明数据卷,通常指定的是应用的数据挂在点
(8)WORKDIR:为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
(9)RUN:在容器中运行命令并创建新的镜像层,常用于安装软件包
(10)CMD 与 ENTRYPOINT:这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。 docker run后面的参数可以传递给ENTRYPOINT指令当作参数。 Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
使得虚拟机可以连网
真机上:iptables -t nat -I POSTROUTING -s 172.25.0.0/24 -j MASQUERADE
run一个镜像,如果本地没有就会从网络拉取
docker ps -a可以查看当前所有的容器的状态
用ctrl+pq退出之后可以直接 docker attach vm1重新进入容器
用ctrl+d退出容器之后,必须先执行docker start vm1 然后再执行docker attach vm1才可以进入容器
编写Dockerfile构建镜像