簡體   English   中英

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

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

我使用kubectl create/apply -f ...部署大量 Kubernetes 資源的 Bash 腳本對於 Bash 來說已經變得太大了。 我正在使用 PyPI kubernetes包將其轉換為 Python。

給定 YAML 清單,是否有創建資源的通用方法? 否則,我能看到的唯一方法是創建和維護從 Kind 到 API 方法create_namespaced_<kind>的映射。 這對我來說似乎很乏味且容易出錯。

更新:我正在將許多(10-20)個資源部署到許多(10+)個 GKE 集群。

我編寫了以下一段代碼來實現從其 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、deployment、service 等對象。

PS:上面的代碼不會在一個文件中處理多個 kubernetes 資源,所以每個 yaml 文件應該只有一個對象。

2020 年更新,對於仍然對此感興趣的任何人(因為 python 庫的文檔大部分是空的)。

在 2018 年底,拉取請求已合並,因此現在可以執行以下操作:

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)

我明白你在找什么。 這可以通過其他語言的其他 k8s 客戶端實現。 是java中的一個例子。 不幸的是,python 客戶端庫還不支持該功能。 我打開了一個要求相同的新功能請求,您可以選擇跟蹤它或自己貢獻:)。 是 GitHub 上問題的鏈接。

仍然做您想做的事情的另一種方法是使用 java/golang 客戶端並將您的代碼放在 docker 容器中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM