1.docker是什么?
Docker,翻译过来就是码头工人
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。
2.为什么需要docker?
(1)原因1:安装一个软件,并让这个软件能正常运行,其实是个挺麻烦且容易出问题的事;那么对于我们开发的项目来说,更是如此;软件运行所需的环境,配置起来还是挺麻烦的,而且一旦我们配置错了,程序往往就无法运行;比如,在自己开发电脑上能运行的项目,在运维的服务器上可能就运行不了,这大概率就是【运维服务器上的配置的环境】和【自己开发电脑上的环境】不一致导致的;
(2)原因2:为了解决上面的问题,我们可以考虑使用虚拟机技术;我们可以把程序运行所需的环境给打成一个系统镜像,然后,可以创建很多虚拟机,这些虚拟机都使用我们上面的镜像;那么,这样一来,我们就可以获取到很多OK的【程序以及对应的运行环境】;;但是,虚拟机虽然可以提供完全隔离的环境,但是虚拟机的开销是很大的;一个完整的、想要运行我们项目的虚拟机,大概要占用几十G的硬盘,同时也需要占用内存;而且,这些被虚拟机占用的资源,是无法被外界共享的;而,Docker可以解决这问题;(PS,这儿理解可能错误:Docker的容器,可以认为是一个低消耗、互相隔离的、可共享操作系统内核的,虚拟机))
3.docker特点
(1)标准:
● docker很流行,实际上已经成为了容器的实际标准;这也意味,比如我们这儿有一个镜像,只要我们的服务器上安装有docker环境,那么我们就可以使用docker提供的命令把这个镜像给启动起来,启动成一个容器;(主要原因是:由于docker技术应用广泛且已经是事实上的标准,所以即使是其他技术打成的镜像,我们使用docker的命令,也大概率是能把其给启动起来的)
● 比如,我们打了【Tomcat软件及其运行环境的,镜像】、【Nginx软件及其运行环境的,镜像】;然后,我们知道Tomcat和Nginx的命令是不同的;但是,只要经过一定的配置,我们在使用docker去启动这些镜像的时候,不需要考虑【Tomcat和Nginx,各自的命令】,只要执行docker相关的命令,就可以保证镜像能正常启动,能启动成一个容器,里面的软件能正常运行;;;;也正是由于docker的标准化,docker才越来越流行;
(2)轻量级:
● docker的轻量级,主要是和虚拟机相比的;因为,容器是可以共享机器的操作系统内核的,因此就提高了服务器的整体运行效率;
(3)安全:
● 安全,主要体现在docker的隔离能力;假设我们有两个程序分别运行在两个不同的容器中,那么两个程序相互默认是独立的、隔离的、不影响的;比如如果不使用docker的话,以前,我们的一台服务器往往会运行多个程序(比如,我们可以在服务器上部署多个项目,然后这些项目使用不同的端口),而这很容易会出现这种情况:一个程序在运行时,一不小心把操作系统给带胯了(或者把内存给占光了,或者把硬盘给占满了);那么,这样一来,就会影响到另一个程序;;;而,如果我们使用docker的话,则不会出现这样的问题;
4.docker架构
(1)Client:就是docker的客户端;比如,我们在自己的服务器上安装docker后,那么自己的本地的这台服务器,就可以看成是docker的客户端;
● docker客户端,可以使用docker的相关命令,这些信号会传到到DOCKER_HOST(docker服务器);
(2)DOCKER_HOST(docker服务器);
● 这些命令,首先会传到Docker_daemon;由Docker_daemon对这些命令,进行分发和处理;Docker_daemon是进行统一指挥的;
● Images(镜像),Containers(容器),Registry(仓库);
(3)Images(镜像);
● docker打包,是把程序和环境一起打包的;这个打包,就是生成一个Image镜像;这个镜像就包括我们的程序和程序运行所需的依赖和环境;
● 所以,如果我们有了一个完整的Images,我们我们就能够确保,程序一定能够跑起来;(因为,这个镜像不仅包含我们的程序,还包含程序运行所需的依赖和环境)
● Images(镜像)可以叠加,而且镜像通常是分层的,最底层可能是某个操作系统(比如Ubuntu);然后,在这层的上面,我们可能会首先安装java环境;然后,有了java环境之后,在往上可能是我们自己电商项目的jar包;;;;那么,由于镜像的这种特点;如果我们创建一个我们电商项目的镜像的话,我们就不需要从0设置我们的镜像,我们可以在别人镜像的基础上(比如,有个人设置了一个CentOS操作系统的镜像)进行叠加;这样一来,效率更高;
● 其实进行镜像就相当于是一个实际存在的标准、规范、配置;当我们把这个镜像设置到我们的服务器上,并启动它的时候,这个镜像就被启动成了一个容器,也就意味这个镜像活了;
(4)Containers(容器);
● 即这个流程是这样的:首先,使用docker把【我们的项目,和,项目的环境、配置】给打成一个镜像;然后,我们把这个镜像放在我们服务器上;然后,在服务器上,我们通过docker命令,把这个镜像给启动起来,然后就得到了该镜像的一个容器;我们的项目就是跑在这个容器中的;
● 一个镜像可以有多个容器;;比如,我么有个Nginx镜像,那么我们把这个镜像上传到服务器上后,把这个镜像给启动起来后,就得到了一个该镜像的容器;;;;;同时,一个镜像可以有多个容器,比如,这个Nginx镜像我们可以启动一个容器,然后设置其端口为80;然后,我们再启动一个容器,其端口可以设为81;然后,我们还可以启动一个容器,其端口设为82;;;;这些容器,都是来自于同一个镜像; 而且,这一个镜像的多个容器,是互相隔离的;
● 容器,是可进一步修改;比如,我们启动了一个MySQL的镜像,启动得到了一个运行MySQL的容器;那么,我们可以在这个容器中,修改MySQL的用户名、端口等;然后,如果我们以修改后的容器中的环境打成一个新的镜像的话,那么这个镜像启动后的容器的环境就是我们修改后的;
(5)Registry(仓库);
● 仓库主要起到集中存储的功能(比如Maven就有中央仓库;);我们在本地打了个镜像后,就可以把这个镜像推送到仓库,然后运维同事就可以从仓库中把镜像给下载下来;
● 一般,我们常使用的【程序及其运行环境的,镜像】,在仓库中,官方都提供了个一个比较标准的;访问docker官方的中央仓库:【Docker Hub】
5.云计算中的服务包括三个层面
IaaS:基础设施服务
基础设施即服务。有了laaS,企业在开发APP时,只需在公有云平台上注册一个账号,花点钱,配置各种云服务器,各种大小的存储,各种带宽的网络,都配齐,不用操心诸如机房选址、设备采购、实体服务器、存储、网络等问题,只要一个账号,便解决了。
PaaS:平台服务
平台即服务。PaaS是在IaaS的基础之上,解决了操作系统、数据库、运行时环境runtime、中间件、各种框架的搭建操作问题,有了PaaS,程序员只需要专心的开发自己的APP就行了。
SaaS:软件服务
软件即服务。SaaS就是现成的了,根本用不着开发,商家只需要专注在自己的业务上就行了,别的写代码、维护等各种事情都交给SaaS厂商就行了。用户只需要一个续费账号,所有问题都解决了。
6.传统虚拟化架构
7.容器架构
8.docker系统架构
Docker 守护进程
Docker 守护进程(dockerd
)侦听 Docker API 请求并管理 Docker 对象,例如 images(镜像),containers(容器),networks(网络)和 volume(卷)。守护进程还可以与其他守护进程通信以管理 Docker 服务。
Docker 客户端
Docker 客户端(docker
)是许多 Docker 用户与 Docker 交互的主要方式。当您使用诸如docker run
之类的命令时,客户端会将这些命令发送到 dockerd
,以执行这些命令。该docker
命令使用 Docker API。Docker 客户端可以与多个守护进程通信。
Docker 仓库
Docker 仓库存储 Docker 镜像。Docker Hub 是任何人都可以使用的官方公共仓库,并且 Docker 配置为默认在 Docker Hub 上查找镜像。您甚至可以运行自己的私人仓库。如果使用 Docker 数据中心(DDC),则其中包括 Docker 可信仓库(DTR)。
使用 docker pull
或 docker run
命令时,所需的镜像将从配置的仓库中提取。使用 docker push
命令时,会将镜像推送到配置的仓库。
Docker 对象
使用 Docker 时,您正在创建和使用镜像(Image),容器(Container),网络(Network),卷(Volume),插件(Plugin)和其他对象。本节是其中一些对象的简要概述。
Images(镜像)
镜像是一个只读模板(不包含任何动态数据,其内容在构建之后也不会被改变 ),其中包含创建 Docker 容器的说明。通常,一个镜像基于另一个镜像,并带有一些额外的配置。 例如,你可以建立一个基于 ubuntu 镜像的镜像,安装 ubuntu Apache HTTP Server 和你的应用程序,以及运行你的应用程序所需的配置细节。
您可以创建自己的镜像,也可以仅使用其他人创建并在仓库中发布的镜像。要构建自己的镜像,您可以使用简单的语法创建一个 Dockerfile
,以定义创建镜像并运行它所需的步骤。Dockerfile
中的每条指令都会在镜像中创建一个层。更改 Dockerfile
并重建镜像时,仅重建那些已更改的层。与其他虚拟化技术相比,这是使镜像如此轻巧,小型和快速的部分原因。
Containers (容器)
容器是镜像的可运行实例。您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。您可以将容器连接到一个或多个网络,将存储附加到该网络,甚至根据其当前状态创建新镜像。
默认情况下,容器与其他容器及其主机之间的隔离程度相对较高。您可以控制容器的网络、存储或其他基础子系统与其他容器或与主机的隔离程度。
容器由其镜像以及在创建或启动时为其提供的任何配置选项定义。删除容器后,未存储在持久性存储中的状态更改将消失。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 Volume(数据卷)、或者挂载宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)进行读写,其性能和稳定性更高。
Service (服务)
服务允许跨多个 Docker 守护进程调度容器,这些守护进程以多个管理者和工作者的集群模式协同工作。集群的每个成员都是一个 Docker 守护进程,并且所有守护进程都使用 Docker API 进行通信。
服务允许您定义所需的状态,例如在任何给定时间必须可用的服务副本数。默认情况下,该服务在所有工作节点之间实现负载平衡。对于使用者而言,Docker 服务似乎是一个单独的应用程序。Docker Engine 在 Docker 1.12 及更高版本中支持集群模式。
9.docker底层技术
Docker用Go编写,并利用Linux内核的多个功能来交付其功能。底层核心技术包括命名空间(Namespaces)、控制组(Control groups)、Union 文件系统(Union file systems)和容器格式(Container format)。
命名空间(namespaces)
Docker使用一种称为 namespaces
的技术来提供称之为容器的隔离工作区。运行容器时,Docker会为该容器创建一组命名空间。通过命名空间隔离容器之间彼此不受影响,且其访问权限也仅限于该命名空间。
Docker Engine 在Linux 上使用以下命名空间:
pid
命名空间:进程隔离(PID:Process ID)。net
命名空间:管理网络接口(NET:Networking)。ipc
命名空间:管理对IPC资源的访问(IPC:InterProcess Communication)。mnt
命名空间:管理文件系统挂载点(MNT:Mount)。uts
命名空间:隔离内核和版本标识符。(UTS:Unix Timesharing System)。
控制组(cgroups)
Linux上的 Docker 引擎依赖一种称为控制组 (cgroups
)的技术。控制组为应用程序限制一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,可以限制特定容器可用的内存。
CGroups 全称control group,用来限定一个进程的资源使用,由Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源 ,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。
联合文件系统(UnionFS)
UnionFS文件系统,是通过创建层来操作的文件系统,这使得它们非常轻量级和快速。 Docker Engine 使用 UnionFS
为容器提供分层构建块。 Docker Engine 可以使用多个 UnionFS
变体,包括 AUFS
、 btrfs
、 vfs
和 DeviceMapper
。
Union File System,简称UnionFS,他是一种为Linux 、FreeBSD 和NetBSD 操作系统设计的,把其他文件系统联3合到一个联合挂载点的文件系统服务。
容器格式(Container format)
Docker Engine 将namespaces
、cgroups
和 UnionFS
组合成一个称为容器格式的包装器。 默认的容器格式是 libcontainer
。