后台回复【资料包】获取学习资料
原文:道客船长
大部分上了私有容器云的企业,开发人员希望能有执行 kubectl 命令的能力,但出于运维安全性的考虑,他们不能随意 SSH 登陆集群节点来执行命令行。
这个矛盾怎么解决呢?
一个好办法是,通过在云平台上使用浏览器打开命令行窗口,用 kubectl 命令行工具去管理、运维集群。
CloudTTY (Cloud Teletypewriter) 正好提供了这些功能。
CloudTTY 是一个云原生开源项目, 基于 kubernetes 之上,解决了一系列集群之上的 “网页命令行” 权限控制下的功能需求。
这个功能在公有云上大多都有,常被称作 cloudshell。但是在私有云场景,目前暂时没有任何一个开源项目能做到 K8s 原生化的 cloudshell 能力。
01
基本使用
CloudTTY 提供了 helm 的安装方式,目前最新版本是 v0.1.0,使用 helm 的安装命令:
helm repo add daocloud https://release.daocloud.io/chartrepo/cloudshell
helm install cloudtty --version 0.1.0 daocloud/cloudtty -n cloudtty-system --create-namespace
安装完检查 cloudTTY 的 operator 是否正常启动。
CloudTTY 提供了 cloudshell 的 crd,创建一个 cr 后,cloudTTY 的 operator 就会准备环境,当 cloudshell 状态为 Completed状态,就可以通过浏览器进行访问。
在创建 cr 之前,需要提供访问集群的 kubeconfig 的 configmap 在 example 中提供了一些 cr 的示例:
apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
name: cloudshell-sample
spec:
configmapName: "my-kubeconfig"
commandAction: "bash"
ttl: 100
once: false
exposureMode: "NodePort"
cleanup: true
重要参数:
- ConfigmapName:集群的 kubeconfig 文件,使用 configmap 挂载到 pod 中方式。如果是多集群,必须要保证网络的连通性 (如果是本机集群,可以不用提供 kubeconfig,此功能会在 v0.2.0 版本开放)。
- CommandAction:执行的初始化命令,也可以指定 kubectl exec 或者 kubectl logs 来进入容器和查看容器日志。
- TTL:cloud shell 的存活时间,时间过期会断开连接并销毁容器。
- Once:访问 cloudTTY 服务的有效连接数,默认为 false,如果设置为 true,将只能访问一次。如果想要窗口多开,必须将此参数设置为 false。
- ExposureMode:cloudTTY 服务的暴露方式,目前支持 ClusterIP、NodePort、Ingress、VirtualService 4 种模式,不同的模式将创建不同的资源提供路由的功能。
- Cleanup:TTL 超时后是否销毁 cloudshell 资源。
我们可以使用以下命令快速创建 cloudshell 的实例:
kubectl apply -f https://github.com/cloudtty/cloudtty/blob/main/config/samples/cloudshell_v1alpha1_cloudshell.yaml
等待 cr 创建完以后就可以看见以下的状态:
$kubectl get cloudshell -w
NAME USER COMMAND TYPE URL PHASE AGE
cloudshell-sample root bash NodePort 192.168.4.1:30167 Ready 31s
cloudshell-sample2 root bash NodePort 192.168.4.1:30385 Ready 9s
当 cloudshell 的状态为 Ready 时,就表示可以在浏览器中进行访问了。
02
运行原理
1. CloudTTY 是基于 ttyd 的服务,当创建 cloudshell 的 cr 后,operator 会创建一个运行 ttyd 的 job 服务,并将 configmap 挂载到 pod 里面去,并设置必要的环境变量,保证 ttyd 的服务运行环境。然后提供了从外部环境访问服务的资源。其中 service 是必需的资源,无论是使用 ingress 还是 stio 的 virtaulService 进行负载。
2. 当 job 和 pod 都运行成功以后,会将访问点设置到 AccessUrl 中。
3. 当 job 在 TTL 或者其他原因结束之后,一旦 job 变为 Completed,cloudshell 的状态也会变 Completed。我们可以设置当 cloudshell 的状态为 Completed 时,同时删除相关联的资源。
03
服务暴露
CloudTTY 提供了 4 种模式来暴露后端的服务: ClusterIP、NodePort、Ingress、VitualService来满足不同的使用场景:
- ClusterIP:默认的模式,在集群中创建 ClusterIP 类型的 Service 资源。适用于第三方集成 cloudtty 服务,用户可以选择更加灵活的方式来暴露自己的服务。
- NodePort:最简单的暴露服务模式,在集群中创建 NodePort 类型的 Service 资源。可以用过节点 IP 和 对应的端口号访问 cloudTTY 服务。
- Ingress:在集群中创建 ClusterIP 类型的 Service 资源,并创建 Ingress 资源,通过路由规则负载到 Service 上。适用于集群中使用 Ingress Controller 进行流量负载的情况。创建 cr 必须指定 ingress 必要参数,如果集群中没有默认的 IngressClass,必须制定 ingressClassName 参数。
apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
name: nginx-demo
namespace: "cloudtty-system"
spec:
configmapName: "my-kubeconfig"
runAsUser: "root"
commandAction: "bash"
exposureMode: "Ingress"
pathPrefix: "/apis/cloudtty.io/"
ttl: 100
once: false
ingressConfig:
ingressName: "cloudshell-ingress-demo"
namespace: "cloudtty-system"
ingressClassName: "nginx"
- VirtualService:在集群中创建 ClusterIP 类型的 Service 资源,并创建 VirtaulService 资源。适用于集群中使用 Istio 进行流量负载的情况。使用 virtaulService 的模式必须指定 istio gateway 的相关参数。
apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
name: vs-demo
namespace: "cloudtty-system"
spec:
configmapName: "my-kubeconfig"
runAsUser: "root"
commandAction: "bash"
exposureMode: "VirtualService"
pathPrefix: "/apis/cloudtty.io/"
ttl: 100
once: false
virtualServiceConfig:
virtualServiceName: "cloudshell-vs-demo"
namespace: "cloudtty-system"
gateway: "istio-system/istio-gateway"
export_to: "istio-system"
04
特别鸣谢
这个项目的很多技术实现都是基于 https://github.com/tsl0922/ttyd,非常感谢 tsl0922 yudai 和社区,前端 UI 也是从 ttyd 项目衍生出来的,另外镜像内所使用的 ttyd 二进制也来源于这个项目。
CloudTTY 初衷是做一个小而美的项目,目前基本功能已经成熟,在将来我们会更加完善我们的功能,非常欢迎大家的试用,有任何的问题都在我们的社区提 issue。
项目地址:
https://github.com/cloudtty/cloudtty
- END -