使用kubectl create/apply -f ...
部署大量Kubernetes资源的我的Bash脚本对于Bash来说已经变得太大了。我正在使用PyPI kubernetes
包将其转换为Python。
在给定YAML清单的情况下,是否存在创建资源的通用方法?否则,我能看到的唯一方法是创建和维护从Kind到API方法create_namespaced_<kind>
的映射。这似乎很乏味,而且容易出错。
更新:我正在为许多(10个以上)GKE集群部署许多(10-20个)资源。
答案 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文件应该只有一个对象。