Docker:教你如何把服务器装进口袋里,让工资涨得明明白白(一)

511 阅读13分钟

本文正在参加「金石计划」

一、简介

1.1、遇到的问题

假定您在开发一个系统,您使用的是一台笔记本电脑而且您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。此外,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。您希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销。那么要如何确保应用能够在这些环境中运行和通过质量检测?并且在部署过程中不出现令人头疼的版本、配置问题,也无需重新编写代码和进行故障修复?

环境配置相当麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案-----系统平滑移植,容器虚拟化技术。

image-20230304162502294

1.2、Dcoker能干啥

之前在服务器配置一个应用的运行环境,要安装各种软件,就拿尚硅谷电商项目的环境来说,Java/RabbitMQ/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在 Windows 上安装的这些环境,到了 Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。

传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让维运团队得以部署应用程式,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。Docker的出现使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。

1.3、Dcoker

先给出官网:官网直达,Docker早期的定义:运行你的应用不需要你的环境。

image-20230304163132966

Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”,在打包的时候,我们可以将Docker和他的运行环境进行打包,不需要我们再额外安装环境。

Linux容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用打成镜像,通过镜像成为运行在Docker容器上面的实例,而 Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。

简而言之,Docker解决了运行环境和配置问题的软件容器, 方便做持续集成并有助于整体发布的容器虚拟化技术。以后我们用到哪个服务就启动哪个容器即可。Docker(容器)里面装的是一个一个的软件。

1.4、Docker的优势

image-20230304183609177

1.4.1、高效迁移

这里我们拿java Web应用程序举例,我们一个java Web应用程序涉及很多东西,比如jdk、tomcat、mysql等软件环境。当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来这种情况。Docker则将程序以及使用软件环境直接打包在一起,无论在那个机器上保证了环境一致。即:一致的运行环境,更轻松的迁移。

如果我们不使用Docker的时候,当这些其中某一项版本不一致的时候,可能会导致应用程序跑不起来的这种情况,常见的情况有:在开发的时候,在本机测试环境可以跑,生产环境跑不起来。

但是如果我们使用Docker的话就不会出现这种情况。环境一致,高效迁移。

1.4.2、进程隔离

我们经常遇到的问题:服务器自己的程序挂了,结果发现是别人程序出了问题把内存吃完了,自己程序因为内存不够就挂了。

这种也是一种比较常见的情况,如果你的程序重要性不是特别高的话,公司基本上不可能让你的程序独享一台服务器的,这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免地就会受到其他程序的干扰,导致自己的程序出现问题。Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序。

这个时候Docker的优势就体现出来了,那就是进程级隔离,容器间独立,对进程进行封装隔离,容器与容器之间互不影响,更高效的利用系统资源。容器与容器之间是属于进程之间的进程级别的隔离。虽然我们是允许在一台机器上,但是两个容器是分属于不同的操作系统。

1.4.3、镜像机制

在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事,而且每台服务器的环境还不一定一样,就会出现各种问题,最后部署地头皮发麻。用Docker的话,我只需要将程序打包到镜像,你要多少台服务,我就给力跑多少容器,极大地提高了部署效率。比如公司要弄一个活动,可能会有大量的流量进来,公司需要再多部署几十台服务器,那我们在部署项目的时候,还需要再同时部署多个环境,所以我们可以直接通过镜像复制N多个环境一致容器。

1.5、Docker起源

image-20210525114439924

2010年,几个年轻人在旧金山成立了一家做PaaS(Platform as a Service,平台及服务)平台的创业公司,起名为 dotCloud,并且还获得了创业孵化器 Y Combinator 的支持,虽然 dotCloud 期间获得过一些融资,但随着 IT 巨头(微软、谷歌、亚马逊等)也杀入 PaaS 平台,dotCloud举步维艰。

2013 年,dotCloud 的创始人,28 岁的 Solomon Hykes 做了一个艰难的决定:将 dotCloud 的核心引擎开源,这项核心引擎技术能够将 Linux容器中的应用代码打包,轻松的在服务器之间迁移。

然而这个基于 LXC(Linux Container)技术的核心管理引擎开源后,让全世界的技术人员感到惊艳,感叹这一切太方便了!也正是dotCloud 的创始人这个艰难的孤注一掷的决定让所有的 IT 巨头们也为之一颤。

从 2013 年 Docker 开源开始,Docker 技术风靡全球,于是 dotCloud公司决定将 Docker 作为主要业务进行发展,并把公司改名为 DockerInc,全身心投入到 Docker 的开发中,并于 2014 年 8 月,Docker 宣布把 PaaS(Platform as a Service,平台及服务)业务 dotCloud 出售给位于德国柏林的同样专注于平台即服务业务的提供商 cloudControl,从此 Docker 可以轻装上阵,专注于 Docker 的研发。

从 2013 年 2 月决定开源,到 2013 年 3 月 20 日发布 Docker 0.1,只用了一个月时间。当前 Docker 的最新版本是 18.03。

Docker 迅速成长,在 2014 年 6 月 9 日,Docke 团队宣布发布 Docker1.0,1.0 版本标志着 Docker 平台已经足够成熟,并可以被应用到生产产品中(还提供了一些需要付费的支持选项)。

一年的时间,使一个围绕着 Docker 的小型初创企业生态体系逐渐形成。Docker 先后赢得了 Google、 微软、Amazon、VMware 等 IT 巨头的青睐,他们纷纷表示将保证自己平台与 Docker 容器技术的兼容性。

2016 年 2 月 29 日,CloudControl 公司在其官方博客中宣告即将破产,隶属于cloudControl公司的dotCloud也宣布将于2月29日关闭服务。作为 Docker 的前身,DotCloud 目睹 Docker 的成长,成为云平台的一颗新星,而自己却力不从心,Docker 的繁荣间接地导致 Docker 的前身 dotCloud 在 PaaS 平台的衰败,兴衰成败,令人唏嘘不已,这也许是颠覆式创新的经典案例。

1.6、Docker和虚拟机

1.6.1、虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows10系统里面运行Linux系统CentOS7。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。

image-20230304174514147

虚拟机的缺点:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动慢

1.6.2、Docker容器

我们可以先来浅浅的比解读一下Docker的官方Logo的含义。

image-20230304174933052

Docker的吉祥物是一条鲸鱼,在鲸鱼的身上有着一个个的小箱子,小箱子之间互不影响,相互独立。而鲸鱼就代表Docker引擎。

这个时候就有人引出来了Docker引擎和传统虚拟机的对比,简单来说就是容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便

image-20201220222456675

比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大,很笨重。Docker是不携带操作系统的,所以Docker的应用就非常的轻巧。另外在调用宿主机的CPU、磁盘等等这些资源的时候,拿内存举例,虚拟机是利用Hypervisor去虚拟化内存,整个调用过程是虚拟内存->虚拟物理内存->真正物理内存,但是Docker是利用Docker Engine去调用宿主的的资源,这时候过程是虚拟内存->真正物理内存。

传统虚拟机Docker容器
磁盘占用几个GB到几十个GB左右几十MB到几百MB左右
CPU内存占用虚拟操作系统非常占用CPU和内存Docker引擎占用极低
启动速度(从开机到运行项目)几分钟(从开启容器到运行项目)几秒
安装管理需要专门的运维技术安装、管理方便
应用部署每次部署都费时费力从第二次部署开始轻松简捷
耦合性多个应用服务安装到一起,容易互相影响每个应用服务一个容器,达成隔离
系统依赖需求相同或相似的内核,目前推荐是Linux

简单来说就是:

  1. 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。
  2. 器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

1.7、Docker能干什么

1.7.1、更快速的应用交付和部署

传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行,而在进行了Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。

1.7.2、更便捷的升级和扩缩容

随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块“积木”,应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原先的天级变成分钟级甚至秒级。

1.7.3、更简单的系统运维

应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。

1.7.4、更高效的计算资源利用

Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。