kubernetes-client / python

Official Python client library for kubernetes
http://kubernetes.io/
Apache License 2.0
6.74k stars 3.26k forks source link

Cannot change kube config at runtime #2240

Open mcreutz opened 4 months ago

mcreutz commented 4 months ago

What happened (please include outputs or screenshots): For unit testing, I want to change the kubeconfig file at runtime and after the import of the config module. As my tests module imports the productive module, the imports are executed before fixtures and patches are executed. When I then change the value of the KUBECONFIG environment variable, the Kubernetes client ignores that change.

What you expected to happen: Cluster can be switched at runtime by changing the KUBECONFIG env var.

How to reproduce it (as minimally and precisely as possible): This is a short example that shows, that changes to the KUBECONFIG environment variable after the import of the configmodule are ignored. Changes to the env var before the import are followed.

export KUBECONFIG="/path/to/first.kubeconfig"
python not_working.py
# not_working.py

import os
from kubernetes import config

config.load_kube_config()
print(config.list_kube_config_contexts())
os.environ["KUBECONFIG"] = "/path/to/second.kubeconfig"
config.load_kube_config()
print(config.list_kube_config_contexts())  # still shows contexts of first.kubeconfig
export KUBECONFIG="/path/to/first.kubeconfig"
python working.py
# working.py

import os

os.environ["KUBECONFIG"] = "/path/to/second.kubeconfig"
from kubernetes import config
config.load_kube_config()
print(config.list_kube_config_contexts())  # shows contexts of second.kubeconfig

Anything else we need to know?: I've already tried without success:

Successful was to run kubectl from Python with subprocess.run(...), that way the updated KUBECONFIG env var is followed. But I need it in this package.

Environment:

Zerohertz commented 4 months ago

https://github.com/kubernetes-client/python/blob/master/kubernetes/base/config/kube_config.py#L816-L817

def load_kube_config(config_file=None, context=None,
                     client_configuration=None,
                     persist_config=True,
                     temp_file_path=None):
...
    if config_file is None:
        config_file = KUBE_CONFIG_DEFAULT_LOCATION

As you can see here, this appears to be because it does not use the KUBECONFIG environment variable, but rather uses global variables within the library.

mcreutz commented 4 months ago

https://github.com/kubernetes-client/python/blob/master/kubernetes/base/config/kube_config.py#L816-L817

def load_kube_config(config_file=None, context=None,
                     client_configuration=None,
                     persist_config=True,
                     temp_file_path=None):
...
    if config_file is None:
        config_file = KUBE_CONFIG_DEFAULT_LOCATION

As you can see here, this appears to be because it does not use the KUBECONFIG environment variable, but rather uses global variables within the library.

Thanks for the answer. But from the code I would expect an

config.load_kube_config(config_file="/path/to/second.kubeconfig")

to be working. But that also does not change the config in the client.

roycaihw commented 4 months ago

I wonder if the default config behavior is related here: https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md#v1201. Could you take a look?

yliaog commented 4 months ago

/assign @roycaihw

k8s-triage-robot commented 1 month ago

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot commented 3 days ago

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten