快速理解Docker

作者:刘旭晖 Raymond 转载请注明出处

Email:colorant at 163.com

BLOG:http://blog.csdn.net/colorant/

是什么

 

简单的说Docker是一个构建在LXC之上的,基于进程容器(Processcontainer)的轻量级VM解决方案

 

拿现实世界中货物的运输作类比, 为了解决各种型号规格尺寸的货物在各种运输工具上进行运输的问题,我们发明了集装箱

 

 

 

Docker的初衷也就是将各种应用程序和他们所依赖的运行环境打包成标准的container/image,进而发布到不同的平台上运行

 

 

 

从理论上说这一概念并不新鲜, 各种虚拟机Image也起着类似的作用

 

Docker container和普通的虚拟机Image相比, 最大的区别是它并不包含操作系统内核.

 

 

 

普通虚拟机将整个操作系统运行在虚拟的硬件平台上, 进而提供完整的运行环境供应用程序运行, 而Docker则直接在宿主平台上加载运行应用程序. 本质上他在底层使用LXC启动一个Linux
Container,通过cgroup等机制对不同的container内运行的应用程序进行隔离,权限管理和quota分配等

 

每个container拥有自己独立的各种命名空间(亦即资源)包括:

 PID 进程, MNT 文件系统,
NET 网络, IPC ,
UTS 主机名 等

 

 LXC有什么不同

 

基本上你可以认为目前的Docker是LXC的一个高级封装,提供了各种辅助工具和标准接口方便你使用LXC,你可以依靠LXC和各种脚本实现与docker类似的功能,就像你不使用APT/yum等工具也可以自己搞定软件包安装一样,你使用他们的关键原因是方便易用!

 

实际使用中,你一般不用关心底层LXC的细节,同时也不排将来docker实现基于非LXC方案的可能性

 

在LXC的基础上, Docker额外提供的Feature包括:标准统一的打包部署运行方案, 历史版本控制, Image的重用,Image共享发布等等

 

 

Container构建方案

 

除了LXC,Docker的核心思想就体现在它的运行容器构建方案上

 

 

为了最大化重用Image,加快运行速度,减少内存和磁盘footprint, Docker container运行时所构造的运行环境,实际上是由具有依赖关系的多个Layer组成的。例如一个apache的运行环境可能是在基础的rootfs
image的基础上,叠加了包含例如Emacs等各种工具的image,再叠加包含apache及其相关依赖library的image,这些image由AUFS文件系统加载合并到统一路径中,以只读的方式存在,最后再叠加加载一层可写的空白的Layer用作记录对当前运行环境所作的修改。

 

有了层级化的Image做基础,理想中,不同的APP就可以既可能的共用底层文件系统,相关依赖工具等,同一个APP的不同实例也可以实现共用绝大多数数据,进而以copy
on write的形式维护自己的那一份修改过的数据等

 

历史和生态环境

 

Docker项目从启动到现在不过一年多时间,发展势头还是很迅猛的

 

2013.01 做为dotcloud内部项目开始启动

2013.03.27 正式作为public项目发布

2014.1 被BLACK DUCK 评选为2013年10大开源新项目“TOP
10 OPEN SOURCE ROOKIE OF THE YEAR”

 

目前的状态 ( 2014.3 )

 

Docker 0.8.1

10000+ github stars(top 50)

350+ contributors

1500+ fork

 

 

具体应用方面,可以看到百度至少在2013年10月份就已经成功使用Docker支持其BAE平台的Paas服务

 

安装运行和使用

 

Docker虽然是号称build once, runeverywhere。但是实际上还是受其引擎依赖关系的限制的,目前的版本具体来说对系统要求:

 

  • Linux Kernel 3.8+
  • LXC support
  • 64bit OS
  • AUFS

 

以上要求,以ubuntu为例,需要12.04 配合 3.8kernel升级, 或者 ubuntu
13.04+

 

在ubuntu12.04上,基本安装步骤如下

 

sudoapt-get update sudo apt-get install linux-image-generic-lts-raringlinux-headers-generic-lts-raring

sudoapt-key adv --keyserver keyserver.ubuntu.com --recv-keys36A1D7869245C8950F966E92D8576A8BA88D21E9

sudosh -c "echo deb http://get.docker.io/ubuntudocker main\ > /etc/apt/sources.list.d/docker.list"

sudoapt-get update

sudoapt-get install lxc-docker

 

如果你在安装之前想要先体验一下docker的基本操作命令等的话, 可以尝试一下这个在线的live教程https://www.docker.io/gettingstarted/#h_tutorial

 

常用命令

 

分类列一下常用的CLI命令

 

  • 仓库相关

 

search/ pull / push / login etc.

例:docker pull ubuntu 从仓库下载ubuntuimage

 

  • Images 操作相关

 

images/ rmi / build / export  / import / save /load etc.

例:docker images -t 以树形结构列出当前本地Image

 

  • 运行相关

 

run / start / stop / restart / attach /kill etc.

docker run -i -t ubuntu /bin/bash  启动ubuntu image,并交互式的运行shell

 

  • 杂项

 

Docker diff  / commit

Dockerinfo / ps / inspect / port / logs / top / history etc.

 

 

具体docker命令的使用参见 http://docs.docker.io/en/latest/reference/commandline/

 

常见问题

 

  • 使用Non root 用户

 

目前版本的docker由于使用Socket进行通讯,因此需要root用户权限 sudo
xxx,或者将需要使用Dockerclient的用户加入docker用户组

sudogpasswd -a ${USER} docker

 

  • 网络相关问题

 

当你在网关背后需要通过代理连接docker的index数据库时,可以手动加上http_proxy环境变量来启动dockerdaemon

 

HTTP_PROXY=http://proxy_server:port docker
-d &

 

更好的做法是修改/etc/default/docker ( on ubuntu ), 添加 exporthttp_proxy=proxy_server:port

 

同样,docker container 如果无法自动正确的从host环境中获得DNS的配置,则需要手动指定DNS服务器地址,这可以通过 docker
-run --dns=xxx 来实现,也可以修改/etc/default/docker 添加例如 DOCKER_OPTS="-dns 8.8.8.8"

 

  • 特权模式

 

在正常情况下 在container内部你没有权限操作device设备,而当前版本中,container内部部分文件例如/etc/hosts;/etc/hostname;
/etc/resolve.conf等文件是动态通过mount动态以只读的形式加载上来的,理论上说你应该找到合适的方法去保证这些自动生成并加载的文件的正确性 (例如 通过--dns 设置 resolve.conf
),但是如果由于特殊原因你需要手动修改,那么你可以通过特权模式启动 docker client :docker
run --privileged ,然后你可以卸载这些文件,自己再创建新的版本

 

  • 过多的层级依赖关系

 

以Layer的方式实现APP和相关library的cheap
reuse和fast update是Docker的关键所在,不过受目前AUFS文件系统的限制,默认Layer的层级最多只能达到127(曾经只有42),在实际使用中有多种情况可能导致你的container的层级关系快速增长到这个极限值,撇开这么多layer叠加以后AUFS的效率不谈,更多情况下是你无法再更新构建你的image了

 

  1. 使用Dockerfile构建Image时,每条指令都会给最终的Image增加一层layer依赖关系.
  2. 以修改,提交,再修改再提交的方式不停的调整,更新你的Image
  3. 从仓库中下载的别人的Image已经包含众多的层级依赖关系,而你需要进一步更新以创建你自己的版本

 

前两者在一定程度上还是你自己可能把控的,最后一种情况就没办法了。这个问题最终必将影响Docker的实际可用性,目前的解决方案包括:

 

  • 使用Dockerfile时,尽可能合并多个操作:例如使用 "&&" 或 ";" 合并运行多个shell命令;将多个shell命令写成脚本,在dockerfile中添加并运行这个脚本
  • 通过Export再Import
    Image,丢弃所有历史信息和依赖关系,创建一个全新的image

 

将来可能的解决方案包括:

 

  • 在Dockerfile中添加对多步操作的合并提交的支持
  • 外部的image Flat工具的支持,目标是能够保留历史信息等
  • 非AUFS的其它Storage解决方案

 

 

 

Future development

 

虽然Docker目前默认使用LXC和AUFS,但是Docker的核心思想本身,并不强制绑定这两者,0.8版本已经可以使用BTRFS,而整个Docker框架也改成了插件式的架构,便于添加替换各个功能模块

 

 

 

例如更多的Storage方案的支持,规避AUFS当前的问题,除了LXC以外更多的虚拟化方案等

时间: 2024-12-30 23:44:41

快速理解Docker的相关文章

Docker Machine快速安装Docker环境(二)

什么是Docker Machine? Machine是一个简化安装Docker环境的工具.怎么简化法,例如,在ubuntu安装一个docker环境要按照U这个系统配置教程来装,哪天又换了CentOS系统,又要按照这个系统配置教程装.市场上主流Linux系统版本很多,每次安装岂不有些麻烦.使用Machine工具就简单很多,一两条命令即可在主流Linux系统上安装Docker环境,用户不用考虑什么操作系统. 另一方面,Machine还具备Docker工具管理什么虚拟化技术,Generic驱动默认管理

【Docker官方文档】理解Docker

本文讲的是[Docker官方文档]理解Docker,[编者的话]本文来自Docker的官方文档,详细介绍了Docker的体系结构.重要概念.内部工作机理等内容,推荐不了解Docker内部原理的同学阅读. 什么是Docker? Docker是一个用于开发.交付和运行应用的开放平台,Docker设计用来更快的交付你的应用程序.Docker可以将你的应用程序和基础设施层隔离,并且还可以将你的基础设施当作程序一样进行管理.Docker可以帮助你更块地打包你代码.测试以及部署,并且也可以减少从编写代码到部

[翻译] 理解Docker容器网络

理解Docker容器网络 翻译自Understand Docker container networks 如果你需要创建互相协作并安全的web应用,使用Docker的网络的特性可以帮你解决.定义上,网络为容器了完全的隔离性,所以,控制你的应用程序运行所在的网络很重要.Docker的网络特性变提供了你对网络的控制能力. 这篇文章将提供Docker原生的网络的行为的概览,Docker默认会创建哪些网络,以及创建自定义的自有的网络,以及在单节点或者集群上创建自定义的网络需要哪些资源. 默认网络(Def

socket快速理解

相信大家都知道,socket用于描述IP地址和端口,是一个通信链的句柄.但是如何使用它,它是如何通信的. 直接看代码或者函数说明可能有点乱.在这里给出一个直观清晰的解释.下图是tcp套接字的工作流程.然后再用类比说明让你快速明白工作流程.  服务器端: 获取电话线        socket() 分配电话号码    bind() 等着电话打来    listen() 接听电话            accept() 相互交谈           read()/write() 挂断电话      

深入理解Docker Volume(二)

本文讲的是深入理解Docker Volume(二),[编者的话]继上一篇文章深入理解Docker Volume(一)后,DockerOne翻译了深入理解Volume的第二篇文章.本文重点介绍了两种创建Volume方式的异同以及使用docker run命令创建Volume时,指定主机目录与不指定主机目录的区别. Docker的难点之一就是Volume的使用,这也是很多人都会问到的问题.所以让我们一起来深入看看Docker Volume是如何工作的. 很多人都对Volume有一个误解,他们认为Vol

学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践

原文 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践 感谢大家在上一篇 学一点Git--20分钟git快速上手 里的踊跃发言.这里再次分享干货, 简单介绍mysql双机,多机异地热备简单原理实战. 双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一 致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换到另一个. 2. 可以做负载均衡,可以将请求分摊到其中任何一台上

如何快速理解设计模式?

问题描述 如何快速理解设计模式? 设计模式那么多,要怎么快速理解呢?又要在什么情况下使用.求大神指教. 解决方案 设计模式快速理解不了,这个东西需要不断的琢磨,没有一定的开发经验想快速理解也只能是理解的皮毛.相反,有过3年左右开发经验的,自然而然就能够理解. 解决方案二: 你做过很多项目后自然而然就会理解的,设计模式是快速理解不了的. 解决方案三: 这个是需要时间的,没有太多的捷径可走 解决方案四: 认认真真看懂23种模式的书籍和代码. 网上有很多这样的资料,尤其要找代码的资料 解决方案五: 要

10张图带你深入理解Docker容器和镜像

本文讲的是10张图带你深入理解Docker容器和镜像,[编者的话]本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(container)和镜像(image)之间的区别,并深入探讨容器和运行中的容器之间的区别. 当我对Docker技术还是一知半解的时候,我发现理解Docker的命令非常困难.于是,我花了几周的时间来学习Docker的工作原理,更确切地说,是关于Doc

【理解Docker】Docker与Vagrant的简单区别

本文讲的是[理解Docker]Docker与Vagrant的简单区别,[编者的话]本文翻译自Quora上的一个问题:Docker和Vagrant的区别,以及我们何时使用他们. Vagrant和Docker是两只不同的野兽. Docker是一个由shell层和management层两部分组成的,用来构建并运行基于lxc的虚拟Linux容器. Docker的伟大在于:它是轻量级的(因为它依赖于共享内核的Linux容器),[以及与它的分布无关].虽然所有实例之间的内核共享(但与主机以及互相之间都是隔离