安装docker
配置docker-ce软件仓库
此时yum install -y docker-ce会报错提示需要安装相关依赖包
配置所需依赖包的软件仓库
安装完成并启用docker
docker版本查看及告警解决
查看docker版本
使用docker info查看docker的系统范围信息时出现告警
解决方法
再次执行docker info后可以看到告警解除
docker容器简单运用
在官方公共仓库Docker Hub中搜索镜像
拉取镜像
运行容器
##第一个80:容器宿主机的端口;第二个80:容器的映射端口
此时浏览器访问宿主机的效果为:
删除运行中的容器
先终止容器之后删除容器
容器的端口映射
将容器宿主机的8080端口映射至容器的8080端口
浏览器访问:
docker镜像的分层结构
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、环境变量和配置文件
Docker镜像是由文件系统叠加而成;最底端是一个引导文件系统(bootfs),这很像典型的Linu/Unix的引导文件系统;Docker用户几乎永远不会和引导文件系统有什么交互,实际上,当一个容器启动后,它将会被移到内存中,而引导文件系统则会被卸载(umount),以留出更多的内存供initrd磁盘镜像使用
到目前为止,Docker看起来还很像一个典型的Linux虚拟化栈;实际上,Docker镜像的第二层是root文件系统(rootfs),它位于引导文件系统之上;rootfs可以是一种或多种操作系统(如Debian或者Ubuntu文件系统)
在传统的Linux引导过程中,root文件系统会最先以只读的方式加载,当引导结束并完成了完整性检查之后,它才会被切换为读写模式;但是在Docker里,root文件系统永远只能是只读状态,并且Docker利用联合加载(union mount)技术又会在root文件系统层加载更多的只读文件系统;联合加载指的是一次同时加载多个文件系统,但是在外面看起来只能看到一个文件系统,联合加载会将各层文件系统叠加到一起,这样最终的文件系统会包含所有底层的文件和目录
Docker将这样的文件系统称为镜像,一个镜像可以放到另一个镜像的顶部,位于下面的镜像称为父镜像(parent image),可以依次类推,直到镜像栈的最底部,最底部的镜像称为基础镜像(base image);最后,当从一个镜像启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统,我们想在Docker中运行的程序就是在这个读写层中执行的
当Docker第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层上;比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层,该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏
通常这种机制被称为写时复制(copy on wrte),这也是使Docker如此强大的技术之一;每个只读镜像层都是只读的,并且以后永远不会变化,当创建一个新容器时,Docker会构建出一个镜像栈,并在栈的最顶端添加一个读写层,这个读写层再加上其下面的镜像层以及一些配置数据,就构成了一个容器;容器是可以修改的,它们都有自己的状态,并且是可以启动和停止的;容器的这种特点加上镜像分层框架(image-layering famework),使我们可以快速构建镜像并运行包含我们自己的应用程序和服务的容器
导入本地base镜像并查看其历史
使用base镜像运行容器后可以发现容器共享了宿主机的kernel、dns
base镜像提供的是最小的Linux发行版;同一docker主机支持运行多种Linux发行版本;采用分层结构的最大好处是共享资源
docker构建镜像
1、使用busybox构建基础镜像
busybox是一个集成了一百多个最常用linux命令和工具的软件,它甚至还集成了一个http服务器和一个telnet服务器,而所有这一切功能却只有区区1M左右的大小;我们平时用的那些linux命令就好比是分立式的电子元件,而busybox就好比是一个集成电路,把常用的工具和命令集成压缩在一个可执行文件里,功能基本不变,而大小却小很多倍;在嵌入式linux应用中,busybox有非常广的应用,另外,大多数linux发行版的安装程序中都有busybox的身影,安装linux的时候同时按下ctrl+alt+F2就能得到一个控制台,而这个控制台中的所有命令都是指向busybox的链接;busybox的小身材大作用的特性,给制作一张软盘的linux带来了极大便利
拉取busybox镜像,查看所有本地镜像
docker commit方式构建新镜像三部曲:运行容器--->修改容器--->将容器保存为新的镜像
使用新镜像运行容器
镜像的删除
2、Dokerfile构建镜像
创建存放Dockerfile的目录并编写Dockerdile内容
docker build方式构建镜像,测试使用此镜像运行容器
docker commit与docker build两种方式构建镜像的对比
##commit方式所构镜像
##build方式所构镜像
由上可见docker commit方式构建镜像的弊端有:
使用docker commit意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像;换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知;而且,即使是这个制作镜像的人,过一段时间后也无法记清具体的操作步骤,虽然或许可以从docker diff得到一些线索,但是远远不到可以确保生成一致镜像的地步,且这种黑箱镜像的后期维护工作是非常痛苦的
此外,镜像所使用的分层存储中,除当前层之外的每一层都是不会发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添加、修改,而不会改动上一层;如果使用docker commit制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到,这会让镜像变得臃肿
docker build方式构建镜像的优点:
能够自由灵活的与宿主机联系,比如,某些配置文件在宿主机验证并使用过后很好用,那么,可以将文件copy到镜像中,add远程主机的配置文件到镜像中,定义onbuild动作等等各种灵活的功能;docker commit不能做到这些事情,因为是在一个封闭的在运行中的容器中,无法做复制宿主机文件;dockerfile本身就是一个比较详细的构建文档,有这个文档就可以清楚的知道新构建的镜像经历了怎样的变化,没有黑箱操作的困扰了,后期的维护更为方便
而docker build的每一步构建出来的镜像就是通过docker commit得来的
3、镜像的缓存特性
在构建映像的过程中,docker将按照指定的顺序逐步执行Dockerfile中的指令,随着每条指令的检查,docker将在其缓存中查找可重用的现有映像,而不是创建一个新的(重复)映像,如果用户不想使用缓存,可以在docker build命令中使用--no-cache = true选项
docker将遵循的基本规则如下:
从已经在缓存中的父镜像开始,将下一个指令与从该基本镜像导出的所有子镜像进行比较,以查看其中一个是否使用完全相同的指令构建,如果没有,则缓存无效
在大多数情况下,只需将Dockerfile中的指令与其中一个子镜像进行比较即可(通过比较是否与上一次执行的指令一致);但是,某些指令需要一些额外的检查,对于ADD和COPY指令,将检查镜像中文件的内容,并为每个文件计算校验和,在这些校验和中不考虑文件的最后修改和最后访问的时间;在缓存查找期间,将校验和与现有映像中的校验和进行比较,如果文件(如内容和元数据)中有任何变化,则缓存无效
除了ADD和COPY命令之外,缓存检查将不会查看容器中的文件来确定缓存匹配,例如,当处理RUN yum install -y gcc命令时,不会检查在容器中更新的文件以确定是否存在高速缓存命中,它将只会检查命令字符串是否与之前的一致来判断是否匹配
一旦某一层的缓存无效,所有后续的Dockerfile命令将生成新的镜像,并且高速缓存将不被使用
##可以看到在构建test:lv2镜像时的第2、3步使用了test:lv1镜像的缓存,镜像ID能够一一对应
4、Dockerfile详解
Dockerfile常用指令:
FROM:指定base镜像,如果本地不存在会从远程仓库下载
MAINTAINER:设置镜像的作者,比如用户邮箱等
COPY:把文件从镜像构建环境(构建镜像时的当前路径)复制到镜像,支持两种形式:COPY src dest 和 COPY ["src", "dest"] ;src必须指定镜像构建环境中的文件或目录
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,如果指定了多个,只有最后一个生效
Dockerfile的简单应用:
##编写Dockerfile内容
##构建新镜像
##查看镜像及其分层结构,此时因为镜像层级增加,镜像大小也跟着增加
##在容器中向应用数据挂载点中导入数据
##在容器运行状态下新开shell查看容器中数据在宿主机中的路径
##在容器运行宿主机删除挂载数据
##容器中的数据被删除
Dockerfile的shell和exec书写格式:
##shell格式书写
##shell格式底层会调用/bin/sh -c来执行命令,可以解析变量