Docker是什么
- Docker 是世界领先的软件容器平台。
- 开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
- 运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。
- 企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。
总体来说,Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。用户可以方便地创建和使用容器,把自己的应用放入容器,就不用担心环境问题。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker起源
Docker 是 PaaS提供商 dotCloud 开源的一个基于LXC的高级容器引擎,源代码托管在Github上, 基于go语言并遵从Apache2.0协议开源。
Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持, 就连 Google 的 Compute Engine 也支持 docker 在其之上运行。
物理机、虚拟机和容器之间的区别
物理机
虚拟机
容器
用官方的翻译就是:Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。
容器之间是共享同一套操作系统资源的,由于容器是共享主操作系统的内核,因此就无法在服务器上运行与主服务器不同的操作系统,也就是说不能再Linux的服务器上运行Windows。就如上面哪个图一样,每个胶囊容器是公用一个厕所,厨房,每个胶囊内无法再构建出自己的厕所和厨房!
Docker的优势
- 更快速的交付和部署:开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。
- 更高效的虚拟化(轻量和高效):Docker 容器的运行不需要额外的 hypervisor(虚拟机器监视器)支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。和虚拟机相比,容器仅需要封装应用和应用需要的依赖文件,实现轻量的应用运行环境,且拥有比虚拟机更高的硬件资源利用率。
- 更轻松的迁移和扩展(免去环境/配置的麻烦):对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。 用上docker容器后,可以实现开发、测试和生产环境的统一化和标准化。镜像作为标准的交付件,可在开发、测试和生产环境上以容器来运行,最终实现三套环境上的应用以及运行所依赖内容的完全一致。 Docker可以将我们的想要的环境构建(打包)成一个镜像,然后我们可以推送(发布)到网上去。想要用这个环境的时候,在网上拉取一份就好了。
- 更简单的管理:使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
- 安全(隔离性强):用上了docker容器后,将Docker可以将我们的应用程序打包封装到一个容器中,该容器包含了应用程序的代码、运行环境、依赖库、配置文件等必需的资源。容器之间达到进程级别的隔离,在容器中的操作,不会影响道宿主机和其他容器,这样就不会出现应用之间相互影响的情形!
Docker vs VM
虚拟机(VM)
VM是一个运行在宿主机之上的完整的操作系统,VM运行自身操作系统会占用较多的CPU、内存、硬盘资源。VM 是一个物理硬件层抽象,用于将一台服务器变成多台服务器。管理程序允许多个 VM 在一台机器上运行。每个 VM 都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此占用大量空间。而且 VM 启动也十分缓慢。
容器(Docker)
Docker不同于VM,只包含应用程序以及依赖库,基于libcontainer运行在宿主机上,Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护,这使得Docker更加轻量高效,启动容器只需几秒钟之内完成。由于Docker轻量、资源占用少,使得Docker可以轻易的应用到构建标准化的应用中,并且Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。但Docker目前还不够完善,比如隔离效果不如VM,共享宿主机操作系统的一些基础库等;网络配置功能相对简单,主要以桥接方式为主;查看日志也不够方便灵活。
VM+Docker的方式,将容器和虚拟机配合使用,为应用的部署和管理提供极大的灵活性。
Docker架构
Docker 使用 C/S 结构,即客户端/服务器体系结构。Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像。Docker 客户端和服务端可以运行在一台机器上,也可以通过 RESTful 、 Stock 或网络接口与远程 Docker 服务端进行通信。
主要有两个概念:
- Docker daemon: 运行在宿主机上,Docker守护进程,用户通过Docker client(Docker命令)与Docker daemon交互
- Docker client: Docker 命令行工具,是用户使用Docker的主要方式,Docker client与Docker daemon通信并将结果返回给用户,Docker client也可以通过socket或者RESTful api访问远程的Docker daemon
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。 Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可将 Docker 镜像看成只读模板,通过它可以创建 Docker 容器。 从无到有开始创建镜像 下载并使用别人创建好的现成的镜像 在现有镜像上创建新的镜像 我们可以将镜像的内容和创建步骤描述在一个文本文件中,这个文件被称作 Dockerfile ,通过执行 docker build命令可以构建出 Docker 镜像。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用。 Docker 容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。 |
Docker 客户端(Client) | Docker Client ,也称 Docker 客户端。它其实就是 Docker 提供命令行界面(CLI)工具,是许多 Docker 用户与 Docker 进行交互的主要方式。 客户端可以构建,运行和停止应用程序,还可以远程与 Docker_Host 进行交互。 Docker 客户端通过命令行或者其他工具使用 Docker API 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker 仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。 Docker Hub提供了庞大的镜像集合供使用。 Docker Registry 是存储 Docker Image 的仓库, |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
docker Daemon
| Docker Daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程。 |
这种利用仓库管理镜像的设计理念类似于 Git ,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。
Docker的三个主要概念
Docker image(镜像):
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像包含有需要运行的文件,不包含任何动态数据,其内容在构建之后也不会被改变。镜像(Image)就是一堆只读层(read-only layer)的统一视角。
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其他层都会有一个指针指向下一层。这些层是 Docker 内部的实现细节,并且能够在主机的文件系统上访问到。
统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角。
这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。
镜像用来创建container,一个镜像可以运行多个container;镜像可以通过Dockerfile创建,也可以从Docker hub/registry上下载。
Docker container(容器):
容器(Container)的定义和镜像(Image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
由于容器的定义并没有提及是否要运行容器,所以实际上,容器 = 镜像 + 读写层。
容器是Docker的运行组件,启动一个镜像就是一个容器,容器是一个隔离环境,多个容器之间不会相互影响,保证容器中的程序运行在一个相对安全的环境中。
Docker registry(仓库):
Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行。但是, 如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry(仓库注册服务器)就是这样的服务。有时候会把仓库(Repository)和仓库注册服务器(Registry)混为一谈,并不严格区分。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。实际上,一个 Docker Registry 中可以包含多个仓库(Repository),每个仓库可以包含多个标签(Tag),每个标签对应着一个镜像。所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 Latest 作为默认标签。
仓库又可以分为两种形式:
- Public(公有仓库)
- Private(私有仓库)
Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。当用户创建了自己的镜像之后就可以使用 Push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 Pull 下来就可以了。共享和管理Docker镜像,用户可以上传或者下载上面的镜像,官方地址为 https://registry.hub.docker.com/,也可以搭建自己私有的Docker registry。
镜像是 Docker 运行容器的前提,仓库是存放镜像的场所,可见镜像更是 Docker 的核心。
镜像就相当于打包好的版本,镜像启动之后运行在容器中,仓库就是装存储镜像的地方。
镜像VS容器
镜像是以一系列历史操作叠加而成的,对镜像的每一次操作都会产生新的只读层,比方说你往容器写入内容,提交,再把它移除,则会产生两个历史只读层,有点像 git commits,而容器可以理解问为镜像历史层 + 可写层的可运行系统,在可写层做任何操作都没问题,不提交的话,容器被删除后相应的改动也会丢失,有点像 git 暂存区。
其实镜像有点像代码,容器有点像进程。代码是存放在硬盘上的东西,而把代码运行起来,就会形成一个进程,进程才是跑起来的程序。
Docker镜像的特点
关于Docker镜像,有以下特点:
Docker的镜像的基础是联合文件系统,它支持将文件系统中的修改信息作为一次提交,并层层叠加,外界看到的是最外层的镜像。
- 由Dockerfile生成
- 呈现层级结构
- 每层镜像包含:镜像文件以及镜像json元数据信息
Docker每一层镜像的json文件,都扮演着一个非常重要的角色,其主要的作用如下:
- 记录 Docker 镜像中与容器动态信息相关的内容
- 记录父子 Docker 镜像之间真实的差异关系
- 弥补 Docker 镜像内容的完整性与动态内容的缺失
Docker镜像的json文件可以认为是镜像的元数据信息
-
镜像继承(共享)
Docker镜像可以通过分层来进行继承。