抓狐狸python_​用Python操作Kubernetes的Job

本文给出Python SDK操作Kubernetes Job的更多示例代码,以及相关解释。

pip install kubernetes

初始化

from kubernetes.client import BatchV1Api

from kubernetes.config import load_kube_config

load_kube_config()

batch = BatchV1Api()

load_kube_config 是从默认位置,也就是 ~/.kube/config 加载配置。如果在其它位置,可以通过第一个参数传入其路径。

BatchV1Api() 可以当做Job的客户端来用。命名上,Batch和Job是类似的概念,前者强调批量。

创建Job

以下来自官方样例job_crud.py。

def create_job_object():

container = client.V1Container(

name="pi",

image="perl",

command=["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"])

template = client.V1PodTemplateSpec(

metadata=client.V1ObjectMeta(labels={"app": "pi"}),

spec=client.V1PodSpec(restart_policy="Never", containers=[container]))

spec = client.V1JobSpec(

template=template,

backoff_limit=4)

job = client.V1Job(

api_version="batch/v1",

kind="Job",

metadata=client.V1ObjectMeta(name=JOB_NAME),

spec=spec)

return job

def create_job(api_instance, job):

api_response = api_instance.create_namespaced_job(

body=job,

namespace="default")

print("Job created. status='%s'" % str(api_response.status))

虽然,根据官方教程这样的写法,也能得到可用的 V1Job ,拿去执行创建操作。但还是过于陌生和偏门,不如主流、常见的YAML方便、易读写。

这里该出两种更方便的做法。

直接使用YAML

---

apiVersion: batch/v1

kind: Job

metadata:

name: hello

spec:

template:

spec:

containers:

- name: echo

image: alpine:3.11

args:

- 'echo'

- 'Hello world!'

以上是一个最精简的Job配置样例,

通过读取文件为dict,可以直接拿去使用。

from kubernetes.client import V1Job

import yaml

with open('job.yaml') as file:

cfg = yaml.safe_load(file)

job = batch.create_namespaced_job(namespace='default', body=cfg)

assert isinstance(job, V1Job)

create_namespaced_job 同样接受字典作为body输入,因此YAML配置可以读出后直接传入。

这里返回的 V1Job 只是创建时的状态,但是会包含更多集群中的信息。

使用dict

由于 create_namespaced_job 接受字典作为 body 输入,因此直接使用 dict 也是可行的。

cfg = {

'apiVersion': 'batch/v1',

'kind': 'Job',

'metadata': {

'name': 'hello'

},

'spec': {

'template': {

'spec': {

'restartPolicy':

'Never',

'containers': [{

'name': 'upload',

'image': 'alpine:3.11',

'args': ['echo', 'Hello world!']

}]

}

}

}

}

batch.create_namespaced_job(namespace='default', body=cfg)

由于 dict 结构与YAML相同,而又没有类的束缚,所以也很灵活方便。

此外,从YAML读出为 dict 后,也可以通过修改部分字段,达到动态变化的效果。这种结合YAML和dict的使用方式,是对官方用法的最佳替代。

监控Job运行

在创建Job后,通常需要监控Job的运行,做一些外围处理。轮询当然是下下策,而Kubernetes提供了一个 Watch 机制,通过接收Event,实现对状态变化的掌控。Event只有在状态变化时才会有,所以是非常理想的回调。

from kubernetes.client import V1Job

from kubernetes.watch import Watch

job_name = 'hello'

watcher = Watch()

for event in watcher.stream(

batch.list_namespaced_job,

namespace='default',

label_selector=f'job-name={job_name}',

):

assert isinstance(event, dict)

job = event['object']

assert isinstance(job, V1Job)

Watch().stream 就是前面说的理想回调,它第一个参数是列出类的函数,这里选择 list_namespaced_job 。后面的参数,都是 list_namespaced_job 的参数。除了必备的namespace以外, label_selector也 是一个常用参数,可以避免关注无关的Job。每个Job在创建后,都会自动带一个 f'job-name={job_name}' 的Label,可以借此筛选。 job_name 就是 metadata 里设置的 name ,如这里 job-name=hello 。

