如何正确更新作业状态

时间:2019-08-19 20:11:45

标签: kubernetes kubernetes-jobs

据我所知,当大多数人想知道Kubernetes(甚至Spark甚至Job完成时,他们会在某处发起某种循环来定期检查是否Job以各自的API结尾。

现在,我使用Kubernetesdisown)运算符(下面&内的bash)在后台使用Python来执行此操作:

import subprocess

cmd = f'''
kubectl wait \\
    --for=condition=complete \\
    --timeout=-1s \\
    job/job_name \\
    > logs/kube_wait_log.txt \\
    &
'''

kube_listen = subprocess.run(
    cmd,
    shell = True,
    stdout = subprocess.PIPE
)

所以...我实际上有两个(相关)问题:

  1. 除了shell运算符之外,还有&在后​​台执行此操作的更好方法吗?
  2. 我认为最好的选择实际上是从cURL内部使用Job来更新与Local Server API交互的Kubernetes
    • 但是,我不知道如何从cURL执行Job。有可能吗?
    • 我想您必须在某个地方暴露端口,但是在哪里?真的受支持吗?您可以创建一个Kubernetes Service来管理端口和连接吗?

1 个答案:

答案 0 :(得分:3)

如果您不想阻塞正在运行的进程,则可以创建一个subprocess.Popen实例。有了它后,您可以poll()查看它是否完成。 (如果可能的话,您应该非常努力地避免使用shell=True。)因此,其中的一种变化可能看起来像(未经测试):

with open('logs/kube_wait_log.txt', 'w') as f:
  with subprocess.Popen(['kubectl', 'wait',
                         '--for=condition=complete',
                         '--timeout=-1s',
                         'job/job_name'],
                         stdin=subprocess.DEVNULL,
                         stdout=f,
                         stderr=subprocess.STDOUT) as p:
    while True:
      if p.poll():
        job_is_complete()
        break
      time.sleep(1)

不过,比起使用official Kubernetes Python client library,更胜于kubectl。与其使用此“等待”操作,不如watch所讨论的作业对象,并查看其状态是否变为“已完成”。这大概看起来像(未经测试):

from kubernetes import client, watch
jobsv1 = client.BatchV1Api()
w = watch.watch()
for event in w.stream(jobsv1.read_namespaced_job, 'job_name', 'default'):
  job = event['object']
  if job.status.completion_time is not None:
    job_is_complete()
    break

Job's Pod无需使用Kubernetes服务器更新其自身状态。完成后,只需以成功的状态码(0)退出即可,这将反映在Job的status字段中。