zoukankan      html  css  js  c++  java
  • 紫色飞猪的研发之旅--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
    
    过手如登山,一步一重天
  • 相关阅读:
    ARM Linux 3.x的设备树(Device Tree)
    ubuntu 14.04 编译内核出现unable to locate package ncurses-devel 问题的解决
    Device Tree Usage( DTS文件语法)
    Ubuntu 14.04中gedit打开文件出现中文乱码问题
    Jenkins中集成jmeter-maven插件
    Linux(centos6.5)下安装jenkins
    IM系统架构设计之浅见
    一些常用软件的网络端口协议分类介绍
    Jenkins执行批处理文件失败
    八大持续集成工具
  • 原文地址:https://www.cnblogs.com/zisefeizhu/p/15238099.html
Copyright © 2011-2022 走看看