开源引领 | CloudTTY 入选 CNCF 全景图

248 阅读6分钟

图片

近日道客船长获悉一款专为 Kubernetes 定制的 Cloud Shell 开源产品入选了 CNCF 全景图的应用定义及镜像构建 [1] ****区。

这款 Cloud Shell 产品名为 **CloudTTY [2] **,意指云原生虚拟控制台。在当今复杂多变的多云环境中,如果能在网页上嵌入一层 Shell 就可以操纵所有多云资源,无需下载克隆或在本地搭建环境,这会让一切变得简单。而这就是 CloudTTY 的设计初衷,其开发团队希望在日趋复杂的 Kubernetes 容器云环境中,能够为所有开发者提供一个简单的 Shell 入口。

CloudTTY 秉承了 ttyd[3] 从网页上访问终端命令行的理念:小巧轻量、简单易用。如今已内置到 DCE 5.0[4] 作为 Kubernetes Cloud Shell(Web Terminal)部署到了生产环境,是云原生行业内第一个开源的 Kube Cloud Shell 技术,目前已被 Kubevela 等项目采用。

01

**适用场景 **

CloudTTY 适用于以下几个场景

  1. 如果企业正使用容器云平台来管理 Kubernetes,但由于安全原因,无法随意 SSH 到主机上执行 kubectl 命令,这就需要一种 Cloud Shell 能力。

  2. 在浏览器网页上进入运行中的容器 (kubectl exec) 的场景。

  3. 在浏览器网页上能够滚动展示容器日志的场景。

CloudTTY 的网页终端使用效果如下:

**,时长00:32

如果将 CloudTTY 集成到 DCE 5.0 或你的 UI,最终效果 demo 如下:

图片

02

工作原理

图片

CloudTTY 的工作原理如下:

  1. Operator 会在对应的命名空间(Namespace)下创建同名的 job 和 service。如果使用 Ingress 或者 VitualService 模式,还会创建对应的路由信息。

  2. 当 Pod 运行状态为 Ready 之后,就将访问点写入 cloudshell 的 status 里。

  3. 当 Job 在 TTL 之后或者因其他原因结束之后,一旦 Job[5] 状态变为 Completed,cloudshell 的状态也会变为 Completed。你可以设置当 cloudshell 的状态为 Completed 时,同时删除相关联的资源。

  4. 当 cloudshell 被删除时,会自动删除对应的 Job 和 Service (通过 ownerReference)。如果使用 Ingress 或者 VitualService 模式时,还会删除对应的路由信息。

03

安装****

CloudTTY 的安装比较简单,参照以下步骤进行安装。

  1. 安装并等待 Pod 运行起来。
  helm repo add cloudtty https://cloudtty.github.io/cloudtty
  helm repo update
  helm install cloudtty-operator --version 0.5.0 cloudtty/cloudtty
  kubectl wait deployment cloudtty-operator-controller-manager --for=condition=Available=True
  1. 创建 CR,启动 cloudtty 的实例,并观察其状态。
  kubectl apply -f https://raw.githubusercontent.com/cloudtty/cloudtty/v0.5.0/config/samples/local_cluster_v1alpha

更多范例,参见 config/samples/[6]。

  1. 观察 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,并且 URL 字段出现之后,就可以通过该字段的访问方式,在浏览器打开:

图片

04

构建自定义镜像

当 cloudshell 对象状态变为 Ready,并且 URL 字段出现之后,就可以通过该字段的访问方式,在浏览器打开:

大多数用户除了使用基本的 kubectl 工具来管理集群外,还需要更多丰富的工具来管理集群。可以基于 cloudshell 的基础镜像来自定义,下面是一个添加多云 karmadactl 工具的一个案例:

  • 修改 Dockerfile.example[7] 文件。
FROM ghcr.io/cloudtty/cloudshell:v0.5.0

RUN curl -fsSLO https://github.com/karmada-io/karmada/releases/download/v1.2.0/kubectl-karmada-linux-amd64.tgz \
    && tar -zxf kubectl-karmada-linux-amd64.tgz \
    && chmod +x kubectl-karmada \
    && mv kubectl-karmada /usr/local/bin/kubectl-karmada \
    && which kubectl-karmada

ENTRYPOINT ttyd
  • 重新构建带有 karmadactl 工具的新镜像:
docker build -t <IMAGE> . -f docker/Dockerfile-webtty

05

使用自定义镜像

有两种方式来设置 cloudshell 的自定义镜像:

  1. 直接通过 cl****oudshell CR 字段 spec.image 来设置。
apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
  name: cloudshell-sample
spec:
  secretRef:
    name: "my-kubeconfig"
  image: ghcr.io/cloudtty/customize_cloudshell:latest
  1. 在安装 cloudtty 时可以设置 JobTemplate 镜像参数来运行自己的 cloudshell 的镜像。
