前言
从本节开始,咱们迎来了又一个新朋友 Docker ,使用过VMware的朋友应该知道,在我们的Windows系统上安装VMware之后可以开启多台虚拟机,每一台虚拟机被初始化之后都会虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程,但是这种方式有几个弊端。
其一,虚拟机会占用实际的物理磁盘空间,资源占用多
其二,冗余步骤多,每一台虚拟机上都需要安装OS(操作系统)
其三,启动速度特别慢,最少也得30-40s
其四,在本机上开发出来的一款应用程序不见得在另一台电脑或者虚拟机上能够正常运行!
基于以上,咱们的Docker诞生了!而且是完全碾压传统的虚拟化方式!
什么是Docker
先带大家简单的认识以下我们的新朋友,咱们来看看Docker的官方定义
Docker是一个开项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会,遵从了Apache2.0协议,项目代码在GitHub上进行维护。Docker自开源后受到广范的关注和讨论,以至于dotCloud公司后来都改名为Docker
Inc。RedHat已经在其RHEL6.5中集中支持Docker;Google也在其PaaS产品中广泛应用。Docker的目标是实现经量级的操作系统虚拟化解决方案。Docker的基础是Linux容器(LXC)等技术。在LXC的基础上Docker进行了进一步的封装,让用户不需要关心容器的管理,使得操作更加简单。用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。
大家看Docker的官方图标,下面是不是一头 “蓝鲸” ? “蓝鲸” 的上边就是一个个集装箱,可以说Docker的Logo很形象表达了这款应用的功能了,这么说大家肯定不懂了,不要紧,咱们接着往下看。
Docker的设计思想
Docker的设计思想来自于集装箱,透过刚才Docker的Logo我们也能大概猜出来设计者的意图,我们来想想集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来对吧!
并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。我们当然不会将装衣服的集装箱和装医药类的物品混在一起吧?在各个集装箱相互间不受影响的情况下,承载着这些货物运行,并且这些集装箱仅仅需要依赖 “蓝鲸” 而不需要其他的承运设施就可以被带到世界各地,这其实就是Docker的设计理念!
其实我们放宽了眼界再看,我们的云计算就好比大货轮。Docker就是集装箱。
刚刚说的都是一些理念,那么结合实际应用运行问题,我们该怎么看待呢?
1)不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。Docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,开销小老板就高兴了…
2)你开发软件的时候用的是Ubuntu,但是运维管理的都是CentOs,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转CentOs的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,CentOs不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有Docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的Docker就可以了。而且部署速度快,因此Docker的诞生也意味着开发、运维和测试的春天到了!(真的少扯很多皮…)
3)在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,但使用Docker部署的话,这些内存就会充分利用起来,因为Docker使用的是容器技术,每一个容器所占的空间会非常小(相对于传统的虚拟机所占用的内存)。
结合我们刚才讲的内容,咱们来对比下Docker和传统的虚拟技术,之前我们提到Docker直接碾压传统的虚拟技术可不是吹的,为了印证这一点,咱们就来从结构分析下为何Docker更胜一筹。
咱们先来看下面这张图,左边是传统虚拟方式,右边是Docker。大家仔细对比,是不是发现Docker比传统的Virtual Machine少了Guest OS?
这里给大家科普下,目前我的电脑安装的是Windows 10 操作系统,那么Host OS就是Win 10,我的这台主机就是宿主机,我使用VMware虚拟出来的安装CentOs操作系统的主机就是虚拟机,虚拟机在底层其实就是一个普通的文件夹,那么此时Guest OS就是CentOs了(或者统称之为Linux,CentOs只是Linux的一个发行版),虚拟机实质上是 “寄生” 在宿主机上的,所以称之为 “寄生机” 也不为过。
也就是说传统的Virtual Machine上的应用想要跑起来,必须得自己安装一套操作系统,而Docker则不一样了,在Docker上的应用仅仅只需要它所依赖的类库、可以执行文件等等,而操作系统和环境已经被Docker搭建好了,根本不需要我们额外的耗时间精力做一些冗余的(例如安装操作系统)事情。加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个Docker容器只需要几秒钟。
因此Docker相比于传统虚拟化方式具有更多的优势:
启动快慢:Docker启动快速属于秒级别。虚拟机通常需要几分钟去启动
资源占用率:Docker占用的资源更少, Docker在操作系统级别进行虚拟化, Docker容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化。
系统利用率:Docker更轻量, Docker的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高,普通的机器上最多只能运行几十个虚拟器,而Docker使用容器技术,使得一台PC上可以承载上千个容器!
快速创建和删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
交付和部署:Docker可以进行更快的应用交付和部署。传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。
系统运维简化:应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。
更快的扩容及缩容也是Docker的特性之一。随着微服务架构和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% 高可用,保证业务连续性。
如果实在是记不住上面的内容,掌握下面的也行!
特性 | 容器 | 虚拟机 |
---|---|---|
启动耗时 | 秒级 | 分钟级 |
硬盘占用 | 一般为MB(200MB) | 一般为GB(10G) |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般是几十个 |
Docker安装
咱口说不如实干!直接来安装一款Docker试试… 用过的都说好!
第一步:确定当前是CentOs7的版本
官方建议最好是CentOs 7.0以上版本
第二步:yum安装gcc相关
#确保centos7能上外网
yum -y install gcc
yum -y install gcc-c++
第三步:Docker安装并启动
yum install docker #安装docker
systemctl start docker #启动docker
安装成功之后可以使用命令docker version
查看docker版本
第四步:测试运行hello-world
接下来我们尝试从docker上下载镜像,对!你没看错!hello-world
在docker上也是一个镜像
docker run hello-world
大家在https://hub.docker.com上搜索hello-world
就可以找到这个镜像
因为咱们是刚安装下载的docker,所以本地没有hello-world这个镜像,因此会先下载一个hello-world的镜像,并在容器内运行,当然,如果之前已经下载过这个镜像,就不用去Docker的中央仓库中去下载这个镜像。
第五步:测试运行Nginx
大家还记得咱们之前在 Marco’s Java【Ngnix入门(一) 之Nginx下载安装】 中使用Linux安装Nginx吗?又是下载jar包,又是解压,又是编译… 相当复杂,那么从今天开始,咱们所有的应用的安装基本上都是一条指令搞定!
不信你看!
#将80端口映射为8080,或者80:80还是原先的80端口,不可以不写。
docker run -p 8080:80 -d docker.io/nginx
整个过程会非常慢… 毕竟Docker的服务器在国外,跟Maven一个尿性…
Nginx跑起来后,咱们来访问看看http://192.168.144.132:8080/
看过我之前Nginx博文的朋友可能会有疑问了,之前咱们访问Nginx主页的时候,并没有在后面加端口号8080
啊?而且8080
不是tomcat的默认端口号吗?难道跟tomcat有啥联系?
首先这里有个误区,就是我们设置的port端口号和应用默认的端口号是没有直接联系的,因为port是可以被改变的,唯一要注意的是,假设我们一个应用暂用了端口号8080,那么此时如果安装了tomcat就需要修改默认的端口号,否则启动tomcat的时候会显示端口号被占用。此外,细心的朋友会发现我之前启动nginx的指令docker run -p 8080:80 -d docker.io/nginx
中有这么个部分8080:80
,这是啥意思呢?
很显然8080
就是刚才咱们url访问地址后的port,而80
就是nginx的默认端口,大家可以看下面这张图,当我们的Nginx镜像在Docker上生成一个运行时container时,将自己的端口告诉Docker,紧接着Docker就去注册单中帮Nginx注册了一个外部可以访问到的端口8080
,当外部的PC访问的url地址栏中的port为8080,会在Docker中映射为80,接着再通过80端口访问到Nginx,docker run -p 8080:80 -d docker.io/nginx
本质上就是注册端口号这个操作。
Docker加速配置
为什么这里要讲加速配置呢?因为接下来咱们要安装的tomcat镜像实在是太大了,从Docker Hub仓库直接下载会非常慢,刚才大家安装Nginx的时候应该体验过这酸爽的感觉…
欸… tomcat不是只有10几M吗?怎么会很大?相信肯定会有朋友有这个疑问。注意了,我这里说的是tomcat镜像很大,至于原因嘛… 大家先看下面这张图。
像不像一个洋葱?(当然你硬要说这是蛋我也不会反驳… ) 准确来说是洋葱结构,这个洋葱结构就是Docker中常见的镜像的结构,大家还记得我们之前讲Maven的时候提到的jar包之间的依赖关系吗?镜像也不例外,镜像与镜像之前也存着相互依赖的关系,很明显从上面的中可以看出,tomcat镜像是要依赖于JDK的,而JDK依赖于Linux的内核的,实质上这种关系在Docker中亦称之为 “继承”。而且基本上每一个镜像都是需要依赖Linux kernel的,因为打从一开始Docker就是用linux开发的,虽然现在已经有了Window版本,但很显然在实际开发中我们并不会去使用它!
好啦,说了这么多,咱们就来配置加速器吧!
首先打开并编辑配置文件docker/daemon.json
vi /etc/docker/daemon.json
在配置文件中加入以下配置,这个配置就像一面 “镜子” ,如果不配置,那么我们所有的镜像都是在Docker Hub上拉取下来的,配置之后,镜像拉取的地址就变成了aliyun,所以在此之前建议注册一个阿里云账户,学习过Maven,应该不难理解这个配置的含义。
{
"registry-mirrors": ["https://32xw0apq.mirror.aliyuncs.com"]
}
############### 配置完成务必执行以下操作,否则配置不会生效 ###################
[root@localhost ~]# systemctl daemon-reload #重新加载daemon.json配置文件
[root@localhost ~]# systemctl restart docker#重启docker
接着咱们再执行以下命令从Docker Hub上拉取tomcat:8.5
的镜像
docker pull tomcat:8.5
大家尝试操作下,会发现真的快了许多!不得不说,马云爸爸的东西还是好用啊!