1

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

Xaruman
  • 99
  • 1
  • 12
  • 1
    It's a common mistake; `command:` is **exec** style, not sh style, so what you want is `command: df, args: ["-h"]` – mdaniel Mar 18 '22 at 18:55
  • The previous comment seems valid, but I also get that particular error message when I try to exec a shell into a pod when I have any of the "proxy" vars set in the shell that I'm coming from. When I unset those vars, the exec succeeds. – David M. Karr Mar 18 '22 at 23:23
  • Err, that's the first time anyone mentioned proxy -- for sure `exec` (and I believe `logs`, too) switch protocols so if you have a proxy between python and k8s that isn't websocket friendly, that will end poorly – mdaniel Mar 18 '22 at 23:29
  • Thanks for your helps @mdaniel. But it's not that. If I add ```args```, it's not recognized by method. And If I just set commando to ```df``` I get same response . – Xaruman Mar 19 '22 at 15:59
  • Could you please clarify that a little bit more @DavidM.Karr? I've not set anything on purpose, but you never know. As I said, I can list all pods in cluster with no problems. And also using k9s, I can run remote shells, but at the end, this is using ```kubectl``` with some arguments ```docker``` style. – Xaruman Mar 19 '22 at 16:02
  • Before running the "kubectl" command line to exec into the container, do "env | grep -i proxy". If you have variations of "http(s)_proxy" or "no_proxy", try unsetting them and running the kubectl command again. – David M. Karr Mar 19 '22 at 18:13
  • Nothing related with proxy in my env variables. @DavidM.Karr. Thanks for your idea, but it must me other issue... ```/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``` This is what k9s runs to connect pod using shell, and works fine. – Xaruman Mar 21 '22 at 08:53
  • I have more info, I've found this ```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.``` – Xaruman Mar 21 '22 at 16:26

1 Answers1

0

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)
Bazhikov
  • 765
  • 3
  • 11
  • 2
    Thanks @Bazhikov. I had solved it before reading your response. It's exactly that. I had tried this, but I had just "added" ```connect_get_namespaced_pod_exec``` method into ```stream``` and it's not in that way, ``connect_get_namespaced_pod_exec``` has to be provided as first argument to ```stream``` – Xaruman Mar 22 '22 at 09:46