从这里起航
本系列有感于《第一本Docker书》,当我拿到这本书时感觉如获至宝。
为了培养自己对docker的兴趣,不断鞭策自己,我决定开始写这个系列的博客——《站在蓝鲸的背上思考》
在之后的岁月里,我将不定时的更新这个系列,希望能给正在阅读的您,以及涉足自动化运维不深的我给予鼓励及帮助。
为啥要选择docker
Docker是一个能够把开发的应用程序自动部署到容器的开源引擎。由Docker公司的团队编写,基于Apache 2.0开源授权协议发行。
Docker在虚拟化的容器执行环境中增加了一个应用程序部署引擎。该引擎的目标就是提供一个轻量、快速的环境,能够运行开发者的程序,并方便高效地将程序从开发者的笔记本部署到测试环境,然后再部署到生产环境。Docker极其简洁,它所需的全部环境只是一台仅仅安装了兼容版本的Linux内核和二进制文件最小限的宿主机。而Docker的目标就是要提供以下这些东西
1.提供一个简单、轻便的建模方式:
Docker上手非常快,用户只需要几分钟,就可以把自己的程序“Docker化”(Dockerize)。Docker依赖于“写时复制”(copy-on-write)模型,使修改应用程序也非常迅速,可以说达到了“随心所至,代码即改”的境界。
随后,就可以创建容器来运行应用程序了。大多数Docker容器只需要1秒即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户可以尽可能充分地利用系统资源。
2.职责的逻辑分离:
使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境的一致性,从而降低那种“开发时一切正常,肯定是运维的问题”的风险。
3.快速、高效的开发生命周期:
Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。
4.鼓励使用面向服务的架构:
Docker还鼓励面向对象的架构和微服务架构。Docker推荐单个容器只运行一个应用程序或进程,这样就形成一个分布式的应用程序模型,在这种模型下,应用程序或服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。
Docker组件
- Docker客户端和服务端
- Docker是一个客户-服务端(C/S)架构的程序。Docker客户端只需向Docker服务器或守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。Docker提供了一个命令工具docker以及一整套RESTful API。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。
- Docker镜像
- 镜像是构建Docker世界的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的“构建”部分。镜像是基于联合(Union)文件系统的一种层式结构。由一系列指令一步一步构建出来的。例如:
- 添加一个文件
- 执行一个命令
- 打开一个端口
- 镜像是构建Docker世界的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的“构建”部分。镜像是基于联合(Union)文件系统的一种层式结构。由一系列指令一步一步构建出来的。例如:
- Registry
- Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营的公共Registry叫做Docker Hub。用户可以在Docker Hub上注册账号,并分享保存自己的镜像。你也可以在Docker Hub上保存自己的私有镜像。例如,包含源代码或是专利信息等需要保密的镜像,或是只在团队或组织内部可见的镜像。你甚至可以假设自己的私有Registry。在之后的随笔中会单独写一篇关于如何构建私有Registry的文章一共大家参考。私有的Registry可以受到防火墙的保护,将镜像保存在防火墙后面,以满足一些组织的特殊需求。
- Docker容器
- Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或服务打包放进容器即可。我们刚刚提到,容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。总结起来,Docker容器就是:
- 一个镜像格式;
- 一系列标准的操作;
- 一个执行环境。
- 每个容器都包含一个软件镜像,也就是容器的“货物”,而且与真正的货物一样,容器里的软件镜像可以进行一些操作。例如,镜像可以创建、启动、关闭、重启以及销毁。
- 和集装箱一样,Docker在执行上述操作时,并不关心容器中到底塞进了什么,它不管里面是Web服务器,还是数据库,或者是应用程序服务器什么的。所有容器都按照相同的方式将内容“装载”进去。Docker也不关心你要把容器运到何方:你可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,再把容器部署到Amazon EC2主机的集群中去。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分发,并且尽量通用。
- 使用Docker,我们可以快速构建一个应用程序服务器、一个消息总线、一套实用工具、一个持续集成测试环境(在后面的随笔中将介绍docker如何与jenkins结合,实现持续集成)或者任意一种应用程序、服务或工具。我们可以在本地构建一个完整的测试环境,也可以为生产或开发快速复制一套复杂的应用程序栈。可以说,Docker的应用场景相当广泛。
- Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或服务打包放进容器即可。我们刚刚提到,容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。总结起来,Docker容器就是:
我们能用Docker做什么
我们可以通过以下几个维度来了解Docker可以为我们做什么。隔离性、标准性
- 加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建、运行并分享Docker容器。容器可以在开发环境中构建,然后轻松地提交到测试环境中,并最终进入生产环境。
- 能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。这一点在面向服务架构和重度依赖微型服务的部署中尤其实用。
- 用Docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启动一个用于测试的容器。
- Docker可以让开发者现在本机上构建一个复杂的程序或架构来进行测试,而不是一开始就在生产环境部署、测试。
- 构建一个多用户的平台及服务(PaaS)基础设施
- 为开发、测试提供一个轻量级的独立沙盒环境,或者将独立的沙盒环境用于技术教学,如Unix Shell的使用、编程语言教学。
- 提供软件即服务(SaaS)应用程序,如Memcached即服务。
- 高性能、超大规模的宿主机部署。
Docker的技术组件
Docker可以运行于任何安装了现代Linux内核的x64主机上。一个原生的Linux容器格式,Docker中称为libcontainer,或者很流行的容器平台lxc。libcontainer格式现在是Docker容器的默认格式。
Linux内核的命名空间(namespace),用于隔离文件系统、进程和网络。
- 文件系统隔离:每个容器都有自己的root文件系统
- 进程隔离:每个容器都运行在自己的进程环境中
- 网络隔离:容器间的虚拟网络接口和IP地址都是分开的。
- 资源隔离和分组:使用cgroups(即control group,Linux的内核特性之一)将CPU和内存之类的资源独立分配给每个Docker容器。
- 写时复制:文件系统都是通过写时复制创建的,这就意味着文件系统是分层的、快速的,而且占用的磁盘空间更小。
- 日志:容器产生的STDOUT、STDERR和STDIN这些IO流都会被收集并记入日志,用来进行日志分析和故障排除。
- 交互式shell:用户可以创建一个伪tty终端,将其连接到STDIN,为容器提供一个交互式的shell。