一、Docker镜像简介
1.1 关于Dockers镜像
镜像是可执行的独立软件包,打包程序代码和软件运行环境。包括代码、运行时库、环境变量和配置文件等
Docker使用的联合文件系统UnionFS是分层、轻量级并且高性能的文件系统,对文件的修改作为一次提交来一层层的叠加,可以将不同将不同目录挂载到同一个虚拟文件系统下。
联合加载会把各层文件系统叠加起来,最终的文件系统会包含所有底层的文件和目录。
1.2 Docker镜像结构
bootfs:最底层为bootfs,包括bootloader和kernel,bootloader主要是引导加载kernel,容器启动完成后会被卸载以节约内存资源
rootfs:表现为docker容器的根文件系统,包括/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版本,如CentOS。rootfs由内核挂载为只读模式。
1.3 Docker镜像分层
最底层镜像称为基础镜像(base image),例如一个最小化的CentOS。镜像分层后,可以实现共享base镜像。
相对的,位于下层的镜像称为父镜像(parent image), 最上层为可读写层(writable),其它下层均为只读层
工作流程:先从最底层镜像开始挂载,然后逐步挂载上层镜像。当删除Docker某一层,那其上层镜像会同时被删除
举例:一个Docker从下往上镜像依次为:bootfs(kernal)—Debian(base image)—emacs(parent image)—apache—writable
#例如nginx镜像,包括kernel、debian:buster-slim、和nginx应用3层
[root@efly ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f949e7d76d63 2 weeks ago 126MB
[root@efly ~]# docker inspect nginx 略 "RootFS": { "Type": "layers", "Layers": [ "sha256:c3a984abe8a88059915bb6c7a1d249fd1ccc16d931334ac8816540b0eb686b45", "sha256:99134ec7f247e5a211c7205fec587bf72a6d4aac339b21858b892e9c04f78920", "sha256:d37eecb5b7691ec21bd19989e37f8bb4d20b340a775591d0f3db5897d606b0e4" ] }
1.4 容器数据卷
容器数据卷作用:
对容器运行产生的日志、数据等进行持久化
容器之间实现数据继承、共享。
实现host宿主机与容器之间的数据共享
容器数据卷特点:
卷是目录或文件,不属于联全文件系统的一部分,独立于容器的生存周期
停止容器后,对数据卷进行更改,重新运行容器后会看到更改后的数据
删除容器时不会删除数据卷
二、制作docker镜像
2.1 使用docker commit制作镜像
docker commit提交基于当前运行容器副本,生成新的镜像。
-a:作者
-m:提交信息
#对当前容器进行修改,过程略
docker exec -it 700bfd08ae4e /bin/bash
#修改后,基于当前容器生成新的镜像
root@ubuntu:~# docker commit -a 'efly' -m 'my tomcat' 700bfd08ae4e zlj/mytomcat:1.0
sha256:625b426f4fac1e93cde874c5c5af5baa740526881828b1e86c041c2f2d012fb7
root@ubuntu:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
efly/mytomcat 1.0 625b426f4fac 21 seconds ago 555MB
#生成新镜像运行 docker run -it -p 8888:8080 efly/mytomcat:1.0
2.2 使用Dockerfile制作镜像
Dockerfile 是一个包含创建镜像所有命令的文本文件,通过docker build命令可以根据 Dockerfile 的内容构建镜像。Dockerfile中的COPY、ADD和RUN语句会向镜像中添加新层
Dockerfile命令
FROM:继承哪个基础镜像
EXPOSE:使用哪个端口RUN:执行命令
CMD:执行命令
#编写Dockerfile
root@ubuntu:~# cat Dockerfile
#默认带数据卷的镜像
FROM ubuntu
VOLUME ["/mydata"]
CMD echo "i have data volume"
CMD /bin/bash
#生成镜像 docker build -f Dockerfile -t efly/myubuntu:1.0 .
启动后默认加载数据卷,对应宿主机的下面目录
docker run -it efly/myubuntu:1.0
root@fcf132a5b355:/# ls -d /mydata/
/mydata/
root@ubuntu:~# docker inspect fcf132a5b355 | grep -C 5 mydata
"Mounts": [
{
"Type": "volume",
"Name": "5c1912aaef0f2b3f366a0518a481d4851cea4d42cde00826cd7a0abef3865d7e",
"Source": "/var/lib/docker/volumes/5c1912aaef0f2b3f366a0518a481d4851cea4d42cde00826cd7a0abef3865d7e/_data",
"Destination": "/mydata",
(略)
}
2.3 数据卷在宿主机与容器之间共享
举例:实现host宿主机与容器之间的数据共享
#本地host宿主机/docker_data目录作为数据卷,挂载到容器中的/data。若目录不存在,则会自动创建
docker run -it -v /docker_data:/data ubuntu
#ro表示只读,例如/docker_data:/data:ro
root@ubuntu:~# docker inspect d030eb6272ed | grep -C 5 data "Mounts": [ #挂载内容 { "Type": "bind", "Source": "/docker_data", "Destination": "/data", "Mode": "", #默认可读写 "RW": true, "Propagation": "rprivate" } ],
#实现了宿主机与容器之间的数据共享 #宿主机上操作 root@ubuntu:# echo abc > /docker_data/abc.txt root@ubuntu:# cat /docker_data/def.txt def #容器内操作 root@ed0bdf6b4c1d:/# cat /data/abc.txt abc root@ed0bdf6b4c1d:/# echo def > /data/def.txt
2.4 数据卷在容器之间共享
举例:通过数据卷在多个容器之间共享,实现多个容器之间数据共享
#新建子容器,共享容器fcf132a5b355的数据卷
docker run -it --volumes-from fcf132a5b355 zlj/myubuntu:1.0
root@7bb4628240f6:/# cat /mydata/abc.txt
abc
#删除容器fcf132a5b355,子容器的数据卷还在;删除子容器,数据卷还在 root@ubuntu:# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@ubuntu:# ll /var/lib/docker/volumes/5c1912aaef0f2b3f366a0518a481d4851cea4d42cde00826cd7a0abef3865d7e/_data total 16 -rw-r--r-- 1 root root 4 Dec 8 17:26 abc.txt -rw-r--r-- 1 root root 4 Dec 8 20:25 def.txt