Description:
There is no problem to login a container/pod by client-go/remotecommand.NewSPDYExecutor when there is only one container in a pod.
But when there are many containers in a pod, I cannot login by point a container id.
Can anyone help or give me a solution? Thanks in advance.
Nots:
I am using client-go to connect to k8s, and using remotecommand.NewSPDYExecutor to login container.
Code:
Here is the code I am using for login/connect to a pod/container
func (s *ShellService) BuildConnection(shellVo vo.ShellContainerVo) error {
clu := cluster.GetCluster(shellVo.Cluster)
if clu == nil {
logs.Error("cannot find cluster: ", shellVo.Cluster)
return errors.New("cannot find cluster: " + shellVo.Cluster)
}
if shellVo.Command == "" {
shellVo.Command = "/bin/sh"
}
config := clu.Config
groupversion := schema.GroupVersion{
Group: "",
Version: "v1",
}
config.GroupVersion = &groupversion
config.APIPath = "/api"
config.ContentType = runtime.ContentTypeJSON
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
restclient, err := rest.RESTClientFor(config)
if err != nil {
return err
}
fn := func() error {
req := restclient.Post().
Resource("pods").
Name(shellVo.Container).
Namespace(shellVo.Namespace).
SubResource("exec").
Param("container", shellVo.Container).
Param("stdin", "true").
Param("stdout", "true").
Param("stderr", "true").
Param("command", shellVo.Command).Param("tty", "true")
c := make(chan *remotecommand.TerminalSize)
t := &terminalsize{shellVo.Conn, c}
req.VersionedParams(
&v1.PodExecOptions{
Container: shellVo.Container,
Command: []string{},
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
},
scheme.ParameterCodec,
)
executor, err := remotecommand.NewSPDYExecutor(
config, http.MethodPost, req.URL(),
)
if err != nil {
return err
}
return executor.Stream(remotecommand.StreamOptions{
//SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols,
Stdin: t,
Stdout: shellVo.Conn,
Stderr: shellVo.Conn,
Tty: true,
TerminalSizeQueue: t,
})
//return nil
}
inFd, isTerminal := term.GetFdInfo(shellVo.Conn)
beego.Info(isTerminal)
state, err := term.SaveState(inFd)
return interrupt.Chain(nil, func() {
term.RestoreTerminal(inFd, state)
}).Run(fn)
//kubeShell := &pod.Shell{}
return nil
}
My pod is running with several sidecars. so there are multi containers in a pod. I hope I can login a specified container by provide the container id.