Michael Hausenblas 发布的文章

在现代微服务环境中,构建小型、单一的应用程序的旧策略又再一次流行了起来。

1984 年,Rob Pike 和 Brian W. Kernighan 在 AT&T 贝尔实验室技术期刊上发表了名为 “Unix 环境编程” 的文章,其中他们使用 BSD 的 cat -v 例子来认证 Unix 哲学。简而言之,Unix 哲学是:构建小型、单一的应用程序 —— 不管用什么语言 —— 只做一件小而美的事情,用 stdin / stdout 进行通信,并通过管道进行连接。

听起来是不是有点耳熟?

是的,我也这么认为。这就是 James Lewis 和 Martin Fowler 给出的 微服务的定义

简单来说,微服务架构的风格是将单个 应用程序开发为一套小型服务的方法,每个服务都运行在它的进程中,并用轻量级机制进行通信,通常是 HTTP 资源 API 。

虽然一个 *nix 程序或者是一个微服务本身可能非常局限甚至不是很有用,但是当这些独立工作的单元组合在一起的时候就显示出了它们真正的好处和强大。

*nix程序 vs 微服务

下面的表格对比了 *nix 环境中的程序(例如 catlsof)与微服务环境中的程序。

*nix 程序微服务
执行单元程序使用 stdin/stdout使用 HTTP 或 gRPC API
数据流管道
可配置和参数化命令行参数、环境变量和配置文件JSON/YAML 文档
发现包管理器、man、makeDNS、环境变量、OpenAPI

让我们详细的看看每一行。

执行单元

*nix 系统(如 Linux)中的执行单元是一个可执行的文件(二进制或者是脚本),理想情况下,它们从 stdin 读取输入并将输出写入 stdout。而微服务通过暴露一个或多个通信接口来提供服务,比如 HTTP 和 gRPC API。在这两种情况下,你都会发现无状态示例(本质上是纯函数行为)和有状态示例,除了输入之外,还有一些内部(持久)状态决定发生了什么。

数据流

传统的,*nix 程序能够通过管道进行通信。换句话说,我们要感谢 Doug McIlroy,你不需要创建临时文件来传递,而可以在每个进程之间处理无穷无尽的数据流。据我所知,除了我在 2017 年做的基于 Apache Kafka 小实验,没有什么能比得上管道化的微服务了。

可配置和参数化

你是如何配置程序或者服务的,无论是永久性的服务还是即时的服务?是的,在 *nix 系统上,你通常有三种方法:命令行参数、环境变量,或全面的配置文件。在微服务架构中,典型的做法是用 YAML(或者甚至是 JSON)文档,定制好一个服务的布局和配置以及依赖的组件和通信、存储和运行时配置。例如 Kubernetes 资源定义Nomad 工作规范Docker 编排 文档。这些可能参数化也可能不参数化;也就是说,除非你知道一些模板语言,像 Kubernetes 中的 Helm,否则你会发现你使用了很多 sed -i 这样的命令。

发现

你怎么知道有哪些程序和服务可用,以及如何使用它们?在 *nix 系统中通常都有一个包管理器和一个很好用的 man 页面;使用它们,应该能够回答你所有的问题。在微服务的设置中,在寻找一个服务的时候会相对更自动化一些。除了像 Airbnb 的 SmartStackNetflix 的 Eureka 等可以定制以外,通常还有基于环境变量或基于 DNS 的方法,允许您动态的发现服务。同样重要的是,事实上 OpenAPI 为 HTTP API 提供了一套标准文档和设计模式,gRPC 为一些耦合性强的高性能项目也做了同样的事情。最后非常重要的一点是,考虑到开发者经验(DX),应该从写一份好的 Makefile 开始,并以编写符合 风格 的文档结束。

优点和缺点

*nix 系统和微服务都提供了许多挑战和机遇。

模块性

要设计一个简洁、有清晰的目的,并且能够很好地和其它模块配合的某个东西是很困难的。甚至是在不同版本中实现并引入相应的异常处理流程都很困难的。在微服务中,这意味着重试逻辑和超时机制,或者将这些功能外包到 服务网格 service mesh 是不是一个更好的选择呢?这确实比较难,可如果你做好了,那它的可重用性是巨大的。

