9 docker 解惑

来源:互联网 发布:手机阅读软件mobi 编辑:程序博客网 时间:2024/06/07 05:05

-----Docker的目标: 可以轻松地把应用和它的依赖打包,然后在其他的开发、测试和生产环境上平滑的运行,最终目的是方便移植环境。

-----虚拟机的目标 :把一台机器虚拟成多台机器使用,或者把多台机器虚拟成一台机器使用,侧重点是资源的整合和分割,最终目的是为了充分利用资源。

Docker容器试图解决“依赖地狱”问题。现代的应用通常从已存在的组件组合而来,并且依赖其他服务和应用。比如,你的Python应用可能使用Postgre所为一个数据存储,用Redis缓存以及使用Apache作web服务器。每个这些组件都附带自身的一些依赖,这些依赖可能与其他组件产生冲突。通过打包每个组件及其依赖,Docker容器解决以下问题:

  • 冲突依赖:需要在PHP4.3上运行一个web站点而另一个运行在PHP5.5上?如果你在两个独立的Docker容器中分别运行一个版本的PHP,那就没问题。

  • 缺少依赖:在一个新环境上安装应用对Docker容器来说只是瞬间的事情,因为所有的依赖都和这个应用一起打包到一个容器中。

  • 平台依赖:从一个发行版移动到另一个不再是一个麻烦。如果两个系统都运行了Docker容器,那么相同的容器执行起来将没有任何问题。

1、Docker 是 容器管理工具

Docker 是一个轻量级、便携式(因为docker 环境下的容器可以导出,在另外一个docker 环境下又可以很方便的导入)、与外界隔离(基于linux底层技术lxc 实现命名空间分隔和资源控制)的容器,也是一个可以在容器中很方便地构建、传输、运行应用的引擎。和传统的虚拟化技术不同的是,Docker 引擎并不虚拟出一台虚拟机,而是直接使用宿主机的内核和硬件,直接在宿主机上运行容器内应用。也正是得益于此,Docker 容器内运行的应用和宿主机上运行的应用性能差距几乎可以忽略不计。

但是 Docker 本身并不是一个容器系统,而是一个基于原有的容器化工具 LXC 用来创建虚拟环境的工具。类似 LXC 的工具已经在生产环境中使用多年,Docker 则基于此提供了更加友好的镜像管理工具和部署工具。

为什么说docker 是轻量级的?

容器和虚拟机(VMs)都是虚拟化工具。

容器在操作系统层面虚拟化,而基于管理程序的虚拟化在硬件层面

容器运行在操作系统之上,把正在运行的操作系统当作自己的主机环境。它只运行在这样的空间上:这些空间是主机操作系统的一部分,而且各个容器使用的空间相互独立。这会带来三个非常鲜明的优点。第一个优点是更高效的使用资源。如果一个容器不执行任何操作,那么它就不会消耗资源,而且容器可以调用自己所在的主机操作系统以实现其所需要的部分或者全部功能。第二个优点是容器成本低,因此可以快速地创建和删除容器。容器不需要对整个操作系统进行重启或者关闭。容器仅仅需要的终止运行在自身独立空间的进程。因此启动和停止容器更像是启动和退出某个应用,因此启动和停止就非常快,第三个优点 隔离:容器构造操作系统中可用的受保护部分-它们有效地虚拟化操作系统。运行在同一个操作系统上的两个容器不知道它们在共享资源,因为彼此拥有自己的抽象网络层和进程等等

虚拟化仅提供了对硬件的访问,因此你还需要安装操作系统,每个虚拟机上运行一个,这将快速地吃完服务器上的诸如内存(RAM)、CPU和带宽等资源。在虚拟机上,一个管理程序使各个孤立的硬件可用。通常,这包括两种类型的管理程序:类型1直接运行在硬件裸金属片上,而类型2则在客户操作系统上作为软件附加层运行。开源的Xen和VMware的ESX是类型1 的例子,类型2的实例包括Oracle的开源VirtualBox和VMware服务器。虽然相比Docker容器而言,类型1是个更好的候选,但我在文章的其他部分并不区分这两种类型。

下图展示了虚拟机和容器

2、Docker 不是虚拟化引擎  (资源隔离,不虚拟化)

