当前位置: 首页 > >

Docker容器技术学*(1)??基础知识

发布时间:



文章目录
一、背景为什么要学*docker?
二、Docker的相关概念1.Docker2、镜像3、容器4、运行态容器5、镜像层6、仓库7、Docker 的架构
三、Docker的优缺点



一、背景
为什么要学*docker?

简单举一个例子
在开发中我们经常会遇到这样的问题:我的代码在本地是好好的,为什么放到另一个环境上就跑不起来了呢?


这时候就牵扯到了另一个因素环境。我们的开发环境受制很多因素,比如我用win或者mac os开发的,但是部署到了centos上面了,造成的环境影响。还有配置,数据库版本,等等一系列的问题。


因为环境的不同,当运维拿到我们的代码的时候就会很头疼。所以急切的希望出现一种技术来统一这些环境。你开发就不要只提交代码给我了,把你的代码连着你的开发环境直接打包丢给我吧。或者说我来弄一套环境,你在我这上面开发。


所以这时候docker就出现了,来解决我们这些一套环境的问题。


二、Docker的相关概念
1.Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。(来源百度百科)


我们在理解 docker 之前,首先我们得先区分清楚两个概念:容器和虚拟机。
容器和虚拟机的区别


我们用的传统虚拟机如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。
每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。

而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。 容器包含应用和其所有的依赖包,但是与其他容器共享内核。
容器在宿主机操作系统中,在用户空间以分离的进程运行。


容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。通过下面这幅图我们可以很直观的反映出这两者的区别所在。



Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。而 Linux 容器是 Linux 发展出了另一种虚拟化技术,简单来讲, Linux
容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。
对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。DockerDocker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。
将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了
Docker ,就不用担心环境问题。

总体来说, Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。


2、镜像

镜像(Image Definition)(image)


镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助我们理解镜像的定义



从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker内部的实现细节,并且能够在主机(译者注:运行Docker的机器)的文件系统上访问到。统一文件系统(union file system)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。


你可以在你的主机文件系统上找到有关这些层的文件。需要注意的是,在一个运行中的容器内部,这些层是不可见的。在我的主机上,我发现它们存在于/var/lib/docker/aufs目录下。


# sudo tree -L 1 /var/lib/docker/
/var/lib/docker/
├── aufs
├── containers
├── graph
├── init
├── linkgraph.db
├── repositories-aufs
├── tmp
├── trust
└── volumes
7 directories, 2 files

3、容器

容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。


要点:容器 = 镜像 + 读写层。并且容器的定义并没有提及是否要运行容器。
接下来,我们将会讨论运行态容器。


4、运行态容器

一个运行态容器(running container)被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。
下面这张图片展示了一个运行中的容器。



正是文件系统隔离技术使得Docker成为了一个前途无量的技术。
一个容器中的进程可能会对文件进行修改、删除、创建,这些改变都将作用于可读写层(read-write layer)。下面这张图展示了这个行为。



5、镜像层

为了将零星的数据整合起来,我们提出了镜像层(image layer)这个概念。
下面的这张图描述了一个镜像层,通过图片我们能够发现一个层并不仅仅包含文件系统的改变,它还能包含了其他重要信息。



元数据(metadata)就是关于这个层的额外信息,它不仅能够让Docker获取运行和构建时的信息,还包括父层的层次信息。
需要注意,只读层和读写层都包含元数据。



除此之外,每一层都包括了一个指向父层的指针。如果一个层没有这个指针,说明它处于最底层。



Metadata Location:
我发现在我自己的主机上,镜像层(image layer)的元数据被保存在名为”json”的文件中,比如说:
/var/lib/docker/graph/e809f156dc985.../json
e809f156dc985...就是这层的ID。

一个容器的元数据好像是被分成了很多文件,但或多或少能够在/var/lib/docker/containers/目录下找到,就是一个可读层的ID。
这个目录下的文件大多是运行时的数据,比如说网络,日志等等。


6、仓库

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 的一些常见概念如 Image , Container , Repository 做了详细的阐述,也从传统虚拟化方式的角度阐述了 docker 的优势,我们从下图可以直观地看到


7、Docker 的架构


Docker 使用 C/S 结构,即客户端/服务器体系结构。 Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像。 Docker 客户端和服务端可以运行在一台机器上,也可以通过 RESTful 、 stock 或网络接口与远程 Docker 服务端进行通信。



这张图展示了 Docker 客户端、服务端和 Docker 仓库(即 Docker Hub 和 Docker Cloud ),默认情况下Docker 会在 Docker 中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念类似于 Git ,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。


三、Docker的优缺点

Docker相比于传统虚拟化方式具有更多的优势:


docker 启动快速属于秒级别,虚拟机通常需要几分钟去启动docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离安全性:
docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击可管理性:
docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力高可用和可恢复性:
docker 对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性快速创建、删除:
虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间交付、部署:
虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署

我们可以从下面这张表格很清楚地看到容器相比于传统虚拟机的特性的优势所在:



docker容器也有一些问题是没有解决的


隔离性:
基于hypervisor的虚机技术,在隔离性上比容器技术要更好,它们的系统硬件资源完全是虚拟化的,当一台虚机出现系统级别的问题,往往不会蔓延到同一宿主机上的其他虚机。但是容器就不一样了,容器之间共享同一个操作系统内核以及其他组件,所以在收到攻击之类的情况发生时,更容易通过底层操作系统影响到其他容器。当然,这个问题可以通过在虚机中部署容器来解决,可是这样又会引出新的问题,比如成本的增加以及下面要提到的问题:性能。

性能:
不管是虚机还是容器,都是运用不同的技术,对应用本身进行了一定程度的封装和隔离,在降低应用和应用之间以及应用和环境之间的耦合性上做了很多努力,但是随机而来的,就会产生更多的网络连接转发以及数据交互,这在低并发系统上表现不会太明显,而且往往不会成为一个应用的瓶颈(可能会分散于不同的虚机或者服务器上),但是当同一虚机或者服务器下面的容器需要更高并发量支撑的时候,也就是并发问题成为应用瓶颈的时候,容器会将这个问题放大,所以,并不是所有的应用场景都是适用于容器技术的。

存储方案:
容器的诞生并不是为OS抽象服务的,这是它和虚机最大的区别,这样的基因意味着容器天生是为应用环境做更多的努力,容器的伸缩也是基于容器的这一disposable特性,而与之相对的,需要持久化存储方案恰恰相反。这一点docker容器提供的解决方案是利用volume接口形成数据的映射和转移,以实现数据持久化的目的。但是这样同样也会造成一部分资源的浪费和更多交互的发生,不管是映射到宿主机上还是到网络磁盘,都是退而求其次的解决方案。


随着硬件技术和网络技术的迭代发展,容器技术的缺点会变得越来越不那么明显,而且随着容器技术的发展和普及,对应的解决方案也会越来越多。所以总体来看,docker等容器技术会朝着更加普及的趋势走*我们技术领域。 也希望每一位热爱技术的小伙伴们能更加了解这些新技术,让它们能够更好的为我们服务。



友情链接: