简体   繁体   中英

With Python Kubernetes client, how to replicate `kubectl create -f` generally?

My Bash script using kubectl create/apply -f ... to deploy lots of Kubernetes resources has grown too large for Bash. I'm converting it to Python using the PyPI kubernetes package.

Is there a generic way to create resources given the YAML manifest? Otherwise, the only way I can see to do it would be to create and maintain a mapping from Kind to API method create_namespaced_<kind> . That seems tedious and error prone to me.

Update: I'm deploying many (10-20) resources to many (10+) GKE clusters.

I have written a following piece of code to achieve the functionality of creating k8s resources from its json/yaml file:

def create_from_yaml(yaml_file):
    """

    :param yaml_file:
    :return:
    """

    yaml_object = yaml.loads(common.load_file(yaml_file))
    group, _, version = yaml_object["apiVersion"].partition("/")
    if version == "":
        version = group
        group = "core"

    group = "".join(group.split(".k8s.io,1"))
    func_to_call = "{0}{1}Api".format(group.capitalize(), version.capitalize())

    k8s_api = getattr(client, func_to_call)()

    kind = yaml_object["kind"]
    kind = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', kind)
    kind = re.sub('([a-z0-9])([A-Z])', r'\1_\2', kind).lower()

    if "namespace" in yaml_object["metadata"]:
        namespace = yaml_object["metadata"]["namespace"]
    else:
        namespace = "default"

    try:
        if hasattr(k8s_api, "create_namespaced_{0}".format(kind)):
            resp = getattr(k8s_api, "create_namespaced_{0}".format(kind))(
                body=yaml_object, namespace=namespace)
        else:
            resp = getattr(k8s_api, "create_{0}".format(kind))(
                body=yaml_object)
    except Exception as e:
        raise e

    print("{0} created. status='{1}'".format(kind, str(resp.status)))

    return k8s_api

In above function, If you provide any object yaml/json file, it will automatically pick up the API type and object type and create the object like statefulset, deployment, service etc.

PS: The above code doesn't handler multiple kubernetes resources in one file, so you should have only one object per yaml file.

Update in the year 2020, for anyone still interested in this (since the docs for the python library is mostly empty).

At the end of 2018 this pull request has been merged, so it's now possible to do:

from kubernetes import client, config
from kubernetes import utils

config.load_kube_config()
api = client.ApiClient()

file_path = ... # A path to a deployment file
namespace = 'default'

utils.create_from_yaml(api, file_path, namespace=namespace)

EDIT: from a request in a comment, a snippet for skipping the python error if the deployment already exists

from kubernetes import client, config
from kubernetes import utils

config.load_kube_config()
api = client.ApiClient()


def skip_if_already_exists(e):
    import json
    # found in https://github.com/kubernetes-client/python/blob/master/kubernetes/utils/create_from_yaml.py#L165
    info = json.loads(e.api_exceptions[0].body)
    if info.get('reason').lower() == 'alreadyexists':
        pass
    else
        raise e


file_path = ... # A path to a deployment file
namespace = 'default'

try:
    utils.create_from_yaml(api, file_path, namespace=namespace)
except utils.FailToCreateError as e:
    skip_if_already_exists(e)

I see what you are looking for. This is possible with other k8s clients available in other languages. Here is an example in java. Unfortunately the python client library does not support that functionality yet. I opened a new feature request requesting the same and you can either choose to track it or contribute yourself :). Here is the link for the issue on GitHub.

The other way to still do what you are trying to do is to use java/golang client and put your code in a docker container.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM