在计算机技术发展的早期,几乎全部的程序都是在开发后部署到一台或是少数几台服务器上的。那时的程序也几乎都是集全部模块和运行时环境为一身的“全栈应用”,虽然这些程序能够基于一套良好、完善的协议栈 ( 譬如一套完整的 MVC 架构 ) 进行开发,但再好的架构也没法让应用服务在这种体系下快速发展。html
随着互联网的极速发展,应用程序的功能愈来愈丰富,而须要迭代的速度要求也愈来愈高,为了实现这些目标,应用的开发逐渐趋向服务化甚至微服务化。每一个应用程序都有其对应依赖的操做系统或者其余程序,而在将应用程序细分为不一样的微服务或者是其余形式的微小应用模块后,解决这种依赖问题会愈发显得棘手。有的应用运行环境特别复杂,搭建过程也极易出错,这都是让开发、测试、运维人员焦头烂额的地方。更多时候,开发者们确定更愿意将他们宝贵的时间用在实际的开发中,而不是纠缠着应用运行环境的问题上。git
同时,因为物理硬件的更新迭代速度已经难以追赶互联网的脚步,应用的部署逐渐转向集群化。应用模块的数量乘上每一个应用所部署的机器的数量,会是一个很是庞大的数字。相信全部的开发或者运维都不会愿意把时间浪费在逐一搭建服务器环境这种重复的劳动上。docker
这些变化都对应用的开发、部署带来了不小的挑战。编程
我想不少读者已经想到了应对这些挑战的办法了,没错,那就是虚拟化技术。经过虚拟化技术可让环境的搭建变得更加的容易,对咱们快速部署分布式应用服务体系提供了极大的便利。安全
进而言之,若是咱们把管理环境的复杂度,更轻量级的虚拟化实现等更加实际的问题考虑进去,容器技术天然成了虚拟化技术中最佳的选择项。bash
若是说在分布式部署中应用容器技术是一个方向,那么 Docker 就是在这个方向上跑得最快也最完美的运动员了。Docker 不论从实现容器技术的完整性上来讲,仍是从上手易用性来讲,都是可圈可点的。服务器
好了,这里我要穿插一下推荐 Docker 的缘由了。咱们使用 Docker 的目的其实很简单,就是利用它的全面性和易用性来提高咱们的工做效率。了解了这个目的,我想你们会更容易理解不少场合 Docker 能派上用场的缘由。固然,经过这个道理,你也就明白了为何我会说 Docker 是一门新时代开发者必须掌握的技术了。毕竟全部的老板都但愿找到会得多、干活快的优秀开发者 ( 亦或者说,会的多、干活快是优秀开发者所必备的品质 )。网络
再怎么从理论上说快也是很难服众的,是骡子是马拉出来“跑个分”就知道了。Docker 官方对 Docker 在工做上带来的提高作了调查研究,分别从工做效率的提高和技术设计投入的减小等方面数据化了 Docker 所作出的突出贡献。架构
让咱们先来从一张 Docker 官方提供的架构图来看看 Docker 对容器结构的设计。 运维
举个具体的例子,在常见的虚拟机实现中,咱们要搭建一套 LAMP 结构的服务,咱们一般会创建一个虚拟机,在虚拟机中安装上 Linux 系统,以后分别安装 Apache、MySQL 和 PHP。而在 Docker 里,最佳的实践是分别基于 Apache、MySQL 和 PHP 的镜像创建三个容器,分别运行 Apache、MySQL 和 PHP ,而它们所在的虚拟操做系统也直接共享于宿主机的操做系统。 若是咱们将 Docker 的轻量级容器实现和虚拟机的一些参数进行对比,更容易获得结果。
属性 | Docker | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
硬盘使用 | MB 级 | GB级 |
性能 | 接近原生 | 较低 |
普通机器支撑量 | 数百个 | 几个 |
虽然这里只列出了一些 Docker的优点项,但这些优点都是对咱们开发中环境搭建和使用极其有帮助的内容。就拿启动速度来讲,咱们在开发中显然不肯意调整环境或更新代码后要等待几分钟来让其生效,Docker 秒级的启动速度几乎让咱们感知不到咱们对环境作了什么改动。而像虚拟机占用大量操做系统资源,致使咱们本地开发使用电脑过慢 ( 有时候不得不将环境搭建在另外的机器上,但这显然在代码编写到运行自测的过程当中增长不少工做量 ) 等问题,也容易获得解决。
从理论上咱们已经知道 Docker 可以为咱们的工做带来巨大的便利,那么将其放于实践中,咱们应该如何正确的使用它呢?这里我摘录整理了一段来自 Docker 官方文档的指导意见,但愿可以对你们的实践提供参考。
使用 Docker 后,开发者可以在本地容器中获得一套标准的应用或服务的运行环境,由此能够简化开发的生命周期 ( 减小在不一样环境间进行适配、调整所形成的额外消耗 )。对于整个应用迭代来讲,加入 Docker 的工做流程将更加适合持续集成 ( Continuous Integration ) 和持续交付 ( Continuous Delivery )。
举个具体的例子:
基于容器技术的 Docker 拥有很高的跨平台性,Docker 的容器可以很轻松的运行在开发者本地的电脑,数据中心的物理机或虚拟机,云服务商提供的云服务器,甚至是混合环境中。
同时,Docker 的轻量性和高可移植性可以很好的帮助咱们完成应用的动态伸缩,咱们能够经过一些手段近实时的对基于 Docker 运行的应用进行弹性伸缩,这可以大幅提升应用的健壮性。
Docker 的高效和轻量等特征,为替代基于 Hypervisor 的虚拟机提供了一个经济、高效、可行的方案。在 Docker 下,你能节约出更多的资源投入到业务中去,让应用程序产生更高的效益。同时,如此低的资源消耗也说明了 Docker 很是适合在高密度的中小型部署场景中使用。
在 Docker 体系里,有四个对象 ( Object ) 是咱们不得不进行介绍的,由于几乎全部 Docker 以及周边生态的功能,都是围绕着它们所展开的。它们分别是:镜像 ( Image )、容器 ( Container )、网络 ( Network )、数据卷 ( Volume )。
镜像 ( Image ) 这个概念相信你们不会陌生,由于它是其余虚拟化技术 ( 特别是虚拟机 ) 中经常被使用的一个概念。所谓镜像,能够理解为一个只读的文件包,其中包含了虚拟环境运行最原始文件系统的内容。
固然,Docker 的镜像与虚拟机中的镜像仍是有必定区别的。首先,以前咱们谈到了 Docker 中的一个创新是利用了 AUFS(参考文档:www.cnblogs.com/sammyliu/p/… 做为底层文件系统实现,经过这种方式,Docker 实现了一种增量式的镜像结构。
另外,因为这种结构,Docker 的镜像实质上是没法被修改的,由于全部对镜像的修改只会产生新的镜像,而不是更新原有的镜像。
容器 ( Container ) 就更好理解了,在容器技术中,容器就是用来隔离虚拟环境的基础设施,而在 Docker 里,它也被引伸为隔离出来的虚拟环境。
若是把镜像理解为编程中的类,那么容器就能够理解为类的实例。镜像内存放的是不可变化的东西,当以它们为基础的容器启动后,容器内也就成为了一个“活”的空间。
用更官方的定义,Docker 的容器应该有三项内容组成:
对于大部分程序来讲,它们的运行都不会是孤立的,而是要与外界或者更准确的说是与其余程序进行交互的,这里的交互绝大多数状况下指的就是数据信息的交换。网络通信是目前最经常使用的一种程序间的数据交换方式了。
因为计算机网络领域拥有相对统一且独立的协议等约定,其跨平台性很是优秀,全部的应用均可以经过网络在不一样的硬件平台或操做系统平台上进行数据交互。特别是在分布式云计算的时代,应用或服务间的通信更是充分依赖于网络传输,因此天然拥有一套完善的网络体系支撑,是承载应用运行所必须的基础设施。
在 Docker 中,实现了强大的网络功能,咱们不但可以十分轻松的对每一个容器的网络进行配置,还能在容器间创建虚拟网络,将数个容器包裹其中,同时与其余网络环境隔离。
另外,利用一些技术,Docker 可以在容器中营造独立的域名解析环境,这使得咱们能够在不修改代码和配置的前提下直接迁移容器,Docker 会为咱们完成新环境的网络适配。对于这个功能,咱们甚至可以在不一样的物理服务器间实现,让处在两台物理机上的两个 Docker 所提供的容器,加入到同一个虚拟网络中,造成彻底屏蔽硬件的效果。
正是由于拥有强大的网络功能,才能让咱们制造健壮的 Docker 应用体系。
除了网络以外,文件也是重要的进行数据交互的资源。在以往的虚拟机中,咱们一般直接采用虚拟机的文件系统做为应用数据等文件的存储位置。然而这种方式其实并不是彻底安全的,当虚拟机或者容器出现问题致使文件系统没法使用时,虽然咱们能够很快的经过镜像重置文件系统使得应用快速恢复运行,可是以前存放的数据也就消失了。
为了保证数据的独立性,咱们一般会单独挂载一个文件系统来存放数据。这种操做在虚拟机中是繁琐的,由于咱们不但要搞定挂载在不一样宿主机中实现的方法,还要考虑挂载文件系统兼容性,虚拟操做系统配置等问题。值得庆幸的是,这些在 Docker 里都已经为咱们轻松的实现了,咱们只须要简单的一两个命令或参数,就能完成文件系统目录的挂载。
可以这么简单的实现挂载,主要仍是得益于 Docker 底层的 Union File System 技术。在 UnionFS 的加持下,除了可以从宿主操做系统中挂载目录外,还可以创建独立的目录持久存放数据,或者在容器间共享。
在 Docker 中,经过这几种方式进行数据共享或持久化的文件或目录,咱们都称为数据卷 ( Volume )。
时至今日,Docker 生态已经远比它诞生之初要庞大许多,虽然咱们仍然习惯使用 Docker 这个名字去指代实现容器技术支持的软件,但显然更加容易与其余的概念产生混淆。这里咱们颇有必要对这个 Docker 中最核心的软件进行介绍,不只由于它在 Docker 生态中扮演着中心的地位,也由于它是咱们在开发中实实在在接触最多的东西。
目前这款实现容器化的工具是由 Docker 官方进行维护的,Docker 官方将其命名为 Docker Engine,同时定义其为工业级的容器引擎 ( Industry-standard Container Engine )。在 Docker Engine 中,实现了 Docker 技术中最核心的部分,也就是容器引擎这一部分。
docker daemon 和 docker CLI 虽然咱们说 Docker Engine 是一款软件,但实实在在去深究的话,它其实算是由多个独立软件所组成的软件包。在这些程序中,最核心的就是 docker daemon 和 docker CLI 这俩了。
全部咱们一般认为的 Docker 所能提供的容器管理、应用编排、镜像分发等功能,都集中在了 docker daemon 中,而咱们以前所提到的镜像模块、容器模块、数据卷模块和网络模块也都实如今其中。在操做系统里,docker daemon 一般以服务的形式运行以便静默的提供这些功能,因此咱们也一般称之为 Docker 服务。
一般来讲,咱们是采用在控制台或者命令行输入命令来控制 docker daemon 的,由于这样很酷也更容易适应那些有或者没有图形界面的操做系统。
那么问题来了,若是咱们在控制台中编写一个 HTTP 请求以借助 docker daemon 提供的 RESTful API 来操控它,那显然是个费脑、费手又费时间的活儿。因此在 Docker Engine 里还直接附带了 docker CLI 这个控制台程序。
整体上来讲,咱们能够将 Dockerfile 理解为一个由上往下执行指令的脚本文件。当咱们调用构建命令让 Docker 经过咱们给出的 Dockerfile 构建镜像时,Docker 会逐一按顺序解析 Dockerfile 中的指令,并根据它们不一样的含义执行不一样的操做。
若是进行细分,咱们能够将 Dockerfile 的指令简单分为五大类。
docker pull gitlab/gitlab-ce
复制代码
sudo docker run --detach \
--hostname fhero.me \
--publish 443:443 --publish 80:80 --publish 22:22 \
--name gitlab \
--restart always \
--volume ~/gitlab/config:/etc/gitlab \
--volume ~/gitlab/logs:/var/log/gitlab \
--volume ~/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest
复制代码
由于部署在本地,又指定了fhero.me做为域名,因此在/etc/hosts配置下,这样能够经过域名访问gitlab。
docker run \
-u root \
--rm \
-d \
-p 8081:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean
复制代码
Jenkins新建项目中源码管理使用Git时遇到以下问题: Failed to connect to repository : Error performing command: git ls-remote -h …. 须要查看服务器上是否已经安装git.
从起启动Jenkins时输入以前的用户名和密码,居然提示我无效的用户名或密码,最后只能用强攻了,将用户名和密码去掉,直接进入到Jenkins。
swam建立集群:mp.weixin.qq.com/s/cKRAs-H8p…?