不了解Docker的可以先看看这篇文章:【云原生】Docker快速入门实操
镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。
镜像:可以理解为软件安装包,可以方便的进行传播和安装。
容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。
Docker镜像层都是只读的,容器层是可写的 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。镜像分层最大的一个好处就是共享资源,方便复制迁移,便于复用。
在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M?
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
1.在当前容器做出一些改变,例如在docker内执行:(官网是默认下载的Ubuntu没有vim命令,我们自己新增加了vim功能,commit构建镜像后,可以成功使用。
)
2.在docker外使用docker commit提交容器副本使之成为一个新的镜像,具体命令:docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:版本号
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
每条保留字指令都必须为大写字母且后面要跟随至少一个参数;指令按照从上到下,顺序执行;#表示注释;每条指令都会创建一个新的镜像层并对镜像进行提交。
构建步骤:
1.编写Dockerfile文件(建一个文件夹,执行vim Dockerfile)
2.docker build命令构建镜像(docker build -t 新镜像名字:TAG .)
3.docker run依镜像运行容器实例(docker run -it 新镜像名字:TAG)
Docker执行Dockerfile的大致流程:
(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
命令 | 解释 |
---|---|
FROM | 基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FROM |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 容器构建时需要运行的命令,1.shell格式,等同于在终端操作的shell命令RUN yum -y install vim;2.exec格式,RUN [“./test.php”, “dev”, “offline”],等同于RUN ./test.php dev offline。RUN是在 docker build时运行的。 |
EXPOSE | 当前容器对外暴露出的端口 |
WORKDIR | 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 |
USER | 指定该镜像以什么样的用户去执行,如果都不指定,默认是root |
ENV | 用来在构建镜像过程中设置环境变量,ENV MY_PATH /usr/mytest,然后可以WORKDIR $MY_PATH |
ADD | 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 |
COPY | 类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定容器启动后的要干的事情,和RUN相似也是两种格式。Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,docker run的时候CMD中的首个参数会被 docker run 之后的参数替换。CMD是在docker run 时运行;RUN是在 docker build时运行。 |
ENTRYPOINT | 用来指定一个容器启动时要运行的命令,类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。 |
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
容器和宿主机之间数据共享
1 docker修改,主机同步获得
2 主机修改,docker同步获得
3 docker容器stop,主机修改,docker容器重启数据同步。
运行一个带有容器卷存储功能的容器实例:
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。