Unable to exec command into kubernetes pod

3.5k views Asked by At

Python version 3.8.10 Kubernetes version 23.3.0

I'm trying to run a command into a specific pod in kubernetes using python. I've tried to reduce the code as much as I could, so I'm running this.

from kubernetes import client, config

config.load_kube_config()

v1 = client.CoreV1Api()
response = v1.connect_get_namespaced_pod_exec(pod_name , namespace, command="df -h", stderr=True, stdin=True, stdout=True, tty=True)
print(response)

But it's not working. I'm getting this response.

kubernetes.client.exceptions.ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Audit-Id': '511c23ce-03bb-4b52-a559-3f354fc80235', 'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 18 Mar 2022 18:06:11 GMT', 'Content-Length': '139'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Upgrade request required","reason":"BadRequest","code":400}

If I run typical example of list all pods . It's working fine. So, it should not be a configuration issue. I've read about this problem in the past here and here. But I assume it cannot be that, due to they are closed issues.

If I run k9s shell request, I can connect with pod with no problem. This is what I see in ps a when I'm doing this /usr/bin/kubectl --context gke_cloudpak_europe-west2-xxxxx exec -it -n namespace_name pod_name -c rt -- sh -c command -v bash >/dev/null && exec bash || exec sh

Another update, I've found this info. At last of page there is a paragraph with says.

Why Exec/Attach calls doesn’t work
Starting from 4.0 release, we do not support directly calling exec or attach calls. you should use stream module to call them. so instead of resp = api.connect_get_namespaced_pod_exec(name, ... you should call resp = stream(api.connect_get_namespaced_pod_exec, name, ....

Using Stream will overwrite the requests protocol in core_v1_api.CoreV1Api() This will cause a failure in non-exec/attach calls. If you reuse your api client object, you will need to recreate it between api calls that use stream and other api calls.

I've tried to do it in this way, but same result :(

Any idea about what I'm doing wrong?

Thanks a lot for your help.

Regards

2

There are 2 answers

1
Bazhikov On BEST ANSWER

Yes, this official guide says that you should use resp = **stream**(api.connect_get_namespaced_pod_exec(name, ... instead.

So you have to edit your code like this:

...
from kubernetes.stream import stream
...
v1 = client.CoreV1Api()
response = stream(v1.connect_get_namespaced_pod_exec, pod_name , namespace, command="df -h", stderr=True, stdin=True, stdout=True, tty=True)
print(response)
0
Jacob Tomlinson On

If you're open to trying a different Python Kubernetes library this is supported in kr8s without needing to worry about the details of the underlying HTTP transport.

from kr8s.objects import Pod
response = Pod.get(pod_name, namespace).exec(["df", "-h"])
print(response.stdout.decode())