50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

为什么说 Kubernetes 是新的应用服务器

  • 2018-09-16
  • 本文字数:5734 字

    阅读完需:约 19 分钟

本文最初发表于 RedHat 开发者博客,经原作者 Rafael Benevides 授权由 InfoQ 中文站翻译分享。

你是否想过我们为什么要使用容器部署多平台应用呢?难道这仅仅是“跟风”吗?在本文中,我将提出一些有挑战性的问题,以佐证我的观点,那就是为什么说 Kubernetes 是新的应用服务器。

你可能已经注意到了,大多数的语言都是要经过“解释(interpret)”的,并且使用“运行时”来执行源码。在理论上,大多数的 Node.js、Python 和 Ruby 代码可以很容易地从一个平台(Windows、Mac、Linux)转换到另一个平台。Java 应用则更进一步,它将编译后的 Java 类转换成了字节码,能够在任何具有 JVM(Java 虚拟机)的地方运行。

Java 生态系统提供了标准的格式来分发同一个应用中的所有 Java 类。我们可以将这些类打包为 JAR(Java Archive)、WAR(Web Archive)以及 EAR(Enterprise Archive),在这些格式中包含了前端、后端以及嵌入其中的库。那么我就要问了:你为什么要使用容器来分发 Java 应用呢?难道它不是已经支持很便利地在不同环境间迁移了吗?

站在开发人员的角度回答这个问题的话,答案可能并不那么明显。但是,我们考虑一下你的开发环境,以及因为开发环境和生产环境的差异可能导致的问题:

  • 你使用 Mac、Windows 还是 Linux?在路径分隔符方面有没有遇到过\/相关的问题?
  • 你使用什么版本的 JDK?是否在开发环境使用 Java 10,而在生产环境使用 JRE 8?你有没有遇到过 JVM 差异所引入的 bug?
  • 你使用什么版本的应用服务器?生产环境是否使用相同的配置、安全补丁和相同版本的库?
  • 在生产部署的时候,是否遇到过不同版本的驱动或数据库服务器所导致的 JDBC 驱动问题,而这些问题在开发环境可能并不存在?
  • 你是否请求过应用服务器管理员为你创建数据源或 JMS 队列,但是在创建的过程中却出现了拼写错误?

所有的这些问题都是由应用之外的因素导致的,容器最大的好处之一就是它能够在一个预先构建的容器中部署所有的内容(比如 Linux 发行版、JVM、应用服务器、库、配置,最后还有你的应用)。另外,在一个容器中将所有的东西都包含进来能够更容易地将你的代码转移到生产环境中,在它无法正常运行的时候,也更容易分析其中的差异。因为它易于执行,所以也很容易将相同的容器镜像扩展至多个副本。

强化应用

在容器流行起来之前,应用服务器提供了一些非功能性需求(NFR,non-functional requirement),比如安全性、隔离性、容错、配置管理等等。打个比方,应用服务器和应用之间的关系就像 CD 播放器和 CD 之间的关系一样。

作为开发人员,你应该遵循预定义的标准并按照特定的格式分发应用,而应用服务器会“执行”你的应用并带来一些额外的功能,这些功能因服务器“品牌”的差异而有所不同。注意:在 Java 领域,应用服务器所提供的企业功能的标准最近转移到了 Eclipse 基金会。Eclipse Enterprise for Java( EE4J )的工作形成了 Jakarta EE 。(关于这方面的更多信息,请阅读 Jakarta EE 官方发布的文章或观看 DevNation 视频:Jakarta EE:Java EE 的未来)。

与 CD 播放器的类比方式相似,随着容器的流行,容器镜像成为了新的 CD 格式。实际上,容器镜像仅仅是用来分发容器的格式。(如果你需要更深入地了解容器镜像是什么以及它们如何进行分发的话,请参见容器术语的实用简介。)

容器的真正收益在你需要为应用添加企业级功能时才体现出来。为容器化的应用提供这些功能的最佳方式就是使用 Kubernetes 作为它们的平台。另外,Kubernetes 平台还为其他项目提供了很棒的基础实施,这些项目包括 Red Hat OpenShift Istio 以及 Apache OpenWhisk ,基于这些基础设施能够更容易的构建和部署健壮的生产级质量的应用。

接下来,我们探讨九个这样的功能:

1. 服务发现