helm install cloudtty-operator --version 0.5.0 cloudtty/cloudtty --set jobTemplate.image.registry=</REGISTRY> --set jobTemplate.image.repository=</REPOSITORY> --set jobTemplate.image.tag=</TAG>

如果你已经安装了 CloudTTY,还可以修改 JobTemplate 的 configmap 来设置 cloudshell 的镜像。

06

进阶用法

进阶 1:用 CloudTTY 访问其他集群

如果是本地集群,可以不提供 kubeconfig,CloudTTY 会创建具有 cluster-admin 角色权限的`serviceaccount。在容器的内部,kubectl 会自动发现 ca 证书和 token。如果有安全方面的考虑,你也可以自己提供 kubeconfig 来控制不同用户的权限。

如果是远端从集群,CloudTTY 可以执行 kubectl 命令行工具。若访问集群,需要指定 kubeconfig。用户需自己提供 kubeconfig 并储存在 Secret 中,并且在 cloudshell 的 CR 中,通过 spec.secretRef.name 指定 Secret 的名称。CloudTTY 会自动挂载到容器中,请确保服务器地址与集群网络连接顺畅。

设置 kubeconfig 的步骤:准备 kube.conf,放入 Secret 中,并确保密钥/证书是 base64 而不是本地文件

 kubectl create secret generic my-kubeconfig --from-file=kube.config

进阶 2:用 CloudTTY 访问集群上的 node 主机

可以在 cloudshell 的基础镜像中集成 kubectl-node-shell [8]  插件,使用该插件可以通过 kubectl 的命令登录到集群中任意节点上。该命令将会在节点上启动一个具有特权 Pod。如果对安全性要求非常高,请谨慎使用此功能。

修改 Dockerfile.example 文件。

FROM ghcr.io/cloudtty/cloudshell:v0.5.2

RUN curl -fsSLO https://github.com/kvaps/kubectl-node-shell/raw/master/kubectl-node_shell \
  && chmod +x ./kubectl-node_shell \
  && mv ./kubectl-node_shell /usr/local/bin/kubectl-node_shell \
  && which kubectl-node_shell

ENTRYPOINT ttyd

重新构建带有 node-shell 工具的新镜像:

docker build -t <IMAGE> . -f docker/Dockerfile.example

下面是一个使用的示例:

apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
  name: cloudshell-node-shell
spec:
  configmapName: "<KUBECONFIg>"
  commandAction: "kubectl node-shell <NODE_NAME>"

更多的示例可以参考 kubectl-node-shell。

注意:集群中如果已经存在 PodSecurity 和 PSP 等安全性策略,可能会影响该功能的使用。

进阶 3:修改服务暴露方式

CloudTTY 提供了以下 4 种服务暴露模式以满足不同的使用场景。

ClusterIP:在集群中创建 ClusterIP 类型的 Service[9] 资源。
适用于第三方集成 CloudTTY 服务,用户可以选择更加灵活的方式来暴露自己的服务。

NodePort:这是默认的模式,也是最简单的暴露服务模式。
在集群中创建 NodePort 类型的 Service 资源,通过节点 IP 和对应的端口号访问 CloudTTY 服务。

Ingress:在集群中创建 ClusterIP 类型的 Service 资源,并创建 Ingress 资源,通过路由规则负载到 Service 上。
适合在集群中使用 Ingress Controller[10] 进行流量负载的情况。

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 (istio):在集群中创建 ClusterIP 类型的 Service 资源,并创建 VirtaulService 资源。
适合在集群中使用 Istio[11] 进行流量负载的情况。

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"

CloudTTY 初衷是做一个小而美的项目,目前基本功能已经成熟,在将来我们会更加完善我们的功能,非常欢迎大家的试用,有任何的问题都可以在我们的社区提 issue。

现在扫描小助手二维码,备注「CloudTTY」可加入技术交流群。

图片

相关链接

[1] cncf landscape:landscape.cncf.io/?selected=c…] CloudTTY 仓库地址:github.com/cloudtty/cl…] ttyd:
github.com/tsl0922/tty…] DCE 5.0:
docs.daocloud.io/[5] Job:kubernetes.io/zh-cn/docs/…] config/samples/:github.com/cloudtty/cl…] Dockerfile.example:github.com/cloudtty/cl…] kubectl-node-shell:github.com/kvaps/kubec…

[9] Service:

kubernetes.io/zh-cn/docs/…

[10] Ingress Controller:

kubernetes.io/zh-cn/docs/…

[11] Istio:

github.com/istio/istio


 本文作者 

图片

要海峰

现任「DaoCloud 道客」高级文档工程师

K8s-zh-owner,Istio maintainer,otel 等 Member