SpringCloud Alibaba 实战 - 前京东金融架构师 - 拉勾教育

你好,今天咱们来了解什么是微服务与容器化技术。前面我们反复强调微服务架构是将大的应用打散为多个小服务,这就必然导致打散后形成更多需要独立部署的应用程序,在大型互联网应用中,这些程序可能会达到上千个之多。频繁的测试、打包、发布,无疑会给运维部门带来巨大的工作量与更多的不可控因素。因此在大型应用中急需一种成本更低、更高效、自动化的技术解决运维问题,而这一切随着 DevOps 与 Docker 容器化技术的逐渐落地已经成为现实。本讲咱们将围绕 DevOps 与容器化技术讲解三方面内容:

  • 介绍什么是 DevOps;
  • 讲解容器化技术的与众不同;
  • 分析 DevOps 架构执行流程。

什么是 DevOps?

DevOps 是 “软件开发人员(Dev)” 和“IT 运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化 “软件交付” 和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

23 | 极速运维:微服务与 DevOps - 图1

DevOps

用人话翻译过来就是,在现代以微服务架构为代表的分布式架构,将原本单体应用独立部署转型为多节点、多实例的大集群部署,架构形式的改变对于开发与运维都提出了新的挑战。以我之前所在公司为例,公司在项目微服务改造后,通过虚拟化技术在物理机上虚拟出几百台应用节点,这些节点被分配给不同的微服务项目组,而公司要求每一个微服务在生产环境的不同节点上至少部署三个服务实例来提高系统可用性。

虽然理想是丰满的,但现实却很残酷。随着公司业务不断增多,微服务架构的规模也在不断扩大,研发工程师在每次上线时都要写非常详细的上线文档指导运维同事手动部署,稍有差池上线后还会遇到各种莫名其妙的问题导致上线失败,而这个过程中运维同事也苦不堪言,因为每一个微服务都要在多个节点上部署副本,面对海量的重复工作也只能熬夜苦战自认倒霉。

假如这时能有一种技术让开发人员把新版本应用制作成 “安装程序” ,将应用运行所需的产出物、依赖环境、应用设置都打包在一起交付给运维人员,运维人员得到“安装程序” 后无须理解其中含义,只需在生产环境执行这个 “安装程序”,便自动部署并启动与开发人员定义一致的应用程序。这样做同时也衍生出另外一个好处,因为所有部署都变成了标准的“执行安装程序” 的过程,运维就可以通过脚本与集群管理工具自动实现批量部署。

随着技术的发展,标准化部署的期望也逐渐变为现实,以 Docker 为代表的容器化技术逐渐成为 DevOps 的核心实现,基于容器化技术构建的镜像包含了应用运行所需的底层资源,在开发人员为新版应用生成镜像后,运维人员便可通过镜像在生产环境中真正实现 “一键发布”。

那么,到底什么是容器化技术呢?

软件部署的发展过程

首先我们要理解容器化技术为什么会出现呢?

到目前为止,在应用的部署方式上主要经过了三个阶段:物理机部署阶段、虚拟机部署阶段、容器化部署阶段。

物理机部署阶段

23 | 极速运维:微服务与 DevOps - 图2

物理机部署阶段

物理机部署阶段顾名思义就是应用程序安装在物理服务器的操作系统中,应用程序直接通过操作系统获取物理服务器的 CPU、内存、硬盘等资源。物理机部署阶段是最原始、最简单的部署方式,但它的问题也非常严重,因为应用程序并不能充分利用服务器资源,就会造成 CPU 闲置、内存过剩等资源浪费情况,再加之物理服务器通常非常昂贵,因此物理机的部署成本也是最高的。随着服务器内存已经进入百 G 时代,目前直接在物理机部署应用的情况已经越来越少,取而代之是通过虚拟机部署应用。

虚拟机部署阶段

23 | 极速运维:微服务与 DevOps - 图3

虚拟机部署阶段

