Docker简介---www

Docker出现的原因

软件开发最大的麻烦事之一,就是环境配置.用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来?
用户必须保证两件事:操作系统的设置,各种库和组件的安装.只有它们都正确,软件才能运行.
举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量.
 
如果某些老旧的模块与当前环境不兼容,那就麻烦了.
开发者常常会说:"它在我的机器可以跑了"(It works on my machine),言下之意就是,其他机器很可能跑不了.
 
环境配置如此麻烦,换一台机器,就要重来一次,旷日费时.
很多人想到,能不能从根本上解决问题,软件可以带环境安装?
也就是说,安装的时候,把原始环境一模一样地复制过来.
 

虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案.
它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统.
应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,
而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响.
 
虽然用户可以通过虚拟机还原软件的原始环境.但是,这个方案有几个缺点:
(1)资源占用多
虚拟机会独占一部分系统资源,它运行的时候,其他程序就不能使用这些资源了.
哪怕虚拟机里面的应用程序真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行.
(2)冗余步骤多
虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录等, 操作繁琐.
(3)启动慢
启动操作系统需要多久,启动虚拟机就需要多久. 可能要等几分钟,应用程序才能真正运行.
 
 

Docker 出现的背景

 
虽然虚拟机解决了带环境安装的问题, 不过在公司日常的研发和项目场景中,以下情况仍普遍存在:
A. 个人开发环境为了做大数据相关项目,需要安装一套大数据集群,常见的做法是在自己电脑里搭建3台与大数据版本对应的虚拟机,把大数据集群装起来后,考虑到以后很有可能还要使用一个干净的大数据集群,为了避免以后重复安装环境,通常会对整套大数据集群做一个备份,这样电脑里就有6个虚拟机镜像了。另外,后面在学习其他技术时,比如学习Ambari大数据集群,那么为了不破坏已有的虚拟机环境,又要重新搭建3台虚拟机,本机磁盘很快被一大堆的虚拟机镜像占满。
 
B. 公司内部开发环境公司里往往会以小团队的方式来做项目,一般由运维部门从他们管理的服务器资源中分配出虚拟机供团队内部开发测试使用。
比如做一个与机器学习相关的项目:
• 小明在运维部门分配的虚拟机上搭建了一套Ambari集群,拿来跑大数据相关业务
• 小刚用python3写了一个机器学习算法,放到虚拟机上运行发现虚拟机里是python2,算法不兼容,于是把虚拟机里的python版本升级了,算法跑通了,但Ambari用到python的部分功能可能就报错了
• 小李开发了应用,放到虚拟机上启动tomcat,发现虚拟机里的是OpenJDK,导致tomcat起不来,于是又安装了一个JDK,这时候可能Ambari里的Java代码可能就报错了
• 小赵想利用服务器资源做性能测试,发现虚拟机严重削减了性能,最终还是直接找物理机来跑测试,破坏了物理机原来的环境
• 做完项目后,这些虚拟机上安装的东西往往变得没用了,下个项目组来还是得新申请虚拟机重新部署软件
 
C. 开发/测试/现场环境研发人员在开发环境里写好了代码做好测试后,提交给测试部门,测试人员在测试环境跑起来发现有BUG,研发人员说在开发环境没这个BUG,和测试人员多次扯皮解决BUG后发布版本. 在生产环境部署后,又发现有BUG,这下又到工程人员和测试人员扯皮... 有时候为了兼容特殊的现场环境,还需要对代码进行定制化修改,拉出分支,这样导致了每次到现场升级都是一场噩梦
 
D. 升级或迁移项目在每次发版本要升级到现场时,如果现场起了多个tomcat应用,那么需要对每个tomcat都先停掉,替换war包,然后再起起来,轮流着做,不仅繁琐而且很容易出错,如果遇到升级后出现严重BUG,还要手工做回退。另外,如果项目想上云,那么在云上部署后要重新进行一轮测试,如果后面考虑其他云厂商,可能相同的测试还要再进行一次(比如更换了数据存储组件),费时费力。
 
总结以上列举的场景,他们存在的一个共同的问题是:没有一种既能够屏蔽操作系统差异,又能够以不降低性能的方式来运行应用的技术,来解决环境依赖的问题。
 
Docker解决了这些问题。
 

Docker 是什么

 
Docker 是一种应用容器引擎。
 

什么是容器

 
Linux系统提供了Namespace和Cgroup技术实现环境隔离和资源控制
其中Namespace是Linux提供的一种内核级别环境隔离的方法,能使一个进程和该进程创建的子进程的运行空间都与Linux的超级父进程相隔离
注意Namespace只能实现运行空间的隔离,物理资源还是所有进程共用的
为了实现资源隔离,Linux系统提供了Cgroup技术来控制一个进程组群可使用的资源(如CPU、内存、磁盘IO等)
把这两种技术结合起来,就能构造一个用户空间独立且限定了资源的对象,这样的对象称为容器。
 
Linux Container是Linux系统提供的容器化技术,简称LXC,它结合 Namespace 和 Cgroup 技术为用户提供了更易用的接口来实现容器化。
LXC仅为一种轻量级的容器化技术,它仅能对部分资源进行限制,无法做到诸如网络限制、磁盘空间占用限制等。
 

什么是Docker

 
DotCloud公司结合LXC和以下列出的技术实现了Docker容器引擎,相比于LXC,Docker具备更加全面的资源控制能力,是一种应用级别的容器引擎。
• Chroot:在container里构造完整的Linux文件系统。Chroot 可以增进系统的安全性,限制使用者能做的事;
• Veth:在主机上虚拟出一张网卡与container里的eth0网卡进行桥接,实现容器与主机、容器之间的网络通信;
• UnionFS:联合文件系统,Docker利用该技术“Copy on Write”的特点实现容器的快速启动和极少的资源占用;
• Iptables/netfilter:控制container网络访问策略;
• Tc:该技术主要用来做流量隔离,限制带宽;(Tc 命令用于Linux内核的流量控制)
• Quota:该技术用来限制磁盘读写空间的大小;
• Setrlimit:该技术用来限制 container 中打开的进程数,限制打开的文件个数等
 
正是因为Docker依赖Linux内核的这些技术,至少使用3.8或更高版本的内核才能运行Docker容器,官方建议使用3.10以上的内核版本
 
Docker本质是宿主机上的一个进程,Docker通过Namespace实现资源隔离,通过Cgroup实现资源限制,
通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)
 
Docker

与openstack

 
 
Docker

与虚拟机

 
传统的虚拟化技术在虚拟机(VM)和硬件之间加了一个软件层Hypervisor,或者叫做虚拟机管理程序。Hypervisor的运行方式分为两类:
• 直接运行在物理硬件之上。如基于内核的KVM虚拟机,这种虚拟化需要CPU支持虚拟化技术;
• 运行在另一个操作系统。如VMWare和VitrualBox等虚拟机。
 
GuestOS 通过Hypervisor分享硬件,Guest OS发出的指令需要被Hypervisor捕获,然后翻译为物理硬件或宿主机操作系统能够识别的指令。
故像 VMWare和VirtualBox等虚拟机在性能方面远不如裸机,但基于硬件虚拟化的KVM约能发挥裸机80%的性能。
虚拟化的优点是不同虚拟机之间实现了完全隔离,安全性很高,并且能够在一台物理机上运行多种内核的操作系统(如Linux和Window)
缺点是每个虚拟机都很笨重,占用资源多而且启动很慢。
 
Docker引擎运行在操作系统上,是基于内核的LXC、Chroot等技术实现容器的环境隔离和资源控制
在容器启动后,容器里的进程直接与内核交互,无需经过Docker引擎中转,因此几乎没有性能损耗,能发挥出裸机的全部性能。
但由于Docker是基于Linux内核技术实现容器化的,因此使得容器内运行的应用只能运行在Linux内核的操作系统上。
 
目前在Window上安装的Docker引擎其实是利用了Window自带的Hyper-V虚拟化工具创建了一个Linux系统,容器内的操作实际上是使用这个虚拟系统实现的。
 

Docker 基本概念

 
(1) Docker镜像
Docker镜像就是一个只读的模板。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
镜像可以用来创建 Docker 容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,
用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
 
