紫色飞猪的研发之旅--07client-go实现进入pod模拟终端登录

实验目的:使用client-go进入任一pod执行命令,模拟终端.

比较简单 直接上代码

/*
    模拟 ``ctl exec -it pods -n namespace -- /bin/sh `` 命令

    # ctl get po -n a | grep client
	elasticsearch-client-7bf748d697-bfd9p   1/1     Running   1          36d
 */

func ExecPodCom()  {
	config  := config.KubeConfig()

	clientSet,err  := kubernetes.NewForConfig(config); if err != nil {
		logrus.Println(err.Error())
	}

	// 初始化pod所在的corev1资源组,发送请求
	// PodExecOptions struct 包括Container stdout stdout  Command 等结构
	// scheme.ParameterCodec 应该是pod 的GVK (GroupVersion & Kind)之类的
	req := clientSet.CoreV1().RESTClient().Post().
		Resource("pods").Name("elasticsearch-client-7bf748d697-bfd9p").
		Namespace("a").
		SubResource("exec").
		VersionedParams(&coreV1.PodExecOptions{
			Command: []string{"bash","-c","/bin/sh"},
			Stdin: true,
			Stdout: true,
			Stderr: true,
			TTY: true,       // 打开linux终端
	},scheme.ParameterCodec)

	// remotecommand 主要实现了http 转 SPDY 添加X-Stream-Protocol-Version相关header 并发送请求
	exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())

	// 检查是不是终端
	if !terminal.IsTerminal(0) || !terminal.IsTerminal(1) {
		fmt.Errorf("stdin/stdout should be terminal")
	}

	// 这个应该是处理Ctrl + C 这种特殊键位
	oldState, err := terminal.MakeRaw(0); if err != nil {
		fmt.Println(err.Error())
	}

	// 读取当前状态
	fd := int(os.Stdin.Fd())
	oldState, err = terminal.MakeRaw(fd); if err != nil {
		fmt.Println(err.Error())
	}

	defer terminal.Restore(fd, oldState)

	// 用IO读写替换 os stdout
	screen := struct {
		io.Reader
		io.Writer
	}{os.Stdin, os.Stdout}

	// 建立链接之后从请求的sream中发送、读取数据
	if err = exec.Stream(remotecommand.StreamOptions{
		Stdin: screen,
		Stdout: screen,
		Stderr: screen,
		Tty: true,
	}); err != nil {
		fmt.Print(err)
	}
}

执行

 zisefeizhu@zisefeizhudeMacBook-Pro  ~/linkun/goproject/operator  go run main.go                         
INFO[0000] init root.go...                              
/Users/zisefeizhu/linkun/goproject/operator/config/config.yaml
kubeConfig /Users/zisefeizhu/.kube/config
sh-4.2# ls
LICENSE.txt  README.asciidoc  config  jdk  logs     plugins
NOTICE.txt   bin              data    lib  modules  repository-s3-7.8.0.zip
sh-4.2# cd logs/
sh-4.2# ls
gc.log  gc.log.00
posted @ 2021-09-07 14:34  紫色飞猪  阅读(1007)  评论(0编辑  收藏  举报