虚拟机部署阶段是物理机部署阶段的升级版,通过 VMWare 或者 VirtualBox 等虚拟化工具,可以将高性能物理服务器切割为若干虚拟机,这些虚拟机拥有自己独立的 CPU、内存、硬盘资源,并且这些资源彼此隔离不允许交叉访问。这样运维工程师就可以为不同类型的应用分配不同的资源,如计算密集型的应用就多分配一些 CPU 核数,存储密集型应用就多分配一些内存与硬盘空间,并且这些资源可以在不停机的情况下实现动态调整,让服务器资源得到最大化的利用。但是看似完美的方案其实也存在问题,虚拟机关注资源层面上的分配与管理,但对如何快速部署应用程序并没有给出更好的可行办法。因此 IT 业内就需要一种更为轻量级的,且关注点在应用本身的部署方案,这时以 Docker 为代表的容器化技术就应运而生。

容器化部署阶段

23 | 极速运维:微服务与 DevOps - 图4

容器化部署阶段

容器化部署阶段最大的特点是部署时将关注点放在应用本身,通过直接生成一个个容器实现应用的快速部署发布,同时容器化技术不再强调资源隔离,所有容器底层通过 Docker 容器引擎与操作系统获取全局共享的物理机资源。相比虚拟化技术有两点巨大优势:

  • 标准化的部署过程。因为容器化关注应用本身,因此创建容器的过程就是部署应用的过程。容器将是标准化的产物,可能容器内部的应用程序功能各不相同,但对运维人员来说创建容器的命令与操作过程都是基本相同的,可以通过脚本快速批量的完成容器的创建。
  • 更好的性能。相比虚拟机,容器化并不强调资源隔离,物理机的所有资源对于容器都是共享的,容器与底层资源之间通过 Docker 容器引擎与操作系统进行调度,这中间产生的损耗相比虚拟机小得多。

以上就是到目前为止应用部署经历的三个阶段。其中容器化技术有一些重要概念,我们有必要了解。

容器化技术的重要概念

说到容器化技术,肯定避不开 Docker。Docker 是一个开源的应用容器引擎,基于 Go 语言开发。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,Docker 经过多年发展已经是容器化技术的标准。

23 | 极速运维:微服务与 DevOps - 图5

Docker

在基于 Docker 实施 DevOps 微服务架构自动化运维的过程中,我们有几个重要的概念必须理解。

  • 镜像(Image):所谓镜像其实非常像 Windows 操作系统的安装光盘。安装光盘内包含了 Windows 操作系统运行时所有的文件,你可以拿着这张光盘在任何新电脑上安装 Windows 系统。而 Docker 的镜像就是我们自己应用程序的安装光盘,你可以使用镜像在任何安装了 Docker 的 Linux 系统上快速部署应用程序。
  • 仓库(Repository):仓库是存放镜像的地方,以前我们安装系统需要到电脑城购买光盘,现在安装系统只需要从各大软件网站下载 ISO 文件即可。Docker 也是一样的,为了方便我们部署,Docker 提供了 DockerHub 仓库站托管开发者的镜像文件,开发者可以利用 Pull 命令直接从仓库下载镜像到本地部署。
  • Dockerfile:Docker 镜像脚本。通过 Dockerfile 中描述的构建过程,Docker 可创建用户自定义的镜像文件,这些自定义镜像可被存放在仓库(Repository)供其他人员下载部署。
  • 容器(Container):容器就是镜像的实例。镜像是只读的,就像你单有一张安装盘却没有电脑,这个安装盘是无用的。只有你通过安装盘将程序安装在电脑上,程序才能运行产生价值,而容器就是被 Docker 创建的一个个程序实例。

23 | 极速运维:微服务与 DevOps - 图6

DockerHub

  • 容器编排工具:容器编排工具的典型代表是 Google Kubernetes(K8S) 和 Docker Swarm,容器编排工具用于管理大规模集群中的容器实例。我们举例说明,通常一个容器只负责运行一个应用程序,但是像 Nginx+Tomcat+Redis+MySQL 这样的应用架构就需要多个容器间协同作业才能正常运行。假如公司采购了 200 台服务器,CTO 要求这些容器不但要求基于 Docker 独立运行与部署,还要在服务器网络间自动实现互联互通,甚至还要求随着外部用户的访问压力的变化自动进行容器的扩容与收缩。显然如此复杂的容器管理与调度,必须借助专用的工具来进行统筹,于是以 K8S 为代表的容器编排工具就派上用场了,K8S 允许运维人员通过可视化的方式对容器进行动态调整,同时对所有运行节点也提供了实时监控。以前多名运维工程师需要工作几个小时的任务,现在只需要一名运维工程师点几下鼠标就能实现,公司为此可以节省大量的人力与时间成本。

