控制器在集群上运行时 exec 输出为空

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

我有一个控制器,它具有一个在 Pod 中执行命令的功能(与操作员相同的命名空间)。当控制器在本地启动时,我能够看到输出,当同一个控制器在集群上运行(作为 pod)时,它会给出空输出,即使命令看起来正确执行。

该函数作为方法实现,因为最初我通过协调器对象传递了命名空间。

func (r *BPReconciler) ExecCmdPod(config *restclient.Config, podName string, containerName string, podNamespace string, cmd []string) (string, error) {
    log := ctrl.Log.WithName("Execute command  ")
    log.Info("Executing command inside container", "Pod Name:", podName, "Container Name:", containerName)

    //NewForConfig creates a new Clientset for the given config. func NewForConfig(c *rest.Config) (*Clientset, error)
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        fmt.Printf("Error creating clientset: %s\n", err)
    }
    //build the request URL which will be used by Executor
    request := clientset.CoreV1().RESTClient().Post().Resource("pods").Name(podName).Namespace(podNamespace).SubResource("exec") // .Param("container", containerName)

    //https://pkg.go.dev/k8s.io/api/core/v1#PodExecOptions
    option := &corev1.PodExecOptions{
        Command:   cmd,
        Stdin:     true,
        Stdout:    true,
        Stderr:    true,
        TTY:       true,
        Container: containerName,
    }
    request.VersionedParams(
        option,
        scheme.ParameterCodec,
    )

    // return Executor https://pkg.go.dev/k8s.io/client-go/tools/remotecommand#Executor
    exec, err := remotecommand.NewSPDYExecutor(config, "POST", request.URL())
    if err != nil {
           fmt.Printf("Error creating executor: %s\n", err)
    }

    var execOut bytes.Buffer
    var execErr bytes.Buffer
    w := io.MultiWriter(os.Stdout, &execOut)

    err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{
        Stdin:  os.Stdin,
        Stdout: w, 
        Stderr: &execErr,
        Tty:    true,
    })
    if err != nil {
        log.Info("There was an error")
        fmt.Println(err)
        fmt.Println("Error output:", execErr.String())
        return "", err
    }
    if execErr.Len() > 0 {
        log.Info("There was an errorExec")
        return "", fmt.Errorf("stderr: %v", execErr.String())
    }
    if err == nil {
        log.Info("Command executed successfully")
    }

    return execOut.String(), nil
}

我已经尝试使用标准输入/标准输出的多个选项,但无法正常工作。 我最后的想法是 RBAC,但我相信我拥有所需的一切:

//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;delete;deletecollection
//+kubebuilder:rbac:groups=core,resources=pods/exec,verbs=create
//+kubebuilder:rbac:groups=core,resources=pods/log,verbs=get;list

我什至尝试过:

//+kubebuilder:rbac:groups=*,resources=*,verbs=*

知道这里可能出了什么问题吗?

go exec client-go operator-sdk
1个回答
0
投票

我也遇到同样的问题了! 我发现当运行 go run main.go 时输出不为空,但在集群中运行时操作符有问题。

© www.soinside.com 2019 - 2024. All rights reserved.