一、概述
1.docker是什么?
docker是一种容器式的虚拟化技术。
优点:相比与虚拟化来说,省去了HyperVisor层,部署更加快,且让你可以部署更多的容器。
个人理解:它就像是一个简化版的虚拟机(Docker 属于 Linux 容器的一种封装),舍去了虚拟机的硬件及不需要的软件。
2.docker解决了什么问题?
软件开发最大的麻烦事之一,就是环境配置。
以前开发人员把写好的jar包、war包交给运维,然后运维放到服务器并下载相关的组件,比如redis、mysql等,但是这些组件可能并不是jar包需要的版本会出现各种问题,也有可能做集群的时候要安装几十台机器。
而Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
二、docker三要素
docker架构图:
1.image(镜像)
镜像就是一个只读的模板,用来创建容器(一个镜像可以创建多个容器)。
Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。
2.container(容器)
容器是由镜像创建的运行实例。
每个容器相互隔离,保证安全的平台。
3.repository(仓库)
仓库是集中存放镜像文件的场所。
仓库分为公开仓库和私有仓库。最大的公开仓库是Docker Hub。国内公开仓库有:阿里云、网易云。
4.总结
我们把应用程序和配置打包好生成一个运行环境,这个运行环境就是镜像。可以把镜像看成一个模板,而它生成的实例就是docker容器。一个模板可以生成多个容器。
image文件生成的容器实例,本身也是一个文件,称为镜像文件。
仓库就是放置一堆镜像的地方,我们可以把自己的镜像存放到仓库中,而在使用的时候可以从本地从仓库中下载所需要的镜像。
三、docker安装及配置阿里云镜像
docker安装及配置阿里云镜像
运行docker:systemctl start docker
运行测试:docker run hello-world
四、底层原理
docker为什么这么快?
docker与虚拟机的对比:
五、docker常用命令
1.帮助命令
docker --help
2.镜像命令
(1)docker images 列出本地主机上的镜像
OPTIONS说明 | - |
---|---|
-a | 列出本机所有镜像(含中间镜像层) |
-q | 只显示镜像ID |
–digests | 显示摘要信息 |
–no-trunc | 显示完整镜像信息 |
(2)docker search 镜像名字 去hub docker上查找该镜像
OPTIONS说明 | - |
---|---|
-s 数量 | 列出收藏数不小于该数量的镜像 |
–automated | 只列出automated build类型的镜像 |
–no-trunc | 显示完整镜像信息 |
(3)docker pull 镜像名字[:TAG] 去hub docker上下载该镜像(如果设置阿里云的话,会去阿里云下载)
如果是docker pull 镜像名字 省略后面的版本号的话 会默认下载最新版本
(4)docker rmi 镜像名字|镜像ID 删除该镜像
删除单个:docker rmi 镜像名字|镜像ID
删除多个:docker rmi 镜像名字|镜像ID 镜像名字|镜像ID (多个镜像名用空格分割)
删除所有:docker rmi $(docker images -aq)
OPTIONS说明 | - |
---|---|
-f | 强制删除 |
3.容器命令
(1)docker run [OPTIONS] IMAGE [COMMAND] [arg] 新建并启动容器
OPTIONS说明 | - |
---|---|
–name 容器别名 | 为容器指定名称 |
-d | 后台运行容器,并返回容器ID。即启动守护式容器 |
-i | 以交互模式启动容器,通常与-t一起使用 |
-t | 为容器重新分配一个伪输入终端,通常与-i一起使用 |
-P | 随机端口映射 |
-p | 指定端口映射,有以下四种格式: ip:hostPort:containerPort ip::containerPort hostPort:containerPort containerPort |
(2)docker ps 列出当前所有正在运行的容器
OPTIONS说明 | - |
---|---|
-a | 列出所有正在运行的容器+历史上运行过的 |
-l | 显示最近创建的容器 |
-n 数字 | 显示最近创建的指定数量的容器 |
-q | 静默模式,只显示容器编号 |
–no-trunc | 不截断输出 |
(3)退出容器的两种方式:
exit :容器停止退出
ctrl+P+Q:容器不停止退出
(4)docker start 容器ID|容器名称 启动容器
(5)docker restart 容器ID|容器名称 重启容器
(6)docker stop 容器ID|容器名称 停止容器
(7)docker kill 容器ID|容器名称 强制关闭容器
(8)docker rm 容器ID|容器名称 删除已停止的容器(删除缓存记录)
组合命令:删除多个容器:
docker rm $(docker ps -qa)
docker ps -qa | xargs docker rm
4.容器命令-重要部分
(1)启动守护式容器: docker run -d 容器名
(2)查看容器日志: docker logs -ft --tail 容器ID
OPTIONS说明 | - |
---|---|
-t | 加入时间戳 |
-f | 跟随最新的日志打印 |
–tail 数字 | 显示最后多少条 |
例子:后台运行centos并每2秒打印一句话,然后查看日志
docker run -d centos /bin/sh -c “while true;do echo hello;sleep 2;done”
docker logs -tf --tail 3 xxxxx
(3)查看容器内进程: docker top 容器ID
(4)查看容器内部细节: docker inspect 容器ID
(5)进入正在运行的容器并以命令行交互:
docker exec -it 容器ID bashShell(是在容器中打开新的终端,并可以启动新的进程)
重新进入 docker attach 容器ID(直接进入容器启动命令的终端,不会启动新的进程)
例子:
docker exec -it 0e5842faa39c /bin/bash
docker exec -it 0e5842faa39c ls -l /tmp
exec也不用进入容器就可以直接返回容器结果,而attach只能先进入容器
(6)从容器内拷贝文件到主机上: docker cp 容器ID:容器内路径 目的主机路径
5.docker常用命令总结
六、镜像原理
1.镜像是什么
(1)UnionFS(联合文件系统)
(2)docker镜像加载原理
(3)分层的镜像
以tomcat为例:
(4)为什么docker镜像要采取分层结构
2.镜像特点
docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
3.镜像commit操作补充
(1)docker commit 提交容器副本使之成为一个新的镜像
docker commit -m “提交描述信息” -a “作者” 容器ID 要创建的目标镜像名:[标签名]
(2)例子:
从hub上下载tomcat镜像,并成功运行 docker run -it -p 8888:8080 tomcat
进入容器,删除docs文件
生成新的镜像:docker commit -m “提交描述信息” -a “作者” 容器ID 要创建的目标镜像名:[标签名]
运行新生成的镜像,发现访问不了docs
七、容器数据卷
1.容器数据卷是什么
我们需要把容器运行的数据持久化,希望容器之间可以共享数据。
Docker容器产生的数据,如果不通过commit生成新的镜像,使数据作为镜像的一部分保存下来,那么当容器删除后,数据就没有了
为了能保存数据在docker中,我们使用卷
2.容器数据卷能干什么
(1)容器的持久化
(2)容器间继承+共享数据
3.数据卷-容器内添加
(1)直接命令添加
docker run -it -v /宿主机绝对路径:/容器内路径 镜像名
宿主机目录与容器内目录共享,就算关闭容器,再启动容器时也会共享
docker run -it -v /宿主机绝对路径:/容器内路径 镜像名:ro (只读)
共享,但宿主机可以修改文件,而容器不可以修改。简单说就算容器只能读取到宿主机共享的目录,而不能操作。
举例:
docker run -it -v /root/docker_centos:/root/docker_centos_container centos
发现两个目录中文件共享
关闭容器,在宿主机共享目录上添加文件
重启容器,发现容器中共享目录上也存在该文件
(2)DockerFile添加
创建dockerFile:vim Dockerfile
内容如下:
#volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo “finished----------success”
CMD /bin/bash
使用build创建镜像文件:
docker build -f Dockerfile -t syr/centos .
生成新的镜像后,运行,发现有两个数据卷
最后可以使用docker inspect命令查看相关联的宿主机目录。
4.数据卷容器
(1)是什么?
命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
(2)作用
容器之间数据共享
(3)例子:
运行一个容器:docker run -it --name doc01 syr/centos
以doc01为父容器运行doc02:docker run -it --name doc02 --volumes-from doc1 syr/centos
以doc01为父容器运行doc03
发现他们数据共享,而且删除任意一个,还是共享。
(4)结论:
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
八、DockerFile
1、是什么
(1)DockerFile是用来构建docker镜像的构建文件,是由一系列命令和参数组成的脚本。
(2)构建镜像步骤:dockerFile、docker build
(3)官网 hud.docker.com 查看centos的dockerFile
2、DockerFile构建过程解析
(1)DockerFile内容基础知识
每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
指令从上到下顺序执行
#表示注释
每条指令都会创建一个新的镜像层,并对镜像进行提交
(2)Docker执行DockerFile的大致流程
(3)总结
3、DockerFile体系结构(保留字指令)
(1)FROM:指定基础镜像,必须为第一个命令
格式:
FROM
FROM :
FROM @
示例:
FROM mysql:5.6
注:
tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
(2)MAINTAINER: 维护者信息
格式:
MAINTAINER
示例:
MAINTAINER Jasper Xu
MAINTAINER sorex@163.com
MAINTAINER Jasper Xu sorex@163.com
(3)RUN:构建镜像时执行的命令
RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
格式:
RUN
exec执行
格式:
RUN [“executable”, “param1”, “param2”]
示例:
RUN [“executable”, “param1”, “param2”]
RUN apk update
RUN ["/etc/execfile", “arg1”, “arg1”]
注:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定–no-cache参数,如:docker build --no-cache
(4)EXPOSE:指定于外界交互的端口
格式:
EXPOSE […]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注:
EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
(5)WORKDIR:工作目录,类似于cd命令
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)
注:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
(6)ENV:设置环境变量
格式:
ENV #之后的所有内容均会被视为其的组成部分,因此,一次只能设置一个变量
ENV = … #可以设置多个变量,每个变量为一个"=“的键值对,如果中包含空格,可以使用\来进行转义,也可以通过”"来进行标示;另外,反斜线也可以用于续行
示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
(7)ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
格式:
ADD …
ADD ["",… “”] 用于支持包含空格的路径
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:“home.txt”
ADD test relativeDir/ # 添加 “test” 到 WORKDIR
/relativeDir/
ADD test /absoluteDir/ # 添加 “test” 到 /absoluteDir/
(8)COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
(9)VOLUME:用于指定持久化目录
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", “/var/log/apache2”, “/etc/apache2”
注:
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它
(10)CMD:构建容器后调用,也就是在容器启动时才进行调用。
格式:
CMD [“executable”,“param1”,“param2”] (执行可执行文件,优先)
CMD [“param1”,“param2”] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD echo “This is a test.” | wc -
CMD ["/usr/bin/wc","–help"]
注:
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
(11)ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。
格式:
ENTRYPOINT [“executable”, “param1”, “param2”] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
FROM ubuntu
ENTRYPOINT [“top”, “-b”]
CMD ["-c"]
注:
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。
(12)ONBUILD:用于设置镜像触发器
格式:
ONBUILD [INSTRUCTION]
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
(13)总结
4、案例
生产自己的tomcat9
在docker运行命令中,可以生成一个或多个数据卷,以后发布程序的时候,就可以直接放到主机数据卷,等它同步到容器数据卷的时候就可以访问了,并且可以做日志相关的数据卷。