23 | 极速运维:微服务与 DevOps - 图7

K8S 监控仪表盘

DevOps 执行流程

讲到这里,我们理解了基于容器化几个重要的概念。下面咱们来分析一下某知名大厂是如何实施 DevOps。

23 | 极速运维:微服务与 DevOps - 图8

DevOps 流程

第一步,研发工程师将测试验收后的源码上传到 GitLab 服务器,并创建新的版本分支。GitLab 是用于管理代码版本的 Web 开源项目,使用 Git 作为代码管理工具,你可以理解为内网的 GitHub 仓库。公司出于保密原因其源码不允许将其托管到 GitHub 这样的开放平台,因此才需要搭建独立的 GitLab 仓库。当然创业型公司也可以出于成本考虑将代码托管到 GitHub 或者 Gitee 上。

第二步,在 GitLab 创建新的版本分支后,研发工程师还需要创建 Dockerfile 来描述 Docker 镜像的构建过程,之后将 Dockerfile 也上传到该分支下。

第三步,在 GitLab 中新版本源码与 Dockerfile 都已上传,由软件工程师或者配置管理员发起 Jekins 的自动化脚本完成镜像的自动化构建与仓库推送,这个自动化脚本包含 3 个步骤:

  1. 抽取新版本源码到 Jekins 服务器,利用 Jekins 服务器安装 Maven 自动完成编译、测试、打包的过程,因为微服务采用 SpringBoot 开发,最终产出物为 Jar 文件。
  2. 抽取新版本 Dockerfile 到 Jekins 服务器,利用 Jekins 服务器安装的 Docker 完成镜像的构建工作,在构建过程中需要将上一步生成的 Jar 文件包含在内,在容器创建时自动执行这个 Jar 文件。
  3. 镜像生成后,还是通过 Jekins 服务器上的 Docker 将新版本镜像推送到 HARBOR 仓库。HARBOR 用于创建 Docker 镜像的私有仓库,公司从保密角度出发要求自己搭建内网 Docker 镜像仓库,创业公司可以直接使用 Dockerhub 或国内 Docker 开放镜像平台进行托管。当新版本镜像推送到镜像仓库后,软件工程师的任务已完成,之后便是等待上线发版了。

第四步,在上线日运维工程师接入 Kubernetes 管理端,发起 Deploy 部署命令,此时生产环境的 K8S 节点会从 HARBOR 仓库抽取最新版本的应用镜像,并在服务器上自动创建容器,最新版本的 Jar 文件在容器创建时也会随之启动开始对外提供服务。在校验无误后,本次上线宣告成功。

讲到这里我为你勾勒出 DevOps 的执行流程,当然真实环境比本文介绍的过程复杂得多,还要考虑多种异常因素,例如:

  • 源码编译、打包时产生异常的快速应对机制
  • 上线失败如何快速应用回滚
  • 镜像构建失败的异常跟踪与补救措施
  • ……

因为篇幅有限,本文我们并未涉及过多 Docker 与 K8S 的具体知识,如果你对容器化技术感兴趣,可以继续学习拉勾教育提供的《由浅入深吃透 Docker》《Kubernetes 原理剖析与实战应用》课程,一定会让你有巨大收获。

小结与预告

本讲我们探讨了三方面内容,首先通过现实案例介绍了什么是 DevOps,其次通过部署技术的发展使我们认识了容器化技术的优点,最后我们分析了大厂成熟的 DevOps 执行流程。

这里给你留一道讨论题:你可将之前项目开发、运维中遇到的各种问题在评论区中吐槽,看我和其他小伙伴有没有更好的解决办法。

下一课是整个课程的最后一讲,我们将对微服务架构和 Spring Cloud Alibaba 进行总结,并对它的后续发展进行展望。