使用Python Kubernetes客户端,如何复制`kubectl create -f`一般?

时间:2017-08-28 20:29:09

标签: python kubernetes

使用kubectl create/apply -f ...部署大量Kubernetes资源的我的Bash脚本对于Bash来说已经变得太大了。我正在使用PyPI kubernetes包将其转换为Python。

在给定YAML清单的情况下,是否存在创建资源的通用方法?否则,我能看到的唯一方法是创建和维护从Kind到API方法create_namespaced_<kind>的映射。这似乎很乏味,而且容易出错。

更新:我正在为许多(10个以上)GKE集群部署许多(10-20个)资源。

3 个答案:

答案 0 :(得分:1)

我明白你在找什么。对于其他语言的其他k8s客户端,这是可能的。 Here是java中的一个例子。不幸的是,python客户端库还不支持该功能。我打开了一个新的功能请求请求相同的,您可以选择跟踪它或自己贡献:)。 Here是GitHub上问题的链接。

另一种方法仍然是你要做的就是使用java / golang客户端并将你的代码放在一个docker容器中。

答案 1 :(得分:1)

在2020年进行更新,以供仍对此感兴趣的任何人使用(因为python库的文档大部分为空)。

在2018年底,this拉取请求已合并, 所以现在可以做到:

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)

编辑:在注释中的请求中,如果部署已经存在,则跳过python错误的代码段

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)

答案 2 :(得分:0)

我编写了以下代码,以实现从json / yaml文件创建k8s资源的功能:

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

在上述功能中,如果您提供任何对象yaml / json文件,它将自动获取API类型和对象类型,并创建诸如statefulset,部署,服务等对象。

PS:上面的代码不会在一个文件中处理多个kubernetes资源,因此每个yaml文件应该只有一个对象。