【博客416】k8s使用client-go通过exec subsource来进入pod执行命令

【博客416】k8s使用client-go通过exec subsource来进入pod执行命令,第1张

k8s使用client-go通过exec subsource来进入pod执行命令 example pod
$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           
sleep-7f768b447f-5crh7   1/1     Running   1          46h   172.17.0.14  
通过exec subsource可以进入到pod来执行命令
# 使用client-go,通过 *** 作exec subsource在pod内执行命令获取pod的ip
package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"golang.org/x/crypto/ssh/terminal"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/tools/remotecommand"
	"k8s.io/client-go/util/homedir"
)

func main() {
     var kubeconfig *string
     if home := homedir.HomeDir(); home != "" {
            kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")} else {
     kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
     }
     flag.Parse()
     
     config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
     if err != nil {
        panic(err)
     }
     clientset, err := kubernetes.NewForConfig(config)
     if err != nil {
        panic(err)
     }

     req := clientset.CoreV1().RESTClient().Post().
         Resource("pods").
         Name("sleep-7f768b447f-5crh7").
         Namespace("default").
         SubResource("exec").
         VersionedParams(&corev1.PodExecOptions{
             Command: []string{"grep", "sleep-7f768b447f-5crh7", "/etc/hosts"},
             Stdin:   true,
             Stdout:  true,
             Stderr:  true,
             TTY:     false,
         }, scheme.ParameterCodec)
     exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())

     if !terminal.IsTerminal(0) || !terminal.IsTerminal(1) {
        fmt.Errorf("stdin/stdout should be terminal")
     }
     
     oldState, err := terminal.MakeRaw(0)
     if err != nil {
        fmt.Println(err)
     }
     
     defer terminal.Restore(0, oldState)
 
     screen := struct {
           io.Reader
           io.Writer
     }{os.Stdin, os.Stdout}
     
     if err = exec.Stream(remotecommand.StreamOptions{
        Stdin: screen,
        Stdout: screen,
        Stderr: screen,
        Tty:    false,
     }); err != nil {
        fmt.Print(err)
     }
}

# 成功在pod内部执行命令来获取pod的ip
 $ go run main.go
172.17.0.14     sleep-7f768b447f-5crh7
总结

exec其实是k8s对象的subsource,就像status,scale这些都是subsource。
其实kubectl exec也是通过这种原理来实现进入pod执行命令的。背后本质的原理是 *** 作了exec之后,其实是由kubelet去帮你代理请求到集群节点上的cri组件的,然后真正去做这件事的是cri,也就是我们集群中实现了container runtime interface的具体容器运行时组件,比如:docker引擎。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/990863.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存