通识

○ 容器与虚拟机的区别
(1)虚拟机在 Hypervisior 之上虚拟出一套完整操作系统,提供的资源通常超过大部分应用所需。
(2)容器在 Docker Engine 之上仅虚拟出一个应用程序运行所需的基础操作系统环境,这个环境以独立原生进程的方式运行在 Linux,有自己隔离的运行环境,但又与其他进程和容器共享主机内核,除了运行应用程序之外基本不消耗额外的系统资源,比虚拟机方式更轻量。

○ Docker CE,即 Docker Community Edition,用于开发人员和小团队熟悉 Docker 和试验基于容器的 app。
○Docker EE,即 Docker Enterprise Edition,面向企业级关键应用。
○EE 是 CE 的超集,代码仓库层面,CE 位于 EE 的上游,CE 在发布后提供 7 个月支持,EE 提供 24 个月。
○ 三种类型的 release 包:stable(稳定版,版本号如 stable-18.09)、test(稳定版发布前的测试版,版本号如 test-18.09)、nightly(又名 edge 版,是当前最新版,版本号如 0.0.0-20180720214833-f61e0f7),每次稳定版同时发布 CE 和 EE。
○Docker 是个用于通过容器技术开发、部署和运行应用的平台,Linux 中的容器是之前已有的概念,使用容器部署应用是新的东西,使用 Linux 的容器部署应用称为“容器化”。
○ 容器化优点:
(1)容器是互相隔离的进程,直接运行在 Linux 之上,并不比普通进程占用更多内存,是轻量的,多个容器可共享主机资源。
(2)支持热更新部署。
(3)根据需要灵活增减容器的数量。
○ 镜像(image)是包含运行一个应用的所有必需内容(包括库、环境、配置文件)的 package。
○ 镜像通过 Dockerfile 来定义。
○ 容器(container)是镜像的运行实例,通过命令“docker ps”查看正在运行的容器。
○Docker 模式运行的应用在架构上自底向上包含三层:Swarm(非必须)、Container、Services、Stack
(1)运行 Docker 应用的主机集群(cluster)称为“swarm”,通过在机器上运行 Docker 并(可以是物理机或虚拟机)加入 swarm,一个 docker 应用可部署在 swarm 集群上,运行于多台机器。swarm 中的一台机器称为一个节点(node)。
(2)swarm 集群中有一台机器作为 swarm manager,在 swarm manager 执行运行于 swarm 上的 docker 命令或授权其他机器作为 worker 加入当前 swarm。
(3)container 是一个运行的 image。
(4)分布式应用的不同组成部分称为 service,Docker 模式下,每个 service 包含运行自同一个 image 的一个或多个 container,service 同时定义了如何编排这些 container 以实现 service 的整体行为表现,service 内每个 container 称为 task。
(5)stack 用于定义多个 service 的行为。
(6)service 通过 compose 文件编排 container 的行为,而同一个 compose 文件中可以配置多个 service,这几个 service 组成一个 stack,这个 compose 文件也就成了编排 stack 行为的文件。
○ 一个 Docker 应用运行所需环境无须安装到宿主系统,只需要引入所需环境的镜像。
○repository 和 registry
(1)repository:是镜像的集合,类似项目代码已经被编译好的 GitHub 项目。
(2)registry:是 repository 的集合。registry 上的每个账号可以创建多个 repository,docker 命令行默认使用 public registry
(3)DTR(Docker Trusted Registry):是支持安装在防火墙之后的企业级 registry,可以作为持续集成的一部分,提供 web 访问的方式管理镜像。

Dockerfile

●Dockfile 是一种被 Docker 程序解释的脚本,Dockerfile 由一条一条的指令组成,每条指令对应 Linux 下面的一条命令。
●Dockerfile 有自己书写格式和支持的命令,Docker 程序解决这些命令间的依赖关系,类似于 Makefile,根据指令生成定制的 image。
● 指令忽略大小写,建议使用大写。每一行只支持一条指令,每条指令可以携带多个参数。
● 指令分为两种:构建指令和设置指令。
构建指令用于构建镜像,其指定的操作不会在容器上执行。
(1)ADD 与 COPY 用于把文件拷贝到容器,区别是:ADD 指令包含类似 tar 的解压功能,而 COPY 只是单纯复制文件。
设置指令用于设置 image 的属性,其指定的操作将在容器上执行。
● 实例:

1
2
3
4
5
6
7
8
# FROM 指令用于指定基础镜像
FROM nginx:latest
# LABEL 指令为构建的镜像设置作者信息
LABEL maintainer "Congzhou"
VOLUME ["/home/docker_congzhou/my_project/agt_jinzhong/nginx_conf","/etc/nginx/conf.d"]
VOLUME ["/home/docker_congzhou/my_project/agt_jinzhong/nginx_file/","/usr/share/nginx/html"]
# EXPOSE 指令声明运行时容器提供的服务端口。
EXPOSE 80

Volume

○Docker 的文件系统称为 Union File System(联合文件系统),自底向上包括只读层和读写层,当在运行中的容器修改一个文件时,会将文件从只读层复制读写层,只读层的文件仍然存在且是未修改状态。
○ 默认情况下容器内的数据只存在于容器的生命周期内,随着容器的删除而删除。
○Volume 的目的是为了能够保存(持久化)数据以及共享容器间的数据,从而删除容器时不会自动删除容器对应的 volume 数据。
○Volume 是绕过默认联合文件系统的目录或者文件,以正常的文件或者目录的形式存在于宿主机上,宿主机和容器访问的是同一个文件夹,宿主或容器内做的修改也将在对面生效。
○ 设置 Volume 有两种方式:(1)运行时使用”-v”参数(2)在 Dockerfile 中通过使用 VOLUME 指令。
○ 运行时使用-v 参数
(1)将 docker 某目录挂载到宿主机,例:

1
2
3
docker run -p 80:80 -v /data nginx:latest   #将容器的"/data"目录挂载到宿主机某目录(具体目录由docker分配)
#具体宿主机目录使用如下命令查看,输出结果中的Mounts->Source和Mounts->Destination列举了目录映射关系
docker inspect containerName
#可见其中将容器的“/data”目录挂载代理宿主机“/var/lib/docker/volumes/4e..../_data”目录

(2)将 docker 某目录挂载到宿主机的指定某目录,例:

1
docker run -p 80:80 -v /home/docker_data:/data nginx:latest   #将宿主机的"/home/docker_data"目录挂载到docker的"/data"目录

○Dockerfile 中使用 VOLUME 指令,示例如下,此方式不支持将 docker 目录挂载到宿主机的指定目录。这种方式不推荐,容易启动 image 时忘记添加”-rm”参数导致 container 退出后在宿主机上对应的 volume 目录未做销毁处理,进而随着多次启动产生大量垃圾文件。

1
2
FROM nginx:latest
VOLUME /data

○ 查看所有的 volume: docker volume ls
○ 批量删除孤单 volume: docker volume rm $(docker volume ls -qf dangling=true)
○ 常见的使用场景是使用纯数据容器(data container)来持久化数据库、配置文件或者数据文件等
(1)创建数据容器,例:docker create -v /data –name data_container ubuntu ,从 ubuntu(用与应用数据的容器相同的 image)创建名为 data 的数据容器,将宿主机的某目录(具体目录由 docker 分配)挂载在到容器中的/data 目录。
(2)通过 docker run 的“–volumes-from”参数使用数据容器的配置完成目录的挂载,例:docker run –name work_container –volumes-from data_container ubuntu。