使用 K8S、Docker 测试和部署 Node.js 应用程序

时间:2024-03-18 14:33:51

作者:Joyce Lin

编译:小君君(才云)

技术校对:星空下的文仔(才云)、bot(才云)

编者按:如今,随着云应用程序复杂性的增加,很多研发团队开始将应用程序部署为分布式微服务架构,以此来加快软件交付。工程师们也在一直寻找简化和自动化持续部署代码的方法。本文将从容器的含义出发,使用一个简单的 Node.js 应用程序阐述如何使用 Docker 和 Kubernetes 部署可伸缩的 Web 应用程序。

如今,很多技术团队都会使用容器来简化和自动化其应用程序的部署过程,但是随着业务的增加,容器中的组件势必将会运行越来越多的实例。实例越多复杂性就会越高,这种日益增长的复杂性会为团队带来很大的困扰。

为了解决这个问题,实验团队使用 Kubernetes 作为更高级别的技术来管理 Docker,探测 Web 应用程序的可扩展性(不需要 Google 或 Facebook 级别的流量),并进一步简化管道,提高工作效率。

通过阅读本文你将了解:

  • 容器的意义;使用容器、Kubernetes 的好处;使用 Docker 和 Kubernetes 部署 Node.js 应用程序;结合实例的全文总结。

在实验之前,为了让读者更好地理解软件容器,本文将实体集装箱与容器进行了类比。

一、为何使用容器

首先介绍一下实体集装箱。在集装箱出现之前,码头工人需要通过很多道工序处理不同种类的货物。集装箱的出现,将货物的运输方式变得标准化。

例如,在运输木材之类的货物时,使用集装箱有以下好处:

  • 便携性:比起木材,集装在交通工具上有更多选择;
使用 K8S、Docker 测试和部署 Node.js 应用程序

  • 模块化:集装箱可以统一尺寸。在任何港口,装卸内含木材集装箱的起重机也可以搬运内含其他货物的集装箱;安全性:不同种类的货物会因为集装箱的隔离而不易损坏;可扩展性:当木材占据较少空间时,集装箱的剩余空间可做他用。

与实体集装箱相类似,软件容器也具有标准化意义。容器可以标准化 IT 基础架构。简单来说,容器就是将代码与其依赖关系打包到构建块中的一种方式。容器的具体特点如下:

  • 可移植性:因为容器与主机操作系统是分离的,所以它可以在本地或云上的任意设备中运行;模块化:容器可以帮助用户创建易于交换的应用程序堆栈组件,用户可以在 Web 服务器和数据库组件之间分散注意点;
使用 K8S、Docker 测试和部署 Node.js 应用程序

  • 安全性:容器是不可变的,因此人们可以通过更换整个容器来进行更新,从而轻松发布安全补丁或快速回滚更新;可扩展性:容器化应用程序可以向上扩展以处理额外负载或在休整期间降低流量来节约资源。

容器如何工作?

你可以想象一下,有一个繁忙的海港,船只每天来来往往。每个码头上都会有一个列明集装箱物品的清单。工人们会根据清单填充、搬运集装箱并把控船只停泊的时间。像这样繁忙的港口,他们就需要一些工具来协调物流,管理货物。

回到容器,技术人员也需要知道一些关于容器的专业工具来提高效率。

  • 容器镜像

镜像是容器的基石。镜像会告知用户如何将容器实例化,如何敲定并运行组件。用户还可以在容器中创建镜像,并与其他人共享这些规范,以便他们可以在笔记本电脑上运行应用程序。

  • 容器

容器是一个虚拟环境,它将应用程序代码与运行应用程序所需的所有二进制文件和库捆绑在一起。由于容器包含其所有依赖项,因此用户无需在主机操作系统上安装任何内容,就能使其保持独立和原始的状态。

  • 容器编排

容器编排是指协调容器与容器之间的行为,例如调度、资源管理和负载均衡。在复杂或动态的生态系统中,团队将使用编排引擎来控制、管理和自动化这个系统。

使用 K8S、Docker 测试和部署 Node.js 应用程序

在此,利用 Postman 来说明容器的工作原理。Postman 是一款强大的 API 开发调试软件。自从他们团队重新组建微服务架构后,每个服务都使用 Docker 来配置他们自己的环境。每个服务所有者自定义 Dockerfile。当新代码作为 CI / CD 管道的一部分被部署时,会从该 Dockerfile 生成镜像。生成的镜像将推送到团队的容器镜像仓库中,它的 Beanstalk 环境配置将从仓库中提取镜像以运行容器。

每项服务都可以灵活地配置、运行其服务。服务工程师可以专注于构建应用程序,而平台工程师可以专注于如何自动构建和部署。

Docker 负责配置环境和标准化部署管道。这为我们提供了更快的部署并提高效率(构建在 CI 期间只发生一次)。

- Postman 平台工程师 Saswat Das

为什么要使用 Kubernetes?

当你在应用程序中启动很多实例时,单一地启动实例并不会被线性扩展。容器或许会是你的一个好帮手,但大规模地管理这些操作可能会很复杂。此时,像 Kubernetes 这样的编排引擎就可以发挥作用了。它作为处理容器管理的更高级别技术,为技术人员带来了更多便利。

使用 K8S、Docker 测试和部署 Node.js 应用程序

二、使用 Docker 和 K8S 部署 Node 应用程序

介绍了这么多关于容器的知识后,相信你对它们应该有了一定的认识。现在,开始本次实验:使用 Docker 和 Kubernetes 部署一个简单的 Node 应用程序(利用 Postman)。

使用 K8S、Docker 测试和部署 Node.js 应用程序

