如何正确更新作业的状态

How to Properly Update the Status of a Job

据我所知,当大多数人想知道 Kubernetes(或 Spark 甚至)Job 是否完成时,他们会在某处启动某种循环以定期检查 Job 是否完成相应的 API.

现在,我正在使用 Kubernetes 在后台使用 disown (&) 运算符(下面的 Python 中的 bash ):

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. 我认为最好的选择实际上是从 Job 内部使用 cURL 来更新与 Kubernetes 交互的 Local Server API
    • 但是,我不知道如何从 Job 执行 cURL。可能吗?
    • 我想您必须在某处公开端口,但在哪里?它真的受支持吗?您可以创建一个 Kubernetes Service 来管理端口和连接吗?

如果您不想阻止进程 运行 完成,您可以创建一个 subprocess.Popen instance instead. Once you have this, you can 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. Rather than using this "wait" operation, you would watch 有问题的作业对象并查看其状态是否更改为 "completed" 比炮击到 kubectl 更好。这看起来大致像(未经测试):

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 的 Pod 不需要通过 Kubernetes 服务器更新自己的状态。它只需要在完成时以成功状态代码 (0) 退出,这将反映在作业的状态字段中。