我有一个控制器,它具有一个在 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 run main.go 时输出不为空,但在集群中运行时操作符有问题。