event是一个dict,只有三个值。其中 event['raw_object'] 只是 event['object'] 的 dict 形式,没有太大意义。 event['type'] 常见三个值,对应增删改。

ADDED ,创建时的信息,和

create_namespaced_job 的返回值通常没有区别。

MODIFIED ,Job状态变化时的信息。

DELETED ,Job删除时的信息。

以上三个状态值,对其它类型的资源也是通用的,比如Pod、Deployment等。

V1Job的使用

对于具体的 V1Job 实例,其它字段都是和创建时的配置差不多的,只是多一些集群中的具体信息。所以,常用的还是.status字段。

>>> from kubernetes.client import V1JobStatus

>>> isinstance(job.status, V1JobStatus)

True

>>> print(job.status)

{'active': None,

'completion_time': datetime.datetime(2020, 8, 10, 9, 49, 38, tzinfo=tzutc()),

'conditions': [{'last_probe_time': datetime.datetime(2020, 8, 10, 9, 49, 38, tzinfo=tzutc()),

'last_transition_time': datetime.datetime(2020, 8, 10, 9, 49, 38, tzinfo=tzutc()),

'message': None,

'reason': None,

'status': 'True',

'type': 'Complete'}],

'failed': None,

'start_time': datetime.datetime(2020, 8, 10, 9, 49, 32, tzinfo=tzutc()),

'succeeded': 1}

直接使用 job.status.succeeded ,可以得到成功的Container数量。下面几乎每一级都有特定的类,可以连续使用.操作符。如果有特殊需要,也可以用 job.to_dict() 转换成字典来用。

其它字段,作用基本上也和名称相关,不难推测。

列出Job

列出所有Job的 list_job_for_all_namespaces 不常用,一般只列出指定Namespace的Job。

from kubernetes.client import V1JobList, V1Job

job_list = batch.list_namespaced_job(namespace='default')

assert isinstance(job_list, V1JobList)

assert isinstance(job_list.items, list)

for job in job_list.items:

assert isinstance(job, V1Job)

与监控的示例相比,这里去掉了 label_selector ,可以获取Namespace中所有的Job。如果有需要,可以通过自定义Label把所有Job分类,并使用l abel_selector 获取指定类型的Job。

读取Job

如果知道Job的 name ,可以直接通过 read_* 系列接口,获得指定的 V1Job 。

from kubernetes.client import V1Job

job = batch.read_namespaced_job(name='hello', namespace='default')

assert isinstance(job, V1Job)

如果更看重状态,可以改用 read_namespaced_job_status 。虽然访问的API不同,但在Python的 V1Job 这个结果层面,没有本质差异。

列出一个Job的Pod

Pod是Kubernetes调度的最小单元,也是最常用的一种资源。

from typing import List

from kubernetes.client import CoreV1Api, V1Pod

def get_pods_by(job_name: str) -> List[V1Pod]:

core = CoreV1Api()

pods = core.list_namespaced_pod(

namespace='default',

label_selector=f'job-name={job_name}',

limit=1,

)

return pods.items

这里的 get_pods_by ,可以用 job_name 获取对应的Pod。 limit=1 是在已知Pod只有一个的情况下做出的优化,可按需调整或去掉。

删除Job

删除一个Job:

from kubernetes.client import V1Status

status = batch.delete_namespaced_job(

namespace='default',

name=job_name,

propagation_policy='Background',

)

assert isinstance(status, V1Status)

其中, propagation_policy='Background' 是不可省略的关键,否则默认是 Orphan ,其Pod不会被删除。这属于API设计的一个失误,与 kubectl 的默认行为不符合。而且,应该没有人在删除了Job之后,还要保留Pod的吧。这里也可以选择 'Foreground' ,阻塞等待相关资源的删除完毕。

删除多个、或所有Job:

status = batch.delete_collection_namespaced_job(

namespace='default',

propagation_policy='Background',

label_selector='some-label=your-value',

)

assert isinstance(status, V1Status)

如果没有 label_selector ,那就是删除一个 Namespace 中的所有Job。

更新Job

这个比较少用,因为一般都是建新的。用法其实和 create_namespaced_job 差不多,参考官方样例即可。

def update_job(api_instance, job):

job.spec.template.spec.containers[0].image = "perl"

api_response = api_instance.patch_namespaced_job(

name=JOB_NAME,

namespace="default",

body=job)

print("Job updated. status='%s'" % str(api_response.status))

总结

用Python操作Kubernetes的Job,总体上还是比较方便的,虽然有一些坑。

作者: 匿蟒

原文链接:https://note.qidong.name/2020/08/python-k8s-job/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql8支持myISAM_mysql菜鸟手迹8--mysql存储引擎之MyISAM

MyISAM可以将表压缩为只读表来节省空间。使用myisampack工具来进行表压缩。MyISAM支持全文索引;一般使用instr()来替代。myisam在写的时候,会产生一个表级锁。myisam锁的时候使用一个lock命令,lock类型有write锁(只有当前线程可以做读写删操作…

mysql双机数据热备份_配置MySQL数据库双机热备份

1、mysql 数据库没有增量备份的机制,当数据量太大的时候备份是一个很大的问题。还好 mysql 数据库提供了一种主从备份的机制,其实就是把主数据库的所有的数据同时写到备份数据库中。实现 mysql 数据库的热备份。  2、要想实现双机的热备首先要了解主从…

java token_Java实现基于token认证的方法示例

随着互联网的不断发展,技术的迭代也非常之快。我们的用户认证也从刚开始的用户名密码转变到基于cookie的session认证,然而到了今天,这种认证已经不能满足与我们的业务需求了(分布式,微服务)。我们采用了另外一种认证方式&#xff…

重置mysql+密码_MySQL重置root密码的几种方法(windows+Linux)

重置root密码的方法:windows系统下:1、停止mysql服务;2、新建文件init-root.txt,写上如下内容:update mysql.user set password password(‘newpwd‘) where user ‘root‘;flush privileges;保存;3、打开命令行&…

java 中导出word后压缩文件_Java批量导出word压缩后的zip文件案例

一、js代码,由于参数比较大所以利用form表单使用post导出function export_word(){var selectedRows $("#dg").datagrid("getSelections");if (selectedRows.length0) {showAlertWarning("请选择一条的信息...");return;}if (selecte…

opengl es java_java – 在Android OpenGL ES App中加载纹理

1)您应该根据需要分配尽可能多的纹理名称.一个用于您正在使用的每个纹理.加载纹理是一项非常繁重的操作,会使渲染管道停顿.所以,你永远不应该在游戏循环中加载纹理.您应该在呈现纹理的应用程序状态之前具有加载状态.加载状态负责加载渲染中所需的所有纹理.因此,当您需要渲染几何…

java io 视频 下载_Java下载映客主播视频回放到电脑硬盘

Java下载映客主播视频回放到电脑硬盘使用Java下载映客回放到电脑硬盘使用方法:在映客app播放回放视频时,分享到QQ,就可以得到url,其中的liveid属性就是视频ID。源代码由 [**海思教育**](http://edu.itshidu.com/) 提供&#xff0c…

java jni helloword_JNI学习一:编写HelloWorld程序

转载请说明出处~本文教程翻译jni官方文档的部分内容。要查看Jni官方文档,请点击这里先感叹一下时光如水,岁月不留人哇有木有!!!认真想想在XMU的这三年,真的改变了我好多。我还清楚地记得学习C语言写的第一个…

【学习记录】macOS的Redis安装及基本使用

【学习记录】macOS的Redis安装及基本使用一. Redis的安装与启动二. 简单使用① 尝试插入第一个key-value② Redis的数据类型与基本使用字符串列表字典(哈希表)集合有序集合三. 杂乱无章的笔记一. Redis的安装与启动 打开终端,输入以下命令即…

java scipt 对象 函数_java script 基本函数

Math.random() 是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值。日期时间函数(需要用变量调用):var b new Date(); //获取当前时间b.getTime() ; //获取时间戳b.getFullYear(); //获取年…

[学习记录] macOS下的Nginx安装 Nginx基本知识

[学习记录] macOS下的Nginx安装 && Nginx基本知识一. 安装相关1. 安装:直接通过brew安装即可2. 启动:3. 成功运行判断:4. 改端口号:由于8080这个端口号很容易冲突,因此需要改一个其他的端口号。二. Nginx 学习…

java 下载限速_Java 文件下载限流算法

在做文件下载功能时,为了避免下载功能将服务器的带宽打满,从而影响服务器的其他服务。我们可以设计一个限流器来限制下载的速率,从而限制下载服务所占用的带宽。一、算法思路定义一个数据块chunk(单位 bytes)以及允许的最大速率 maxRate(单位…

【学习笔记】JAVA基础——异常处理部分

文章目录前言简介一. try、catch与finally① try && catch② finally③ throws补充:JVM 相关二. 异常的分类① 分类解释与思维导图三. 自定义异常例子:Hero类的attack方法的isDeadException。四. 上传代码到GIT① 首先在github新建一个仓库Java_…

java 反射 json_java 反射机制构建JSON字符串

java 反射机制构建JSON字符串。接着上一篇文章、今天继续学习利用java 反射机制构建JSON字符串。JSON的格式跟使用的方式方法就不讲了、这个百度一下就有……好了今天心情很糟糕、直接上代码吧![java]view plaincopyprint?import java.lang.reflect.Field;import j…

【学习笔记】数据链路层的差错控制——检错编码与纠错编码(海明码、奇偶检验码与CRC循环冗余码)

文章目录前言一. 差错控制简介二.补充知识三. 检错编码(1)奇偶检验码组成:构造方法:以奇检验码为例。举个例子:检验码求法:错误检测方法:特点(2)CRC循环冗余检验码三要素…

【学习笔记】数据链路层——流量控制:停止等待协议、后退N帧协议(GBN)、选择重传协议(SR)

文章目录一. 流量控制① 必要性② 数据链路层 VS 传输层③ 定义④ 方法1)停止等待协议2)滑动窗口协议关系:包括:3)协议对比二. 停止-等待协议必要性应用情况① 无差错情况② 有差错情况1)数据帧丢失&#x…

