如何像 Sealos 一样在浏览器中打造一个 Kubernetes 终端?
作者:槐佳辉。Sealos maintainer
在 Kubernetes 的世界中,命令行工具(如 kubectl 和 helm)是我们与集群交互的主要方式。然而,有时候,我们可能希望能够在 Web 页面中直接打开一个终端,执行这些命令,而不需要在本地环境中安装和配置这些工具。本文将深入探讨如何通过 Kubernetes 自定义资源定义(CRD)实现这个功能,并通过一个真实的示例展示其设计和实现过程。

Sealos 中的 App Launchpad 和 Database 等应用为我们屏蔽掉了 kubernetes 资源层面的逻辑,抽象为应用层,但是对应更为复杂的情况,可能需要我们更原生的操作 kubernetes。
如下所示,在 Terminal 中与 K8s API Server 交互:
查看 Pod 资源(kubernetes 最小调度单位,真正运行容器的资源):
$ kubectl get pod

查看存储 pvc 资源(容器挂载的存储资源,如 App Launchpad 中指定的存储):
$ kubectl get pvc

Terminal 高级用法
Terminal 还支持更为复杂的操作。
Terminal + App Launchpad 一键交互
可以直接通过终端 App 进入每个应用所在容器的终端。假设你在应用管理中部署了一个应用 Nginx,可以直接进入 Nginx 应用的详情页面,依次点击详情右侧的三个点,再点击「终端」,便进入了 Nginx 应用的终端。


Terminal + Database 一键直连
在终端中一键直连数据库 App 中创建的数据库。
进入数据库详情页面,点击左侧的「一键连接」:

跳转到 Terminal 并直连数据库:

功能描述
这个功能的核心是一个名为 Terminal 的 Kubernetes CRD。用户可以在 Web 页面中创建一个新的 Terminal CRD,然后页面会打开一个新的 Terminal。这个 Terminal 具有指定 Kubernetes Namespace 的访问权限,可以执行 kubectl,helm 等命令。
下面是一个 Terminal CRD 的示例:
spec:
apiServer: https://kubernetes.default.svc.cluster.local:443
ingressType: nginx
keepalived: 4h
replicas: 1
token: xxxxx
status:
availableReplicas: 1
domain: https://xxxxxx.cloud.sealos.io
CRD 字段说明
在 Terminal CRD 的 spec 部分,以下是各字段的说明:
apiServer: Kubernetes API 服务器的地址。Terminal 使用这个地址与 Kubernetes API 服务器通信。ingressType: Ingress 控制器的类型,可以是nginx或apisix。keepalived: Terminal 的生存时间。例如,4h表示 Terminal 在被创建 4 小时后会被自动删除。replicas: Terminal 的副本数。目前只支持1。token: Kubernetes API 服务器的访问令牌。Terminal 使用此令牌进行鉴权。
在 status 部分,以下是各字段的说明:
availableReplicas: 可用副本数量。domain: 用于在 Web 中与 Terminal 交互的地址。
创建 Terminal CRD 后,Web 页面中就会打开一个新的 Terminal。用户可以在这个 Terminal 中执行 kubectl,helm 等命令。
设计与实现
Terminal 功能的设计与实现包括以下几个关键部分:
Terminal Controller
Terminal Controller 是 Terminal 功能的核心部分。它负责监听 Terminal CRD 的创建、更新和删除事件,并响应这些事件。
Terminal Pod
Terminal Pod 是实际运行的 Terminal。它运行一个特殊的 Docker 镜像,这个镜像包含了 kubectl,helm 等命令行工具,以及一个 Web 终端服务器(例如 ttyd)。Pod 内的 Web 终端服务器监听 8080 端口,并提供 Web 终端服务。
Service 和 Ingress
Terminal Controller 为每个 Terminal CRD 创建一个对应的 Kubernetes Service 和 Ingress。Service 将网络流量路由到 Terminal Pod,Ingress 将外部访问请求路由到 Service。
Terminal Docker 镜像
Terminal Docker 镜像是 Terminal Pod 运行的镜像。它基于 Ubuntu 20.04,包含了 kubectl,helm 等命令行工具,以及一个 Web 终端服务器 ttyd。此外,该镜像还包含了 MySQL,MongoDB,Redis 的客户端,以便用户能够直接在 Terminal 中连接和操作这些数据库。
这个 Docker 镜像的构建过程如下:
安装必要的软件包,包括
kubectl,helm,vim等。将 Web 终端服务器
ttyd和一个启动脚本start-terminal.sh添加到镜像中。设置
ttyd服务器监听 8080 端口,并配置ttyd服务器的启动参数,包括 Kubernetes API 服务器的地址和访问令牌。
这个 Docker 镜像的 Dockerfile 如下:
FROM ubuntu:20.04
LABEL org.opencontainers.image.authors="labring"
USER root
ENV HOME /root
ARG kubeVersion=1.25.6
ARG ttydVersion=1.7.3
ARG helmVersion=3.12.0
ARG ARCH
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /root
COPY ./inline.html ./index.html
COPY vim/ .
COPY scripts/start-terminal.sh /usr/bin/
COPY scripts/ttyd-kubectl.sh /usr/bin/
RUN arch && \
apt-get update && \
apt-get install -y --no-install-recommends -o Acquire::http::No-Cache=True \
ca-certificates curl wget bind9-utils git g++ gcc libc6-dev make pkg-config vim \
ncurses-dev libtolua-dev exuberant-ctags gdb dnsutils iputils-ping net-tools postgresql-client && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
chmod a+x /usr/bin/ttyd-kubectl.sh && \
bash /usr/bin/ttyd-kubectl.sh && \
vim +PlugInstall +qall && \
chmod a+x /usr/bin/start-terminal.sh
ENV USER_TOKEN ""
ENV APISERVER "https://apiserver.cluster.local:6443"
ENV USER_NAME "admin"
ENV NAMESPACE "default"
EXPOSE 8080
CMD ["sh","/usr/bin/start-terminal.sh"]
镜像 Dockerfile:https://github.com/labring-actions/cluster-image/blob/main/dockerimages/terminal/latest/Dockerfile
镜像托管 GitHub 自动化构建仓库:https://github.com/labring-actions/cluster-image
Terminal 删除和生存时间
Terminal Controller 使用 Kubernetes 的 Finalizer 机制来处理 Terminal CRD 的删除事件。当 Terminal CRD 被删除时,Finalizer 会阻止 Kubernetes 立即删除 CRD,而是等待 Terminal Controller 清理与 Terminal CRD 相关的资源(如 Deployment,Service 和 Ingress)后再删除 CRD。
此外,Terminal Controller 还使用 Keepalive 机制来自动删除过期的 Terminal。Terminal 的生存时间由 keepalived 字段指定,当 Terminal 存在的时间超过 keepalived 指定的时间后,Terminal Controller 会自动删除 Terminal。
前后端交互流程
下面是用户从点击 Terminal 按钮到进入 Terminal 的具体流程:

用户在 Web 页面中点击 Terminal 按钮,页面会发送一个请求到后端,请求中包含了 Terminal 的配置信息(如 Kubernetes Namespace 和生存时间)。
后端接收到请求后,会创建一个新的
TerminalCRD,CRD 中包含了 Terminal 的配置信息。TerminalController 监控到新的TerminalCRD 被创建,会创建一个对应的TerminalPod,Pod 运行的 Docker 镜像包含了kubectl,helm等命令行工具,以及一个 Web 终端服务器。TerminalController 还会创建一个对应的 Kubernetes Service 和 Ingress,Service 将网络流量路由到TerminalPod,Ingress 将外部访问请求路由到 Service。后端会从
TerminalCRD 的status字段中获取到 Terminal 的域名,并将这个域名返回给前端。前端接收到 Terminal 的域名后,会在新的标签页中打开这个域名,用户就可以看到一个新的 Terminal,并可以在这个 Terminal 中执行
kubectl,helm等命令。
自定义配置
多种 Ingress 控制器支持
Terminal 支持多种 Ingress 控制器,包括 Nginx 和 Apisix。用户可以根据自己的实际情况选择合适的 Ingress 控制器。
生存时间设置
用户可以设置 Terminal 的生存时间。Terminal 在被创建一段时间后会被自动删除,这样可以防止 Terminal 长时间未使用而占用系统资源。
未来的改进
更多的命令行工具支持
在 Terminal Docker 镜像中添加更多的命令行工具,如 istioctl,kn 等,这样用户就可以在 Terminal 中执行更多的操作。
更多的 Ingress 控制器支持
支持更多的 Ingress 控制器,如 Traefik,HAProxy 等,用户可以根据自己的实际情况选择合适的 Ingress 控制器。
使用 WebSocket 通信
通过 Ingress 暴露 WebSocket 服务。用户可以在 Web 页面中打开一个终端,通过 WebSocket 与 Kubernetes 集群进行交互。相比于 HTTP 协议,WebSocket 提供了更高效、实时的双向通信能力,极大地提升了用户的使用体验。
权限控制
增加权限控制功能,后续增加企业协作功能,多用户共享 namespace,terminal 通过获取相应权限来获得对应用户空间的权限,如 manager, developer 等。
集成更多开发工具
除了 kubectl 和 helm 外,还可以在 Terminal 中集成更多的开发和调试工具,如 git,curl,jq 等。
个性化配置
用户可以根据自己的需要,配置 Terminal 的外观,如主题颜色,字体大小等。也可以配置 Terminal 的行为,如命令历史记录的长度,键盘快捷键等。
结论
通过 Kubernetes 的 CRD 功能,我们可以轻松地在 Web 页面中添加一个功能强大的 Terminal。用户可以在这个 Terminal 中执行各种命令,更好地与 Kubernetes 集群交互。这不仅提高了用户的工作效率,也极大地提升了用户的使用体验。
如何像 Sealos 一样在浏览器中打造一个 Kubernetes 终端?的更多相关文章
- 网易笔试题:浏览器中输入一个url后回车到返回页面信息的过程
You enter a URL into the browser输入一个url地址 The browser looks up the IP address for the domain name浏览器 ...
- 如何在Microsoft Edge浏览器中添加一个Hello World插件
注:本文提到的代码示例下载地址> How to add a Hello World extension to Microsoft Edge Microsoft Edge 随着Win 10一起推出 ...
- 用户在浏览器中输入一个url发生的奥秘
在HTTP 客户端向服务器发送报文之前,需要用网际协议(Internet Protocol,IP)地址和端口号在客户端和服务器之间建立一条TCP/IP 连接. http://207.200.83.29 ...
- JavaScript问题——在浏览器中每一个元素都有一个offsetParent属性,这个属性是什么?
原文链接http://www.cnblogs.com/zcjnever/archive/2011/04/21/2023133.html Javascript中的offsetParent属性 支持的浏览 ...
- 在浏览器中输入一个URL后都发生了什么
这道题目没有所谓的完全的正确答案,这个题目可以让你在任意的一个点深入下去, 只要你对这个点是熟悉的.以下是一个大概流程: 浏览器向DNS服务器查找输入URL对应的IP地址. DNS服务器返回网站的IP ...
- 关于点击ztree的节点将页面生成到easyui的新增选项卡(easyui-tabs)时,总是在浏览器中生成一个新的页面的问题
最近的项目中用到了easyui,还有ztree菜单.在这里将我遇到的一些问题写出来算是做个笔记吧. 这是我头一次在博客园里分享代码,我的处女作,写的不好的地方还望各位见谅! 由于很久没有写过前台的东西 ...
- 解释一下,在你往浏览器中输入一个URL后都发生了什么,要尽可能详细
这道题目没有所谓的完全的正确答案,这个题目可以让你在任意的一个点深入下去, 只要你对这个点是熟悉的.以下是一个大概流程: 浏览器向DNS服务器查找输入URL对应的IP地址. DNS服务器返回网站的IP ...
- 当在浏览器中输入一个url后回车,后台发生了什么?比如输入url后,你看到了百度的首页,那么这一切是如何发生的呢?
简单来书有以下步骤: 查找域名对应的IP地址.这一步会依次查找浏览器缓存,系统缓存,路由器缓存,ISPDNS缓存,13台根域名服务器. 向IP对应的服务器发送请求. 服务器响应请求,发回网页内容. 浏 ...
- [置顶] 如何在浏览器中打开PDF文件并实现预览的思路与代码
编写项目遇到一个需要在浏览器中打开PDF文件的问题.最终实现效果如下: 其实也就是简单的在浏览器中实现一个打开pdf文件,并有类似预览功能的边框. 其实在网上经常见到类似的页面,在浏览器中打开pdf文 ...
- 【转】浏览器中的data类型的Url格式,data:image/png,data:image/jpeg!
所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些"小"的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag, ...
随机推荐
- std::aligned_alloc
定义于头文件 <cstdlib> (c++) void * aligned_alloc ( std::size_t alignment, std::size_t size); (c++17 ...
- SpringBoot之MVC配置(WebMvcConfigurer详解)
一:基本介绍 Spring MVC是一种常用的Java Web框架,它提供了一种基于MVC模式的开发方式,可以方便地实现Web应用程序.在Spring MVC中,WebMvcConfigurer是一种 ...
- mysql where和having的用法例子
结论:想在分组之后在进行过滤就要使用having了,如果只是对指定的行进行过滤的话,那么就需要使用where了
- zynq7000 emc启动及其加速
背景需求 ZYNQ 7000系统在出场时需要将固件从eMMC启动,原因有2: FLASH存储空间小: SD卡容易脱落,不适合产品存放系统文件: 需要注意,ZYNQ7000 系列不支持eMMC作为BOO ...
- 文心一言 VS 讯飞星火 VS chatgpt (65)-- 算法导论6.5 4题
四.在 MAX-HEAP-INSERT 的第 2行,为什么我们要先把关键字设为 -∞ ,然后又将其增加到所需的值呢? 文心一言: 在 MAX-HEAP-INSERT 算法的第二行将关键字设为 -∞,是 ...
- javascript中一些难以理解的专有名词 2(也不是很专有)
作用域链 让人迷惑的例子 function foo() {console.log(v)} function foo1() { var v = "v1" foo() console. ...
- python连接数据库及查询包含中文错误解决方法
使用MySQLdb库来连接数据库 import MySQLdb conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='', por ...
- rman catalog 遇到的一个错误
[oracle@source admin]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Thu Jun 22 09: ...
- pandas读取mysql并导出为excel
前言 业务需要从数据库导出数据为excel,并设置成自动化.这里用pandas写的数据导入导出,还算方便.配合crontab + shell脚本使用,每天晚上自动生成excel,然后cp到指定目录.s ...
- Typora 主题,设置代码块Mac风格三个小圆点
目录 打造Typora主题 1 typoa样式修改步骤 1.1 第一步打开偏好设置 1.2 第二步打开主题文件夹 2 标题添加颜色 3 表格优化 4 代码块Mac风格三个圆点 5 主题总代码如下: 打 ...