(2) Docker容器
Docker利用容器来运行应用。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、 删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的 Linux 环境(包括 root 用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。
* 注: 镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
 
(3) Docker仓库
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器( Registry)混为一谈,并不严格区分。
实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签( tag)。
仓库分为公开仓库( Public)和私有仓库( Private) 两种形式。
最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括阿里云, 腾讯云, 网易蜂巢, daocloud等。
当然,用户也可以在本地网络内创建一个私有仓库。
用户可以将自己的镜像使用push命令上传到公有或者私有仓库, 下次使用这个镜像时候, 只需要从仓库上 pull下来就可以了。
* Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。
 
(4) Docker引擎
创建和管理容器的工具,通过读取镜像来生成容器,并负责从仓库拉取镜像或提交镜像到仓库中
 

Dockerfile, Docker镜像, Docker容器之间的关系

 
Dockerfile重塑新镜像,定义的不仅仅是镜像中的磁盘文件;
Docker镜像是Dockerfile的产物,自底之上打包软件及其环境,是软件的交付品;
Docker容器是镜像的运行态体现,一切信息来源于镜像。
简单来讲,Dockerfile构建出Docker镜像,通过Docker镜像运行Docker容器。
 

Docker 与 JVM 类比

 
 
Docker的口号是“Build,Ship,and Run Any App,Anywhere”,也就是可以基于Docker构建、装载和运行应用程序,一次构建到处运行。
Java的口号是“Write Once,Run Anywhere”,即一次编写到处运行。
Java是基于JVM适配操作系统的特点来屏蔽系统的差异,Docker则是利用内核版本兼容性的特点来实现一次构建导出运行。
 
正如Java中如果应用代码使用了JDK10的新特性,基于JDK8就无法运行一样,如果容器内的应用使用了4.18版本的内核特性,那么在CentOS7(内核版本为3.10)启动容器时,虽然容器能够启动,但里面应用的功能是无法正常运行的,除非把宿主机的操作系统内核升级到4.18版本。
 

Docker

的使用场景
Docker作为一种轻量级的虚拟化方案,应用场景十分丰富,下面收集了一些常见的场景:
• 使用系统镜像创建容器,当作虚拟机来使用,相比于传统虚拟机,启动速度更快,资源占用更少,可以启动大量的操作系统容器,方便进行各种测试;
 
• 作为云主机使用结合Kubernetes这样的容器管理系统,可以在大量服务器上动态分配和管理容器
在公司内部,甚至可以取代VMWare这样的虚拟机管理平台,使用Docker容器作为云主机使用;
 
• 应用服务打包在Web应用服务开发场景,可以把Java运行环境、Tomcat服务器打包为一个基础镜像,
在修改了代码包后加入到基础镜像来构建一个新的镜像,能很方便的升级服务和控制版本;
 
• 容器云平台CaaSDocker的出现,使得很多云平台供应商开始提供容器云的服务,简称容器即服务CaaS,以下对比一下IaaS、PaaS和SaaS:
IaaS(基础设施即服务):提供虚拟机或者其他基础资源作为服务提供给用户。
用户可以从供应商那里获得虚拟机或者存储等资源来装载相关的应用,同时这些基础设施的繁琐的管理工作将由IaaS供应商来处理。
其主要的用户是企业的系统管理员和运维人员;
 
PaaS(平台即服务):把开发平台作为服务提供给用户。
用户可以在一个包括SDK,文档和测试环境等在内的开发平台上非常方便地编写应用,而且不论是在部署,或者在运行的时候,
用户都无需为服务器、操作系统、网络和存储等资源的管理操心,这些繁琐的工作都由PaaS供应商负责处理。其主要的用户是企业开发人员。
 
SaaS(软件即服务):将应用作为服务提供给客户。
用户只要接上网络,并通过浏览器,就能直接使用在云端上运行的应用,而不需要顾虑类似安装等琐事,并且免去初期高昂的软硬件投入。
SaaS主要面对的是普通的用户。
 
CaaS(容器即服务):完成IaaS和PaaS两个层级的功能。
相对于传统的IaaS和PaaS服务,CaaS对底层的支持比PaaS更灵活,而对上层应用的操控又比IaaS更容易。
同时因为Docker是比VM更细粒度的虚拟化服务,所以能够对计算资源做到更高效的利用。CaaS可以部署在任何物理机,虚拟机或IaaS云之上。
 
 
• 持续集成和持续部署互联网行业提倡敏捷开发,持续集成部署CI/CD便是最典型的开发模式。
使用Docker容器云平台,就能实现从代码编写完成推送到Git/SVN后,自动触发后端CaaS平台将代码下载、编译并构建成测试Docker镜像,
再替换测试环境容器服务,自动在Jenkins或者Hudson中运行单元/集成测试,测试通过后,马上就能自动将新版本镜像更新到线上,完成服务升级。
整个过程全自动化,一气呵成,最大程度地简化了运维,而且保证线上、线下环境完全一致,而且线上服务版本与Git/SVN发布分支也实现统一。
 
• 解决微服务架构的实施难题基于Spring Cloud这样的微服务框架,能够实现微服务的管理,但微服务本身还是需要运行在操作系统上。
一个采用微服务架构开发的应用中,微服务的个数往往很多,这就导致了一台服务器上往往需要启动多个微服务来提高资源的利用率,
而微服务本身可能就只能兼容部分操作系统,这就导致了就算有大量的服务器资源(操作系统可能不一样),
但由于微服务本身与操作系统可能相关,就不能做到让微服务在任意服务器上运行,这就带来了资源的浪费和运维的困难。
利用Docker容器的环境隔离能力,让微服务运行在容器内,就能够解决以上所说的问题。
 
• 执行临时任务有时候用户只是想执行一次性的任务,但如果用传统虚拟机的方式就要搭建环境,执行完任务后还要释放资源,比较麻烦。
使用Docker容器就可以构建临时的运行环境,执行完任务后关闭容器即可,方便快捷。
 
• 多租户环境利用Docker的环境隔离能力,可以为不同的租户提供独占的容器,实现简单而且成本较低。
 

总结

 
Docker的技术并不神秘,只是整合了前人积累的各种成果实现的应用级的容器化技术
它利用各种Linux发行版中使用了版本兼容的内核容器化技术,来实现镜像一次构建到处运行的效果,
并且利用了容器内的基础操作系统镜像层,屏蔽了实际运行环境的操作系统差异,
使用户在开发应用程序时,只需确保在选定的操作系统和内核版本上能正确运行即可,几乎不需要关心实际的运行环境的系统差异,大大提高效率和兼容性。
但随着容器运行得越来越多,容器管理将会成为另一个运维的难题,这时候就需要引入Kubernetes、Mesos或Swarm这些容器管理系统,后面再介绍。
 
posted @ 2020-10-20 19:05  梦里花落知多少sl  阅读(142)  评论(0)    收藏  举报