可观测性

在一个 独石 monolith (2018 年)或是一个试图做任何事情的大型程序(1984 年),当情况恶化的时候,应当能够直接的找到问题的根源。但是在一个

yes | tr \\n x | head -c 450m | grep n

或者在一个微服务设置中请求一个路径,例如,涉及 20 个服务,你怎么弄清楚是哪个服务的问题?幸运的是,我们有很多标准,特别是 OpenCensusOpenTracing。如果您希望转向微服务,可预测性仍然可能是最大的问题。

全局状态

对于 *nix 程序来说可能不是一个大问题,但在微服务中,全局状态仍然是一个需要讨论的问题。也就是说,如何确保有效的管理本地化(持久性)的状态以及尽可能在少做变更的情况下使全局保持一致。

总结一下

最后,问题仍然是:你是否在使用合适的工具来完成特定的工作?也就是说,以同样的方式实现一个特定的 *nix 程序在某些时候或者阶段会是一个更好的选择,它是可能在你的组织或工作过程中的一个最好的选择。无论如何,我希望这篇文章可以让你看到 Unix 哲学和微服务之间许多强有力的相似之处。也许我们可以从前者那里学到一些东西使后者受益。


via: https://opensource.com/article/18/11/revisiting-unix-philosophy-2018

作者:Michael Hausenblas 选题:lujun9972 译者:Jamskr 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

零配置工具简化了信息收集,例如在某个命名空间中运行了多少个 pod。

最近我在纽约的 O'Reilly Velocity 就 Kubernetes 应用故障排除的主题发表了演讲,并且在积极的反馈和讨论的推动下,我决定重新审视这个领域的工具。结果,除了 kubernetes-incubator/spartakuskubernetes/kube-state-metrics 之外,我们还没有太多的轻量级工具来收集资源统计数据(例如命名空间中的 pod 或服务的数量)。所以,我在回家的路上开始编写一个小工具 —— 创造性地命名为 krs,它是 Kubernetes Resource Stats 的简称 ,它允许你收集这些统计数据。

你可以通过两种方式使用 mhausenblas/krs

  • 直接在命令行(有 Linux、Windows 和 MacOS 的二进制文件),以及
  • 在集群中使用 launch.sh 脚本部署,该脚本动态创建适当的基于角色的访问控制(RBAC) 权限。

提醒你,它还在早期,并且还在开发中。但是,krs 的 0.1 版本提供以下功能:

  • 在每个命名空间的基础上,它定期收集资源统计信息(支持 pod、部署和服务)。
  • 它以 OpenMetrics 格式公开这些统计。
  • 它可以直接通过二进制文件使用,也可以在包含所有依赖项的容器化设置中使用。

目前,你需要安装并配置 kubectl,因为 krs 依赖于执行 kubectl get all 命令来收集统计数据。(另一方面,谁会使用 Kubernetes 但没有安装 kubectl 呢?)

使用 krs 很简单。下载适合你平台的二进制文件,并按如下方式执行:

$ krs thenamespacetowatch
# HELP pods Number of pods in any state, for example running
# TYPE pods gauge
pods{namespace="thenamespacetowatch"} 13
# HELP deployments Number of deployments
# TYPE deployments gauge
deployments{namespace="thenamespacetowatch"} 6
# HELP services Number of services
# TYPE services gauge
services{namespace="thenamespacetowatch"} 4

这将在前台启动 krs,从名称空间 thenamespacetowatch 收集资源统计信息,并分别在标准输出中以 OpenMetrics 格式输出它们,以供你进一步处理。

 title=

krs 实战截屏

也许你会问,Michael,为什么它不能做一些有用的事(例如将指标存储在 S3 中)?因为 Unix 哲学

对于那些想知道他们是否可以直接使用 Prometheus 或 kubernetes/kube-state-metrics 来完成这项任务的人:是的,你可以,为什么不行呢? krs 的重点是作为已有工具的轻量级且易于使用的替代品 —— 甚至可能在某些方面略微互补。

本文最初发表在 Medium 的 ITNext 上,并获得授权转载。


via: https://opensource.com/article/18/11/kubernetes-resource-statistics

作者:Michael Hausenblas 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出