内容简介:我用50多行Bash代码实现了我称之为“世界上最简单的Kubernetes仪表板”,它被称为k1s,本文将介绍如何使用它以及它是如何工作的。当然,“世界上最简单”并不是一个很严格的说辞。你可以在GitHub上的仓库
我用50多行Bash代码实现了我称之为“世界上最简单的Kubernetes仪表板”,它被称为k1s,本文将介绍如何使用它以及它是如何工作的。
当然,“世界上最简单”并不是一个很严格的说辞。
你可以在GitHub上的仓库 weibeld/k1s 上找到完整代码和详细使用说明。
概述
k1s大致如下图:
仪表板展示了任意命名空间(或跨所有命名空间)中任何类型的资源列表,并实时更新它。某些类型的资源会显示额外的信息,例如Pod的当前状态,Deployment中所需的副本数和实际数量。
你可以运行多个k1s实例从而可以同时观察多个资源类型的更新。
下图是运行三个仪表板实例的例子,一个用于Deployment,一个用户ReplicasSet,还有一个用于Pod(使用tmux运行)。然后对Deployment上执行一些伸缩操作和滚动更新。
请注意,你可以实时观察Deployment、其管理的ReplicaSets和Pods之间的交互。这有可能提供许多认知,有助于了解Deployment和其他资源的工作原理。
安装
如果你在macOS上使用homebrew,你可以这样安装:
$ brew install weibeld/core/k1s
如果是其他情况,你可以参考下面脚本安装它:
{ wget https://raw.githubusercontent.com/weibeld/k1s/master/k1s chmod +x k1s mv k1s /usr/local/bin }
k1s依赖于机器上安装的以下工具:
- jq
- watch
- curl
- kubectl
可能你已经拥有大部分工具,要是没有的话你可以在GitHub仓库上找到安装向导。
使用
k1s是一个可直接在你本机运行的Bash脚本,它的命令行接口如下:
$ k1s [namespace] [resource-type]
两个额外的命令行参数分别是:
default pods
如果需要跨所有命名空间观察资源,你可以指定命名空间参数为 -
。
资源类型参数的值可以指定为Kubernetes接受的任意名称,包括复数模式,单数模式和简写(如果可用的话)。例如以下参数都是有效的:
- deployments, deployment, deploy
- replicasets, replicaset, rs
- services, service, svc
k1s是由本机上的 kubeconfig
文件支撑的。这意味着k1s始终是连接到你的 kubeconfig
文件中指定的集群。换句话说,k1s默认使用与kubectl使用的同一个集群。
如要退出仪表板请键入Ctrl-C。
实现
现在,我们来谈谈k1s的实现,上面提到k1s是一个Bash脚本,以下是k1s v0.1.0版本的完整代码(内容过多不做展示请直接浏览GitHub仓库访问)。
下面我们将一步步阅读项目代码。不过首先我们先来讨论一下k1s所基于的思路。
基础机制
以下是k1s工作的主要部分:
- 使用
kubectl proxy
用于轻松请求Kubernetes API服务(第20行) - 使用
curl
执行一个向Kubernetes API服务请求指定资源类型的watch
监视请求(第32行)。这将向API服务器创建一个持久连接,该连接返回任意ADDED
、MODIFIED
或DELETED
类型的JSON格式资源事件流。 - 使用
jq
解析每个事件并从中提取信息,例如事件相关的资源的名称。将该信息作为额外的记录行写入到文件系统上的一个文件(称之为状态文件)。如果资源在文件中已存在,则更新它,如果资源被删除,则从状态文件中删除具体行(第48-50行) - 使用
watch
定期更新显示该状态文件(第53行)。这给人一种动态全屏终端应用的印象。
简而言之,k1s会不断地将某个资源类型的状态整合到一个文件中,并将这个文件用 watch
显示出来,这样你就可以实时观察到任何更新。
现在我们来看看实际代码。
具体实现
k1s脚本从以下代码行开始:
这将执行一些基本检查和初始化:
-v/--version
接下来的两行代码如下:
这定义了两个Bash函数用于输出ANSI转义序列,用来以特定的颜色打印文本。这些函数将在以下用来给k1s的输出着色。
接下来是这行:
此行打印启动k1s后立即显示的加载指示器。此任务由一个每0.1秒打印字符 .
的无限循环组成,并作为后台进程启动。当k1s初始化完成之后该进程将会被杀死。
接着是下一段代码:
此段代码实现了k1s的主要初始化步骤。它确定了用户请求的资源类型和命名空间的Kubernetes API路径:
- 第12行启用Bash的
pipefail
选项,如果管道语句中包含的任何一条命令返回一个非零的退出码,那么该选项就会使整个管道语句返回一个非零的退出码。这是后续命令正常执行的前提。 - 第13行执行了请求的资源类型和命令空间的
kubectl get
请求并从输出中提取相应的Kubernetes API路径。这里的诀窍是通过提高kubectl
的输出级别(-v=6),kubectl会输出它向Kubernetes API服务器发出的HTTP GET请求的确切URL。通过这个URL,可通过grep
和sed
提取出来。 - 第14行记录了13行中
kubectl get
的退出码,如果请求成功则退出码为零,否则为非零。退出码非零的很大可能是用户提交了一个无效的资源类型(例如使用dep替代deploy/deployment) - 第15行杀掉第10行开启的加载指示器后台进程。注意加载指示器的进程ID(PID)被指定为Bash内置变量
$!
。在Bash中$!
变量始终保存已启动的最后一个后台进程的进程ID。因为从第10行后没有其他后台进程启动,所以该变量保证是指向加载指示器进程。 - 第16行检查第13行
kubectl get
请求的退出码,如果退出码非零,则假设用户提供了一个无效的资源类型规范,之后脚本以相应的错误信息终止。
接下来的两行具有相当的装饰用途:
- 第17行检查提取的API路径是否包含了命名空间部分。如果没有,则代表着用户请求跨所有命名空间的资源类型或者是非命名空间级别的资源类型。在这种情况下,命名空间将会被设置并在仪表板中显示为为
-
。这修复了当用户指定了非命名空间级别资源却同时指定命名空间的情况。 - 第18行将从API路径中提取的用户请求的资源类型设置为相应资源的复数形式,该值会显示在仪表板的标题上。这意味着如果用户指定
deploy/deployment
来监视Deployments
,那么仪表板会在标题横幅处统一显示为deployments
。
紧接着是下面两行代码:
这两行脚本配置了 kubectl proxy
并在之后被用于连接Kubernetes API服务:
- 第20行启动
kubectl proxy
作为后台进程,该命令为Kubernetes API服务创建一个本地代理,并在本机监听一个随机端口(通过-p=0
指定)。该后台进程的输出被新文件描述符3捕获。 - 第21行从上一行的
kubectl proxy
的输出文件描述符中提取端口。知道这个端口号在后续代码中才能构建Kubernetes API服务的监视请求。
> 在这个 StackOverflow的回答 中,介绍了上述捕捉后台进程输出的技术。
接着是下一段代码:
这段代码创建并初始化状态文件,该文件之后会被 watch
命令调用显示:
- 第23行创建状态文件
- 第24-30行将标题横幅写入到状态文件。 标题横幅由(彩色的)k1s logo和其他一些信息组成,包括正在使用的命名空间和资源类型。
下一段代码如下:
这段代码执行向Kubernetes API服务发起的实际监视请求并处理事件流响应。以上代码实际上是单个Bash语句,其将 curl
命令输出到管道并通过 while
循环从管道中读取 curl
命令的输出:
- 第32行使用
curl
发起监视请求。URL由之前确定的Kubernetes API路径和kubectl proxy
端口号组成。监视请求返回的每个响应都是对应于一个资源事件的JSON单行。curl使用了-N
选项禁止输出缓冲,这样每一行在收到后就会立即输出。 - 第33行开启一个
while
循环读取curl
的每一行输出到名为event
的变量。该循环会无限运行,只有当用户键入Ctrl-C退出仪表板时才被终止。
循环体从34行开始到51行。开头的几行从JSON事件对象中提取一些数据,传递到循环的主体中:
jq
第36到41行以特别的方式处理Pods:
- 第37行提取Pod的当前阶段。阶段是对Pod状态的高级指示,如Running或Pending。
- 第38行确定Pod的
Ready
条件是否设置为True
。如果是的话,那么Pod中的所有容器都通过了就绪探测,Pod可以为用户请求提供服务。 - 第39行确定Pod的
PodScheduled
条件是否设置为True。如果是的话,那么Pod已被Kubernetes调度器分配了一个节点。 - 第40行确定k1s将显示的Pod的状态。默认情况下,k1s显示Pod的阶段。但是,在下面的情况下,行为会有所不同:如果Pod已经被调度,但目前还没有准备好,那么k1s显示NonReady而不是
phase
字段(此时phase
为Pending
)。这使得它更容易区分尚未调度的Pod和仅仅是临时暂停或终止的Pod。 - 第41行为Pod的状态指示器着色,以获得更好的视觉效果:如果状态为Running则为绿色,其他情况为黄色。
第42到45行以特别的方式处理Deployments、ReplicaSets和StatefulSets(这些都是Pod控制器)。
- 第43行确定Pod控制器指定的(需要的)副本的数量
- 第44行确定Pod控制器当前可用(准备好)的副本数量。
- 第45行格式化并着色副本指示器:如果可用的副本数量符合要求,则为绿色,否则为黄色。
接下来,第47行到51行根据事件的类型和上面确定的信息更新状态文件。
- 第47行启动一个
case
语句根据事件的类型采取不同的操作,事件类型可以是ADDED
、MODIFIED
或是DELETED
。 - 第48行处理
ADDED
事件:如果添加了一个资源,它的名称(以及之前确定的任何附加的资源类型特定信息)将被简单地追加为一个新行到状态文件中。 - 第49行处理
MODIFIED
事件:如果一个资源被修改(如Pod的相位改变),状态文件中该资源的现有行将被一个由新信息组成的新行取代。 - 第50行处理
DELETED
事件:如果资源被删除,状态文件中相应行也会被删除。
最后只剩下一行了:
此行执行 watch
命令来定时更新并显示状态文件在你的终端窗口。更新时间间隔设置为0.1秒,这个时间间隔小到足以让人眼看似 "实时"。
k1s的完整代码总共就只有这么多!
讨论和结论
正如其口号所说,k1s的重点是简单和简洁。这就带来了一些局限性,必须指出:
watch kubectl
当然,大多数这些限制可以通过用真正的编程语言(比如Go)实现k1s来解决,就像所有成熟的Kubernetes仪表盘一样。然而,k1s一开始也是作为实验性的,用尽可能简单的手段(和尽可能少的代码)来实现一些有用的东西。实际上,它一开始是一个Bash单行脚本,用于显示默认命名空间中的当前Pod的集合。
考虑到这一重点,该 工具 仍然被证明是令人惊讶的有用的(至少对于实验或教育用例),它可以作为围绕Kubernetes的高级脚本的基础。
本着这种精神,请尽情使用k1s,并提交问题和PR!
【原文链接】: The world’s simplest Kubernetes dashboard: k1s 翻译:冯旭松
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Qt自定义控件之仪表盘2--QPaint绘制仪表盘
- 手动实现一个速度仪表盘
- Qt自定义Widget之仪表盘
- WTF——码农专属终端的仪表板
- 开源仪表盘-Dashboard-C#/WF
- ClickHouse:创建漂亮的 Grafana 仪表盘
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C语言的科学和艺术
罗伯茨 / 翁惠玉 / 机械工业出版社 / 2005-3 / 55.00元
《C语言的科学和艺术》是计算机科学的经典教材,介绍了计算机科学的基础知识和程序设计的专门知识。《C语言的科学和艺术》以介绍ANSI C为主线,不仅涵盖C语言的基本知识,而且介绍了软件工程技术以及如何应用良好的程序设计风格进行开发等内容。《C语言的科学和艺术》采用了库函数的方法,强调抽象的原则,详细阐述了库和模块化开发。此外,《C语言的科学和艺术》还利用大量实例讲述解决问题的全过程,对开发过程中常见......一起来看看 《C语言的科学和艺术》 这本书的介绍吧!