java线程唤醒与等待_Java线程的等待与唤醒

生产者和消费者必须使用同步代码块包裹起来,保证等待和唤醒只能有一个执行,同步使用的锁对象必须保证唯一Thread中重要方法void wait() 在其他线程调用此对象的notify()方法或notifyall()方法前,导致当前线程等待void notify() 唤醒在此对象监…

【学习笔记】数据链路层——信道划分访问控制(FDM、TDM、STDM、WDM、CDM CDMA)

PPT截自王道考研B站教程 一. 铺垫知识 ① 传输数据使用的两种链路 星型、总线型都是广播式结构。 星型更有容错率,总线型断一个则全断。 ② 介质访问控制 定义 采取一定措施,使得两对节点之间的通信不会发生互相干扰的情况。 分类 多路复用&…

stream of java_java8新特性之强大的Stream API

Stream APIStream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数 据库查询。也可以使用Stream API来并行…

【学习笔记】数据链路层——随机访问介质访问控制(ALOHA、CSMA、CSMA/CD、CSMA/CA),截断二进制指数规避算法

文章目录小前言一. ALOHA协议纯ALOHA协议时隙ALOHA协议ALOHA对比CSMA协议定义与分类① 1-坚持CSMA② 非坚持CSMA③ p-坚持CSMA总结CSMA/CD协议传播时延对载波监听的影响确定重传时机:截断二进制指数规避算法最小帧长问题CSMA/CA协议工作原理CSMA/CD 与 CSMA/CA的对比…