$ 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引擎。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)