Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to run a command from reconcile inside of a pod/container? #1561

Closed
camilamacedo86 opened this issue Jun 14, 2019 · 17 comments
Closed

How to run a command from reconcile inside of a pod/container? #1561

camilamacedo86 opened this issue Jun 14, 2019 · 17 comments
Labels
lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed.

Comments

@camilamacedo86
Copy link
Contributor

camilamacedo86 commented Jun 14, 2019

Type of question

Usage

Question

What did you do?
Getting a pod and trying to kubectl exec by using the client libs available.

What did you expect to see?
Do something as :

	cmd := []string{
		"/bin/sh",
		"-c",
		"pg_dump mobile_security_service | gzip > mobile_security_service.gz",
	}

       command(cmd).Run()

API example:

/api/v1/namespaces/project-1/pods/pod-1-lmlzj/exec?command=/bin/bash&command=-c&command=/bin/bash&stdin=true&stderr=true&stdout=true&tty=true

@lilic
Copy link
Member

lilic commented Jun 14, 2019

@camilamacedo86 Can you explain a bit more, not sure I understand the reconcile part.

@cmoulliard
Copy link

@camilamacedo86
Copy link
Contributor Author

camilamacedo86 commented Jun 17, 2019

Hi @lilic, I'd like to execute a command inside of the container in the reconcile func like kubectl exec

@camilamacedo86
Copy link
Contributor Author

camilamacedo86 commented Jun 17, 2019

I tried the following impl and it did not work as well. The restClient is nil. I do not think will be possible to use it inside of the container.

// Get the config
	cfg, err := config.GetConfig()
	if err != nil {
		return reconcile.Result{}, err
	}

	// Get The Rest client for this config
	restClient, _ := rest.RESTClientFor(cfg);

	// Do the request
	req := restClient.Post().
		Namespace(pod.Namespace).
		Resource("pods").
		Name(pod.Name).
		SubResource("exec").
		VersionedParams(&corev1.PodExecOptions{
			Command: cmd,
		}, scheme.ParameterCodec)

	// Connect to url (constructed from req) using SPDY (HTTP/2) protocol which allows bidirectional streams.
	exec, err := remotecommand.NewSPDYExecutor(cfg, "POST", req.URL())
	if err != nil {
		reqLogger.Error(err, "cmd", cmd, "pod", pod.Name)
		return reconcile.Result{}, err
	}

	// initialize the transport of the standard shell streams
	err = exec.Stream(remotecommand.StreamOptions{})
	if err != nil {
		reqLogger.Error(err, "cmd", cmd, "pod", pod.Name)
		return reconcile.Result{}, err

	}

Could you help me here? How can I execute a command inside of the containers of the pods managed by the operator? PS.: I cannot add the command via args when the deployment is made for example. In my case, I would like to do a bkp of the database and move the file for another place.

@camilamacedo86
Copy link
Contributor Author

@shawn-hurley @lilic @cmoulliard any ideas?

@camilamacedo86
Copy link
Contributor Author

Hi @shawn-hurley,

Really tks. However, I am still with an issue before that. The following code will return null.

	// Get The Rest client for this config
	restClient, _ := rest.RESTClientFor(cfg);

PS.: The cfg is that one injects in the manager. Have you any idea to solve it?

@cmoulliard
Copy link

some of the options of your impl to get it to work.

Such examples will work as the restclient is created outside of the k8s cluster, We need for the Camila use case, something like this but able to working within the cluster

https://gist.github.com/cmoulliard/ec4dac1275042643bab7f4ba2867604f#file-gistfile1-txt-L279

@lilic
Copy link
Member

lilic commented Jun 20, 2019

@camilamacedo86 if you want to do the request directly we do it like this:

func proxyViaPod(kubeClient kubernetes.Interface, namespace, podName, podPortName, path string) *rest.Request {
return kubeClient.
CoreV1().
RESTClient().
Get().
Namespace(namespace).
Resource("pods").
SubResource("proxy").
Name(fmt.Sprintf("%s:%s", podName, podPortName)).
Suffix(path)

and to get the client we do:

kubeconfig, kcNamespace, err = k8sInternal.GetKubeconfigAndNamespace(*kubeconfigPath)
if *singleNamespace && namespace == "" {
namespace = kcNamespace
}
if err != nil {
return fmt.Errorf("failed to build the kubeconfig: %v", err)
}
kubeclient, err := kubernetes.NewForConfig(kubeconfig)

You should be able to do direct requests then, haven't tried it myself.

@camilamacedo86
Copy link
Contributor Author

camilamacedo86 commented Jul 10, 2019

Hi @lilic I am not sure if it would attend this need as well. Note that is required the kubeconfigPath. From inside of the cluster it is one path (when the operator been executed) and from outside of the cluster (when we run operator-sdk up local) is another path. I believe that the test file added here is used in the e2e which is running outside of the cluster.

@camilamacedo86
Copy link
Contributor Author

camilamacedo86 commented Sep 5, 2019

Marco shared: https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/exec.go#L44

@openshift-bot
Copy link

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

@openshift-ci-robot openshift-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 4, 2019
@anikin-aa
Copy link

Guys, any ideas here ? Or we should just use kubeClient ?

@openshift-bot
Copy link

Stale issues rot after 30d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle rotten
/remove-lifecycle stale

@openshift-ci-robot openshift-ci-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jan 24, 2020
@openshift-bot
Copy link

Rotten issues close after 30d of inactivity.

Reopen the issue by commenting /reopen.
Mark the issue as fresh by commenting /remove-lifecycle rotten.
Exclude this issue from closing again by commenting /lifecycle frozen.

/close

@openshift-ci-robot
Copy link

@openshift-bot: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.

Reopen the issue by commenting /reopen.
Mark the issue as fresh by commenting /remove-lifecycle rotten.
Exclude this issue from closing again by commenting /lifecycle frozen.

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sarroutbi
Copy link

Marco shared: https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/exec.go#L44

Hello @camilamacedo86. Is this alternative currently working? If so ... have you noticed any issue with it (memory leaks or related)?

I have used a similar approach, but my controller crashes continuously. It seems to be related to this:
kubernetes/kubernetes#105830

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed.
Projects
None yet
Development

No branches or pull requests

8 participants