该应用程序的功能类似于一个 URL 缩短器。在实例中,实验人员将使用“cat”“ =^.^= ”将一个 URL 转换为另一个 URL。当你将自定义 URL 输入浏览器时,浏览器将被重定向回原始网站。

使用容器的好处:即使人们在习惯的操作系统与不同版本的 Node 机器上开发此应用程序时,同样可以依靠容器镜像来规定运行相同应用程序所需的确切规范,无缝地在本地、云中以及其他任何地方进行部署。

使用 K8S、Docker 测试和部署 Node.js 应用程序

克隆此示例,并按照 README 步骤启动这些 API 的本地版本:

  • 开发;测试;部署。

开发应用程序

首先,实验人员使用 React 作为前端,使用 Express 作为后端。

*注:为简化演示,实验中不会实现持久化数据存储。

后端归结为 2 个 API:

  • 转换原始 URL;将新 URL 重定向回原始 URL。

在开发前端之前,实验人员使用 Postman 作为客户端将请求发送到本地服务器中(Postman 在更新有效负载、检查服务器响应时,都十分节省时间)。

以下是大多数人在想到 Postman 时所了解的典型用例。下文将会为读者介绍更多使用 Postman 提高效率的方法。

  • 人们可以使用 Postman 环境来保存配置参数,以达到在服务器设置之间快速切换的目的;实验人员在集合中使用一个名为 url 的环境变量,为本地开发和生产环境创建一个单独的模板;方便在 Postman 环境中快速切换 http://localhost:5500 与 https://cat-kube-stateless-prod-2ea747e90b.kubesail.io,更改配置选项。

在本地服务器上启动这些端点,然后转到 Postman 应用程序。在 Postman 应用程序中找到名为 catURL 的 Postman 模板,导入示例集合和环境。

使用 K8S、Docker 测试和部署 Node.js 应用程序

从 Postman 模板导入 catURL 集合和 catURL 本地环境

使用 catURL 集合和 catURL 本地环境来调试和测试这 2 个 API。

测试应用程序

更新常规 Postman 设置,以便在重定向之前检查服务器的响应标头。

*注:本文不会介绍在 Postman 中编写测试的基础知识,但读者可以看到 Tests 选项卡上的一些测试情况。

在 Postman 中,自动化可以通过手动测试 API 或使用集合运行器来实现。

实验人员使用 Postman 开源库 Newman 来运行构建时的集群,有 3 种方案:

  • 方案一(较好):使用位于项目目录中的静态 Postman 集合和 JSON 环境文件,对在本地服务器上运行的 API 进行测试;方案二(更好):仍针对本地服务器进行测试,使用 Postman API 运行这些测试,以动态提取集合和环境中的最新版本;方案三(更好):仍然使用 Postman API,针对在本地服务器上托管的容器 API 进行测试,以便测试环境完全复制你的生产环境。

最后一个场景 :添加一个部署脚本,它可以在本地容器中创建和启动 API 。任何 Postman 测试失败,Newman 都将返回错误代码,以便在执行任何部署步骤之前立即终止脚本的其余部分。

使用 K8S、Docker 测试和部署 Node.js 应用程序

如果测试未通过,则不会部署代码

  • 需要使用 Postman API 提取最新版本的集合或环境,因为使用静态 JSON 文件并不能确保你运行最新版本的测试;使用 Newman 作为 CI / CD 管道的一部分运行集合和环境。如果用户是使用 Jenkins、Travis CI 或任何类似的构建系统,操作过程并无差别;需要添加一个构建时脚本,该脚本将通知 Newman 运行 Postman 测试。如果测试未通过,则不会部署代码。

部署应用程序

现在,实验人员使用 Kubernetes 将前端和后端部署到单独的容器中。此示例仅指定了 API 的单个副本。(如果你想拥有 3 个副本,Kubernetes 将会一直监控这个应用实例。只要有一个副本崩溃,你就需要更换它们。)

使用 K8S、Docker 测试和部署 Node.js 应用程序

后端部署的配置文件

对于部署,实验人员使用了一个托管 Kubernetes 的提供程序 Kubesail,它创建了一个免费的托管命名空间。底层部署实用程序npx deploy-to-kube支持所有 Kubernetes 集群。

通过在应用程序目录中运行,该应用程序将自动生成 Dockerfile。它将构建、推送部署镜像,生成 Kubernetes 配置文件,并在 Kubernetes 集群上触发部署。

使用 K8S、Docker 测试和部署 Node.js 应用程序

一旦应用程序投入生产,人们就可以定期测试生产的 API,以确保它们的正常运行:

  • 方案一(较好):使用 Postman 集合运行器运行相同的测试以及使用用户的生产配置设置 Postman 环境;方案二(更好):设置一个 Postman 监视器,按照一定频率进行测试,或者使用 Newman 设置一个自定义的 cron 作业来做同样的事情。
使用 K8S、Docker 测试和部署 Node.js 应用程序

继续测试生产环境中的 API 以确保它们正常运行

除了基本监控之外,CNCF 还有很多用于内省的开源资源。例如:Prometheus 和 Istio 可以为用户的 Kubernetes 集群提供更高级的日志记录和调试功能。

最后,使用本地容器来测试 Node 应用程序,使用 Kubernetes 部署前端与后端,利用 Postman 在本地测试 API。

关于容器与编排的最后想法

在测试过程中,人们可以使用镜像针对应用程序测试(如 Postman 工程团队的操作方式)。容器还允许你扩展更多实例以进行并发性能测试。如果你已经将错误发布到生产环境中,容器也可以非常轻松地将更新快速回滚到上一个版本。

参考文献:

[1]https://medium.com/postman-engineering/deploying-a-scalable-web-application-with-docker-and-kubernetes-a5000a06c4e9