服务发现指的是确定如何连接服务的过程。要获得容器以及云原生应用的很多收益,我们需要将配置从容器镜像中移除出去,这样的话,我们就能把相同的容器镜像应用到所有的环境中。将配置提取到应用外部是 12 要素应用的核心原则之一。服务发现是从运行时环境中获取配置信息的方式之一,这样能够避免将其硬编码到应用之中。Kubernetes 自带了服务发现。Kubernetes 还提供了 ConfigMaps 和 [Secrets] ( https://kubernetes.io/docs/concepts/configuration/secret/ ) 用来将配置从应用容器中移除。在运行时环境中,如果要连接数据库这样的服务,我们会存储凭证信息,Secrets 解决了一些这方面所面临的挑战。

借助 Kubernetes,我们无需使用外部的服务器或框架。尽管我们可以通过 Kubernetes YAML 文件管理每个运行时环境的配置,但是 Red Hat OpenShift 提供了 GUI 和 CLI,能够让 DevOps 团队更容易地管理配置信息。

2. 基本调用

容器中的应用可以通过 Ingress 进行访问,也就是从外部世界路由到你所暴露的服务。OpenShift 提供了基于 HAProxy 的 route objects ,它具有各项功能和负载均衡策略。你可以使用路由功能进行轮流部署。这可以作为一些非常复杂的 CI/CD 策略的基础。参见下文的“6. 构建和部署管道”。

如果你想运行一次性的任务,比如一个批处理或者只是使用集群来计算一个结果(比如计算 Pi 的位数),那该怎么办呢?针对这种场景,Kubernetes 提供了 job objects 。同时还有一个 cron job ,能够管理基于时间的任务。

3. 弹性

在 Kubernetes 中,弹性(elasticity)是通过 ReplicaSets (它过去被称为 Replication Controllers)解决的。与面向 Kubernetes 的大多数配置类似,ReplicaSet 是一种协调所需状态的方式:你告诉 Kubernetes,系统应该处于各种状态,Kubernetes 就能知道如何达到该状态。在任意时间,ReplicaSet 都能控制副本的数量或应用程序精确的实例数量。

但是,如果你所构建的服务受欢迎程度超出了预先的规划,计算资源耗尽了该怎么办呢?你可以借助 Kubernetes Horizontal Pod Autoscaler ,它会基于观测到的 CPU 利用率(或所支持的自定义指标,以及应用提供的指标)扩展 pod 的数量。

4. 日志

因为 Kubernetes 集群能够运行容器化应用的多个副本,所以将这些日志聚合起来,以便于在同一个地方进行查看就变得非常重要了。同时,为了利用自动扩展(以及其他云原生应用的功能)所带来的收益,容器应该是不可变的。所以,我们应该将日志存储在容器之外,这样它们才能跨运行时持久化。OpenShift 允许我们部署 EFK 技术栈来聚合来自主机和应用的日志,即便这些日志来自多个容器甚至已删除的 pod 均是可以的。

EFK 技术栈的组成如下所示:

  • Elasticsearch (ES),存储日志内容的对象存储;
  • Fluentd ,从节点收集日志并将其发送至 Elasticsearch
  • Kibana ,针对 Elasticsearch 的 Web UI。

5. 监控

尽管日志和监控看上去解决的是相同的问题,但是它们之间是不同的。监控是观察、检查、通常还有告警以及记录,而日志则只有记录。

Prometheus 是一个开源的监控系统,它包含了时序数据库。它可以用来存储和查询指标、告警,并使用可视化的方式查看系统内部的运行状况。Prometheus 可能是监控 Kubernetes 集群方面最流行的可选方案。在 Red Hat 开发人员博客上,有多篇介绍使用 Prometheus 进行监控的文章。在 OpenShift 博客上,也能找到关于 Prometheus 的文章。

你还可以看到 Prometheus 和 Istio 实际结合使用的教程

6. 构建和部署管道

对于你的应用来说,CI/CD(持续集成 / 持续交付)并不是“必备”的要求。但是,CI/CD 通常被认为是成功软件开发和 DevOps 实践的支柱。如果没有经过 CI/CD 管道的话,软件不应该发布到生产环境中。Jez Humble 和 David Farley 合著的《持续交付:发布可靠软件的系统方法》中是这样描述 CD 的:“持续交付能够将各种类型的变更发布到生产环境中,包括新特性、配置变化、缺陷修正以及体验性的功能,或者说以可持续的方式将这些变更安全且快速地交到用户的手里”。

OpenShift 内置提供了 CI/CD 管道,将其作为“构建策略”。读者可以查看我两年前录制的视频,其中包含了部署一个全新微服务的 Jenkins CI/CD 管道样例。

7. 适应性

Kubernetes 为集群本身提供了适应性(resilience)方案,它还提供了 PersistentVolumes 来支持卷(volume)的副本,从而帮助应用实现适应性。Kubernetes 的 ReplicationControllers / 部署能够确保指定数量的 pod 副本在整个集群中始终正常运行,它会自动处理任何可能出现的节点故障。

结合适应性,容错能够作为一种有效的方式来处理用户对于可靠性和可用性的关切。运行在 Kubernetes 上的应用还可以通过 Istio 的重试规则、断路器和池弹射(pool ejection,即移除掉出现故障的容器——译注)来实现容错。如果你想自行了解一下的话,可以尝试 Istio Circuit Breaker 的教程

8. 认证

在 Kubernetes 中,认证可以通过 Istio 的 mutual TLS 认证来实现,它致力于增强微服务及其通信的安全性,而无需服务代码的变更。它会负责:

  • 为每个服务提供一个代表其角色的强标识(identity),从而允许它能够跨集群和云进行互操作;
  • 保护服务与服务之间的通信,以及终端用户与服务之间的通信;
  • 提供 key 管理系统,自动化 key 和证书生成、分发、轮换和撤销。

另外,值得一提的是,我们还可以在 Kubernetes/OpenShift 集群中运行 Keycloak 以提供认证和授权。Keycloak 是 Red Hat Single Sign-on 的上游产品。关于它的更多信息,请参阅使用 Keycloak 简化单点登录。如果你使用 Spring Boot 的话,还可以观看 DevNation 视频:使用 Keycloak 保护 Spring Boot 微服务或阅读博客文章

9. 跟踪

基于 Istio 的应用可以配置为使用 Zipkin Jaeger 收集跟踪的 span。不管使用什么语言、框架或平台来构建应用,Istio 都能支持分布式跟踪。关于这方面的知识,可参考该教程。读者还可以参见“在笔记本电脑上掌握 Istio 和 Jaeger 的基础知识”以及最近的 DevNation 视频:使用 Jaeger 进行高级的微服务跟踪

应用服务器会消亡吗?

通过这些功能,你就能意识到 Kubernetes + OpenShift + Istio 确实能够增强你的应用,并且提供了一些特性,这些特性以前都是由应用服务器或者像 Netflix OSS 这样的框架来负责的。这是否意味着应用服务器将会消亡呢?

在这个新的容器世界中,应用服务器正在变得越来越像框架。软件开发的演化很自然会导致应用服务器的演化。这种演化的一个例子就是 Eclipse MicroProfile 规范以及 WildFly Swarm 应用服务器,它为开发人员提供了各种特性,比如容错、配置、跟踪、REST(客户端和服务端)等等。WildFly Swarm 和 MicroProfile 规范的设计是非常轻量级的,WildFly Swarm 并不包含完整 Java 企业级应用服务器的各种各样的组件。相反,它关注微服务,只保留了将应用按照简单可执行的“.jar”文件进行构建和运行的功能。在该博客中,你可以阅读到关于 MicroProfile 的更多信息。

另外,Java 应用还包括 Servlet 引擎、数据库池、依赖注入、事务、消息等特性。当然,框架可能会提供这些特性,但是应用服务器必须要具备在任何环境下构建、运行、部署和管理企业级应用所需的各种功能,不管它是不是在容器中运行。实际上,应用服务器可以在任何地方执行,例如,在裸机上、在像 Red Hat Virtualization 这样的虚拟化平台上、在像 Red Hat OpenStack 平台 这样的私有云环境中以及在像 Microsoft Azure Amazon Web Services 这样的公有云环境中。

好的应用服务器要确保它所提供的 API 和具体实现之间的一致性。开发人员可以确信如果他的业务逻辑需要特定的功能,他所部署的逻辑是正常运行的,因为应用服务器开发人员(以及预先定义的标准)能够保证它们之间能够协同工作和协同演化。另外,好的应用服务器还要负责最大化吞吐量和可扩展性,因为它要处理来自用户的所有请求;减少延迟并提升负载能力,它有助于提升应用的可处置性;轻量级的资源占用,最小化硬件资源和成本;最后,还要足够安全,能够防范所有的安全漏洞。对于Java 开发人员来说,Red Hat 提供了 Red Hat JBoss 企业级应用平台,满足了现代、模块化应用服务器的所有需求。

结论

容器镜像已经成为分发云原生应用的标准打包格式。尽管容器本身并没有为应用提供任何真正的业务优势,但是 Kubernetes 及其相关的项目,如 OpenShift 和 Istio,提供了非功能性的需求,而这些需求过去曾是应用服务器的功能的一部分。

开发人员过去所使用的大多数非功能性需求,来源于应用服务器或者像 Netflix OSS 这样的库,这些需求是与特定语言绑定的,比如 Java。但是,如果开发人员选择使用 Kubernetes + OpenShift + Istio 来满足这些需求的话,它们是与任何特定语言都没有关联的,这样的话就能鼓励开发人员针对每个使用场景选择最佳的技术 / 语言。

最后,在软件开发领域,应用服务器依然有它的位置。但是,它们变得更像是特定语言的框架,在开发应用的时候,这是很简便的,因为它们包含了大量已经编写就绪且经过测试的功能。

转移到容器、Kubernetes 和微服务架构时,最棒的事情之一就是不必为应用选择单一的应用服务器、框架、架构风格甚至编程语言。你可以很容易地部署一个含有 JBoss EAP 的容器,让 JBoss EAP 运行已有的 Java EE 应用,其他的容器则可能会包含使用 Wildfly Swarm 编写的微服务或者使用 Eclipse Vert.x 编写的反应式程序。这些容器都可以通过 Kubernetes 进行管理。如果想了解这些概念如何实际运行,参考 Red Hat OpenShift 应用运行时。通过 Launch 服务在线构建和部署示例应用,这些应用可以使用 WildFly Swarm、Vert.x、Spring Boot 或 Node.js。选择“Externalized Configuration”以便于学习如何使用 Kubernetes ConfigMaps,这足以让你踏上学习云原生应用的征途。

你可以说 Kubernetes/OpenShift 是新的 Linux ,甚至可以说“Kubernetes 是新的应用服务器”。但实际上,应用服务器 / 运行时 +OpenShift/Kubernetes + Istio 已经成为了云原生平台的事实标准。

关于作者

Rafael Benevides 是 Red Hat 的开发者体验(Developer Experience)总监,具有多年的各领域 IT 行业经验,他帮助世界范围内的开发人员和公司提升软件开发的效率。Rafael 将自己定位为问题解决者,并乐于分享。他是 Apache DeltaSpike PMC 成员,该项目曾获得过 Duke’s Choice Award,他还会在 JavaOne、Devoxx、TDC、DevNexus 等技术会议上发表演讲。

2018-09-16 18:222892

评论

发布
暂无评论
发现更多内容

常见的主从报错集锦

一个有志气的DB

MySQL 主从配置 主从同步

2020 敏捷产品基本盘

Yanel 说敏捷产品

产品 敏捷 产品设计 产品推荐

Java实现Base64

Java

敏捷团队成员的工作量指标真的那么重要吗?

金生水起

敏捷开发 Scrum精髓 敏捷精髓 Agile

Serverless: 2020年函数计算的冷启动怎么样了

刘宇

工程师、程序员和产品经理

王泰

程序员 产品经理 IT 软件工程师 工程师思维

何时开始重构?

Page

敏捷开发 重构

多多益善的MacOS文件管理方案

陈东泽 EuryChen

macos Mac apple 提升效率 文件管理

【Howe学爬虫】全国统计用区划代码爬取

Howe

Java 爬虫

看完这篇操作系统,和面试官扯皮就没问题了

苹果看辽宁体育

操作系统 计算机基础

【大咖说问大咖】关于开源的那些事 —— PingCAP CTO 黄东旭 Q&A 交流帖

InfoQ写作社区官方

开源 写作平台 大咖说 技术交流 热门活动

spring注入bean的几种策略模式

王德发

Java Spring Boot 测试驱动开发实战营

BVR 才是变革的核心

Yanel 说敏捷产品

团队管理 项目管理 敏捷 敏捷开发 敏捷精髓

近期工作的几点感想

Leiy

app退出登录

揭秘!开源软件背后的神秘组织

Apache Flink

大数据 flink 流计算 实时计算

用"结构性张力"构建自驱力

Yanel 说敏捷产品

团队管理 敏捷 团队协作 项目

搜商:高效的使用搜索引擎

石云升

高效搜索 搜索技巧 搜商

MySQL索引知识介绍

Simon

MySQL 索引结构

提升编程效率:重构

Page

高效工作 敏捷开发 重构 高效

数据分析的利器-clickhouse概述

流沙

数据库 Clickhouse

KK日知录20200515

kimmking

从ClickHouse的名字由来讲起

nauu

数据库 大数据 分布式 OLAP Clickhouse

MySQL备份基础

一个有志气的DB

MySQL 数据

Kafka零数据丢失的配置方案

奈学教育

kafka kafka配置 kafka数据

为什么我喜欢的大V拉黑我?

lmymirror

经历 后真相时代 日常思考

原创 | 使用JUnit、AssertJ和Mockito编写单元测试和实践TDD (七)CORRECT边界条件

编程道与术

Java 编程 软件测试 TDD 单元测试

真的!只需 “六步” 实现图像特定物体识别!!!

攀岩飞鱼

Python OpenCV 计算机视觉 图像识别 物体检测

学习型组织的修炼之道

Yanel 说敏捷产品

团队管理 项目管理 敏捷 团队协作 组织转型

Android | Tangram动态页面之路(一)需求背景

哈利迪

android

太赞了,VSCode 上也能画流程图了!

GitHubDaily

visual-studio GitHub 程序员 vscode 开发者工具

Intellij IDEA2020.x如何安装Lombok插件

龙眼果

开发者工具

为什么说Kubernetes是新的应用服务器_语言 & 开发_Rafael Benevides_InfoQ精选文章