虚拟机是虚拟出一套硬件,虚拟机的系统进行的磁盘操作,其实都是在对虚拟出来的磁盘进行操作。当运行 CPU 密集型的任务时,是虚拟机把虚拟系统里的 CPU 指令“翻译”成宿主机的CPU指令并进行执行。

两个磁盘层,两个处理器调度器,两个操作系统消耗的内存,所有虚拟出的这些都会带来相当多的性能损失,一台虚拟机所消耗的硬件资源和对应的硬件相当,一台主机上跑太多的虚拟机之后就会过载。

而 Docker 就没有这种顾虑。Docker 运行应用采取的是“容器”的解决方案:使用 namespace 和 CGroup 进行资源限制,和宿主机共享内核,不虚拟磁盘,所有的容器磁盘操作其实都是对 /var/lib/docker/ 的操作。

简言之,Docker 其实只是在宿主机中运行了一个受到限制的应用程序。

从上面不难看出,容器和虚拟机的概念并不相同,容器也并不能取代虚拟机。在容器力所不能及的地方,虚拟机可以大显身手.例如:宿主机是 Linux,只能通过虚拟机运行 Windows,Docker 便无法做到。

3、Docker 使用层级的文件系统 (AuFS

前面提到过,Docker 和现有容器技术 LXC 等相比,优势之一就是 Docker 提供了镜像管理.对于 Docker 而言,镜像是一个静态的、只读的容器文件系统的快照。然而不仅如此,Docker 中所有的磁盘操作都是对特定的Copy-On-Write文件系统进行的。

4、Docker 可以节约时间 (镜像技术)

很多年前我在为一个连锁餐厅开发软件时,仅仅是为了描述如何搭建环境都需要写一个 12 页的 Word 文档。例如本地 Oracle 数据库,特定版本的 JAVA,以及其他七七八八的系统工具和共享库、软件包。

整个搭建过程浪费掉了我们团队每个人几乎一天的时间,如果用金钱衡量的话,花掉了我们上万美金的时间成本。虽然客户已经对这种事情习以为常,甚至认为这是引入新成员、让成员适应环境、让自己的员工适应我们的软件所必须的成本,但是相比较起来,我们宁愿把更多的时间花在为客户构建可以增进业务的功能上面。

如果当时有 Docker,那么构建环境就会像使用自动化搭建工具 Puppet / Chef / Salt 一样简单,我们也可以把整个搭建时间周期从一天缩短为几分钟。但是和这些工具不同的地方在于,Docker 可以不仅仅可以搭建整个环境,还可以将整个环境保存成磁盘文件,然后复制到别的地方。需要从源码编译 Node.js 吗?Docker 做得到。

Docker 不仅仅可以构建一个 Node.js 环境,还可以将整个环境做成镜像,然后保存到任何地方。当然,由于 Docker 是一个容器,所以不用担心容器内执行的东西会对宿主机产生任何的影响。

5、Docker 可以节省开销 (镜像技术)

当然,时间就是金钱。除了时间外,Docker 还可以节省在基础设施硬件上的开销。高德纳和麦肯锡的研究表明,数据中心的利用率在 6% - 12% 左右。

不仅如此,如果采用虚拟机的话,你还需要被动地监控和设置每台虚拟机的 CPU 硬盘和内存的使用率,因为采用了静态分区所以资源并不能完全被利用。而容器可以解决这个问题:容器可以在实例之间进行内存和磁盘共享。

你可以在同一台主机上运行多个服务、可以不用去限制容器所消耗的资源、可以去限制资源、可以在不需要的时候停止容器,也不用担心启动已经停止的程序时会带来过多的资源消耗。凌晨三点的时候只有很少的人会去访问你的网站,同时你需要比较多的资源执行夜间的批处理任务,那么可以很简单的便实现资源的交换。

虚拟机所消耗的内存、硬盘、CPU 都是固定的,一般动态调整都需要重启虚拟机。而用 Docker 的话,你可以进行资源限制,可以很方便动态调整资源限制,让然也可以不进行资源限制。Docker 容器内的应用对宿主机而言只是两个隔离的应用程序,并不是两个虚拟机,所以宿主机也可以自行去分配资源。

6、Docker 有一个健壮的镜像托管系统  (镜像技术)

前面提到过,这个托管系统就叫做 Docker Hub Registry。截止到 2015年4月29日,互联网上大约有 14000 个公共的 Docker,而大部分都被托管在 Docker Hub 上面。

和 Github 已经很大程度上成为开源项目的代表一样,Docker 官方的 Docker Hub 则已经是公共 Docker 镜像的代表。这些镜像可以作为你应用和数据服务的基础。

也正是得益于此,你可以随意尝试最新的技术:说不定有些人就把图形化数据库的实例打包成了 Docker 镜像托管在上面。再例如手工搭建 Gitlab 非常困难不建议普通用户去手工搭建,而如果使用 Docker Gitlab,这个镜像则会五秒内便搭建完成。

7、Docker 可以避免产生 Bug (镜像技术)

得益于 Docker 镜像可以很轻松的导入导出,我们可以最大程度地减少因为环境和版本问题导致的不兼容,即便有不兼容了也可以很轻松地回滚。当然,有了 Docker,我们在生产、测试和开发中的运行环境得到统一。

以前在协同开发时,会因为每个人开发的电脑配置不同而导致“在我的电脑上是能运行的,你的怎么不行”的情况,而如今 Docker 已经帮我们解决了这个问题。

8、Docker 目前只能运行在 Linux 上 (资源隔离是Linux 底层技术)

前面也提到过,Docker 使用的是经过长时间生产环境检验的技术,虽然这些技术已经都出现很长时间了,但是大部分技术都还是 Linux 独有的,例如 LXC 和 Cgroup。也就是说,截止到现在,Docker 容器内只能在 Linux 上运行 Linux 上的服务和应用。

除此之外,类似 boot2docker 和 Docker Machine 这种工具已经可以让我们在 Mac 和 Windows 下通过虚拟机运行 Docker 了。


9 docker 的独立性和安全性

Docker容器里所执行的进程与宿主机操作系统上运行的进程或者运行在其它Docker容器里的进程是相互独立的。不过,所有的进程都是运行在相同的内核里。Docker使用LXC来给每个容器提供独立的命名空间,内核里的这项技术已经具有5年多的历史了,已经十分成熟。另外,容器还使用了控制组,Linux内核里的这项技术比LXC的历史更长,它对资源进行审核和限制。

 

Docker服务进程本身还是一个潜在的攻击载体,这是因为它目前只能以root权限运行。对LXC和Docker的改进都应当允许以非root权限运行容器,而且可以用另外一个用户运行Docker服务进程。

虽然容器所使用的这种类型的隔离总的来说非常强大,然而是不是像运行在hypervisor上的虚拟机那么强壮仍具有争议性。如果内核停止,那么所有的容器就会停止运行。虚拟机具有优势的领域是它十分成熟,而且广泛的应用在生产环境中。相比之下,Docker和它的支撑技术几乎没有任何行动。特别是Docker每天都进行大量的修改变化,而且我们大家都知道变化是安全的天敌.


 10 docker 实现的原理:

Linux容器和LXC,一个用于Linux容器的用户空间控制程序包,是组成Docker的核心,LXC使用内核级命名空间将主机和容器相互隔离。用户命名空间将主机和容器的用户数据库分离,这样保证了容器的root用户没有主机的root权限。程序命名空间仅负责显示和管理程序在容器中,而非在主机运行。而且网络命名空间提供自己的网络设备和虚拟IP地址给容器。

LXC提供的另一个组件是控制组(cgroups)。命名空间负责主机与容器之间的隔离,而控制组实现资源核算和限制。当允许Docker限制被一个容器消耗的资源:如内存、磁盘空间和输入输出时,控制组也会输出大量与之相关的指标。这些指标使Docker能够监控容器内各个进程的资源消耗并确保每个进程只获取可用的公平共享资源。


除了以上组件,Docker一直在用AuFS(高级多层次统一文件系统)作为容器的文件系统。AuFS是一个能透明覆盖一或多个现有文件系统的层状文件系统。当一个进程需要修改一个文件时,AuFS创建该文件的一个副本。AuFS可以把多层合并成文件系统的单层表示。这个过程称为写复制。

真正酷毙的是,AuFS允许Docker把某些镜像作为容器的基础。例如,你可能有一个可以作为很多不同容器的基础的CentOS系统镜像。多亏AuFS,只要一个CentOS镜像的副本就够了,这样既节省了存储和内存,也保证更快速的容器部署。


使用AuFS的另一个好处是Docker的版本容器镜像能力。每个新版本都是一个与之前版本的简单差异改动,有效地保持镜像文件最小化。但,这也意味着你总是要有一个记录该容器从一个版本到另一个版本改动的审计跟踪。

传统上,Docker依赖AuFS提供了写复制存储机制。然而,最近添加的一个存储启动API可能降低这种依赖。最初,可用的存储驱动有三种:AuFS、VFS和设备映射器-与红帽合作的产物。

docker 以来aufs 实现了 在下载的镜像基础上修改,然后保存为自己的镜像。

11 Docker仓库

Docker杀手级特性之一就是能够快速的查找、下载和启动由其他开发者创建的容器映像。存储映像的地方称为注册中心。Docker有限公司提供一个公共的注册中心,这个注册中心也称为索引中心。你可以把这个注册中心和Docker客户端看作与Node的NPM,Perl的CPAN或者Ruby的RubyGems等同。

除了可以用来创建Docker容器的各种基本映像外,公共的Docker注册中心还提供即刻即可运行的软件映像,其中包括数据库、内容管理系统、开发环境和Web服务器等等。默认情况下Docker命令行客户端搜索的是公共的注册中心,不过,也可以维护私有的注册中心。如果要发布含有专有知识产权代码的或者仅公司内部使用的组件的映像,那么注册中心就是一个很好的选择。把映像上传到注册中心就像下载一样容易。只要求你创建一个账户,而且这一切都是免费的。最后,Dcoker有限公司的注册中心还有Web界面,方便对映像进行搜索、读取、评论和推荐(即“标记星号”)。映像使用起来出奇的容易,我鼓励你这篇文档资源一小节里的链接,开始浏览映像。

12 docker 下载镜像并且部署服务的过程

一开始,先运行docker search mysql命令,这条命令将显示公共Docker注册中心里匹配关键词"mysql"的映像列表。我确定这条命令可以正常运行,接着使用命令docker pull brice/mysql下载"brice/mysql"映像。你可以看到Docker不仅仅下载的是你所指定的映像,而且还可以下载依赖这个包所建立的其他映像。输入docker images命令,将会罗列出目前本地具有的所有映像,其中包括了"brice/mysql"映像。使用-d选项启动容器,它将会脱离当前运行的容器之外运行一个容器,此时,你已经在一个容器里运行了MySQL了。你可以使用docker ps命令来验证,这条命令经罗列出运行的容器,而不是罗列出映像。在命令行的输出里,你还能看到MySQL服务侦听的端口号,默认是3306。

几点人
几点人
翻译于 2年前

2人顶

 翻译的不错哦!

然而,在知道MySQL运行在容器内部情况下,你该怎样连接到MySQL呢?切记:每个Docker容器有自己的网络接口。你需要确定的是mysqld服务器进程运行在哪个IP地址和端口上。运行docker inspect <imageId>命令,它将给我们提供大量的信息。不过,由于你所需要的仅仅是IP地址,所以当你使用容器的哈希值对容器进行查看的时候,你就可以抓取到IP地址,即运行docker inspect 5a9005441bb5 | grep IPAddress。现在你可以通过给标准的MYSQL CLI客户端指定主机地址和端口选项来连接了。当你使用完MySQL服务器后,你可以使用命令docker stop 5a9005441bb5关闭这个容器了。

我们使用了7条命令查找、下载、启动运行MySQL服务器的Docker容器以及使用完后关闭这个容器。在这个过程中,你不必担心与已安装软件之间存在的冲突,也不必担心MySQL的版本有什么不一样,或者存在哪些包依赖。你使用了7条不同的Docker命令:search、pull、images、run、ps、inspect和stop,不过,Docker客户端实际上有33条命令。你可以通过命令运行docker help命令或者查找在线手册来查阅全部命令列表。



0 0
原创粉丝点击