简体中文 | 英文
像 ttyd 等项目已经非常成熟了,可以提供浏览器之上的终端的能力。
但是在 kubernetes 的场景下,我们需要能有更云原生的能力拓展:
比如 ttyd 在容器内运行,能够通过 NodePort\Ingress 等方式访问,能够用 CRD 的方式创建多个实例。
cloudtty 提供了这些功能,请使用 cloudtty 吧🎉!
-
很多企业使用容器云平台来管理 Kubernetes, 但是由于安全原因,无法随意 SSH 到主机上执行 kubectl 命令,就需要一种 Cloud Shell 的能力。
-
在浏览器网页上能够进入运行中的容器(
kubectl exec
)的场景。 -
在浏览器网页上能够滚动展示容器日志的场景。
如果将 CloudTTY 集成到您自己的 UI 里面,最终效果 demo 如下:
步骤1. 安装
helm repo add daocloud https://release.daocloud.io/chartrepo/cloudshell
helm install cloudtty-operator --version 0.2.0 daocloud/cloudtty
等待pod运行起来
kubectl wait deployment cloudtty-operator-controller-manager --for=condition=Available=True
步骤2. 创建CR,启动 cloudtty 的实例,并观察其状态
kubectl apply -f https://raw.githubusercontent.com/cloudtty/cloudtty/v0.2.0/config/samples/local_cluster_v1alpha1_cloudshell.yaml
更多范例,参见config/samples/
步骤3. 观察 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
字段出现之后,就可以通过该字段的访问方式,在浏览器打开,如下:
-
如果是本地集群,可以不提供 kubeconfig,cloudtty 会创建具有
cluster-admin
角色权限的serviceaccount
。在容器的内部,kubectl
会自动发现ca
证书和 token。如果有安全上的考虑,同样也可以自己提供 kubeconfig 来控制不同用户的权限。 -
如果是远端集群,cloudtty 执行 kubectl 命令行工具访问集群需要指定 kubeconfig。需要用户自己提供 kubeconfig 储存在 comfigmap 中,并且在
cloudshell
的 cr 中spec.configmapName
指定 configmap 的名称,cloudtty 会自动挂载到容器中。请确保 server 地址与集群网络连接是否顺畅。 设置 kubeconfig 的步骤:
准备kube.conf
,放入 configmap 中
- (第1步)
kubectl create configmap my-kubeconfig --from-file=kube.config`, 并确保密钥/证书是 base64 而不是本地文件
- (第2步)
编辑这个 configmap, 修改 endpoint 的地址,从 IP 改为 servicename, 如`server: https://kubernetes.default.svc.cluster.local:443`
Cloudtty 提供了4种模式来暴露服务: ClusterIP
, NodePort
, Ingress
, VitualService
来满足不同的使用场景:
-
ClusterIP: 在集群中创建 ClusterIP 类型的 Service 资源。适用于第三方集成 cloudtty 服务,用户可以选择更加灵活的方式来暴露自己的服务。
-
NodePort:默认的模式,最简单的暴露服务模式,在集群中创建 NodePort 类型的 Service 资源。可以用过节点 IP 和 对应的端口号访问 cloudtty 服务。
-
Ingress:在集群中创建 ClusterIP 类型的 Service 资源,并创建 Ingress 资源,通过路由规则负载到 Service 上。适用于集群中使用 Ingress Controller 进行流量负载的情况。
-
VirtualService (istio):在集群中创建 ClusterIP 类型的 Service 资源,并创建 VirtaulService 资源。适用于集群中使用 Istio 进行流量负载的情况。
-
Operator 会在对应的 NS 下创建同名的
job
和service
,如果使用 Ingress 或者 VitualService 模式时,还会创建对应的路由信息。 -
当 pod 运行
Ready
之后,就将访问点写入 cloudshell 的 status 里。 -
当 job 在 TTL 或者其他原因结束之后,一旦 job 变为 Completed,cloudshell 的状态也会变
Completed
。我们可以设置当 cloudshell 的状态为Completed
时,同时删除相关联的资源。 -
当 cloudshell 被删除时,会自动删除对应的 job 和 service (通过
ownerReference
), 如果使用 Ingress 或者 VitualService 模式时,还会删除对应的路由信息。
这个项目的很多技术实现都是基于https://github.com/tsl0922/ttyd
, 非常感谢 tsl0922
yudai
和社区.
前端 UI 也是从 ttyd
项目衍生出来的,另外镜像内所使用的ttyd
二进制也是来源于这个项目。
如果您有任何的问题,请以下面的方式联系我们:
- Slack Channel
- 微信交流群: 请联系
calvin0327
([email protected])加入交流群
- 运行 operator 和安装 CRD
开发者: 编译执行 (建议普通用户使用上述 Helm 安装)
b.1 ) 安装CRD
- (选择1)从YAML: ```make generate-yaml ; 然后apply 生成的yaml```
- (选择2)从代码:克隆代码之后 `make install`
b.2 ) 运行Operator : `make run`
- 创建 CR
比如开启窗口后自动打印某个容器的日志:
apiVersion: cloudshell.cloudtty.io/v1alpha1
kind: CloudShell
metadata:
name: cloudshell-sample
spec:
configmapName: "my-kubeconfig"
runAsUser: "root"
commandAction: "kubectl -n kube-system logs -f kube-apiserver-cn-stack"
once: false
ToDo:
- (1)通过 RBAC 生成的/var/run/secret,进行权限控制
- (2)代码中边界处理(如 nodeport 准备好)还没有处理
- (3)为了安全, job 应该在单独的 NS 跑,而不是在 CR 同 NS
- (4) 需要检查 pod 的 Running 和 endpoint 的 Ready,才能置为 CR 为 Ready
- (5) 目前 TTL 只反映到 shell 的 timeout, 没有反映到 job 的 yaml 里
- (6) job 的创建模版目前是 hardcode 方式,应该提供更灵活的方式修改 job 的模版
基于 kubebuilder 框架开发 基于 ttyd 为基础,构建镜像
- 初始化框架
#init kubebuilder project
kubebuilder init --domain daocloud.io --repo daocloud.io/cloudshell
kubebuilder create api --group cloudshell --version v1alpha1 --kind CloudShell
- 生成manifest
make manifests
- 如果调试(使用默认的kube.conf)
# DEBUG work
make install # 目标集群 安装CRD
make run # 启动operator的代码
- 如何构建镜像
#build
make docker-build
make docker-push
- 生成 operator 部署的 yaml
#use kustomize to render CRD yaml
make generate-yaml
6.构建 helm 包
make build-chart
#开发注意:
#go get的gotty不能用...要下载 wget https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_amd64.tar.gz
镜像在master分支的docker/目录下
- 创建kube.conf
# 1.create configmap of kube.conf
kubectl create configmap my-kubeconfig --from-file=/root/.kube/config
2.根据不同场景
a) 日常kubectl的console
bash run.sh
b) 实时查看event
bash run.sh "kubectl get event -A -w"
c) 实时查看 pod 日志
NS=caas-system
POD=caas-api-6d67bfd9b7-fpvdm
bash run.sh "kubectl -n $NS logs -f $POD"
我们还会提供更多的功能,非常欢迎大家的 issue 和 PR。🎉🎉🎉