无法通过Golang代码在Kubernetes Pod容器中执行命令

问题描述 投票:0回答:1

我正在尝试使用以下代码连接到 kubernetes 集群。 我正在加载 kubeconfig 并传递命名空间并获取所有 pod。 我想在每个容器 pod 内执行命令,这只不过是 mongodb 实例。

$kubectl get pods -n mongo
mongo-0
mongo-1
mongo-2 

我已经使用了这段代码kubernetes exec using golang

在下面的代码片段中:

pods, err := clientset.CoreV1().Pods("default").List(context.Background(), v1.ListOptions{})
        if err != nil {
                fmt.Printf("error getting pods: %v\n", err)
                os.Exit(1)
        }
        for _, pod := range pods.Items {
                fmt.Printf("Pod name: %s\n", pod.Name)
                //ExecuteRemoteCommand(pod.Name,"ls -ltr")
        }

我刚刚注释掉了 ExecuteRemoteCommand,它将获取 pod 名称和命令字符串,并最终在 pod 上执行命令。 我也在研究这个 discussion 在 pod 上执行命令,但是,我没有得到任何富有成效的结果:

请帮忙,我是 golang 和 kubernetes 的新手。

go kubernetes containers exec
1个回答
0
投票

我有一个 go 文件,可以在 nginx Pod 中运行命令,这是你想要的吗?

go.mod

module my.com/test
                                                    
go 1.20 

require (                                                            
        k8s.io/api v0.28.4                            
        k8s.io/client-go v0.28.4                                           
        k8s.io/kubectl v0.28.4                              
) 

main.go

package main

import (
    "bytes"
    "fmt"

    v1 "k8s.io/api/core/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/tools/remotecommand"
    "k8s.io/kubectl/pkg/scheme"
)

func executeCommandInPod(kubeconfigPath, pod, namespace, command string) (string, string, error) {
    // Build kubeconfig from the provided path
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
    if err != nil {
        return "", "", fmt.Errorf("failed to build kubeconfig: %v", err)
    }

    // Create a new clientset based on the provided kubeconfig
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        return "", "", fmt.Errorf("failed to create clientset: %v", err)
    }

    // Get the pod's name and namespace
    podName := pod
    podNamespace := namespace

    // Build the command to be executed in the pod
    cmd := []string{"sh", "-c", command}

    // Execute the command in the pod
    req := clientset.CoreV1().RESTClient().Post().
        Resource("pods").
        Name(podName).
        Namespace(podNamespace).
        SubResource("exec").
        VersionedParams(&v1.PodExecOptions{
            Command: cmd,
            Stdin:   false,
            Stdout:  true,
            Stderr:  true,
            TTY:     false,
        }, scheme.ParameterCodec)

    executor, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
    if err != nil {
        return "", "", fmt.Errorf("failed to create executor: %v", err)
    }

    var stdout, stderr bytes.Buffer
    err = executor.Stream(remotecommand.StreamOptions{
        Stdout: &stdout,
        Stderr: &stderr,
        Tty:    false,
    })
    if err != nil {
        return "", "", fmt.Errorf("failed to execute command in pod: %v", err)
    }

    return stdout.String(), stderr.String(), nil
}

func main() {
    stdout, stderr, err := executeCommandInPod("/tmp/config", "nginx-0", "default", "ls /")
    fmt.Println(stdout, stderr, err)
}
© www.soinside.com 2019 - 2024. All rights reserved.