16

我有 kubernetes 工作需要不同的时间才能完成。4到8分钟之间。有什么方法可以知道工作何时完成,而不是在最坏的情况下等待 8 分钟。我有一个执行以下操作的测试用例:

1) Submits the kubernetes job.
2) Waits for its completion.
3) Checks whether the job has had the expected affect.

问题是,在我在 kubernetes 中提交部署作业的 java 测试中,我等待 8 分钟,即使该作业完成的时间少于那个时间,因为我没有办法从 java 监视作业的状态测试。

4

7 回答 7

11
$ kubectl wait --for=condition=complete --timeout=600s job/myjob
于 2019-08-16T07:46:58.240 回答
6
<kube master>/apis/batch/v1/namespaces/default/jobs 

端点列出作业的状态。我已经解析了这个 json 并检索了以“deploy ...”开头的最新运行作业的名称。

然后我们可以打

<kube master>/apis/batch/v1/namespaces/default/jobs/<job name retrieved above>

并监控作业成功时的状态字段值如下

"status": {
    "conditions": [
      {
        "type": "Complete",
        "status": "True",
        "lastProbeTime": "2016-09-22T13:59:03Z",
        "lastTransitionTime": "2016-09-22T13:59:03Z"
      }
    ],
    "startTime": "2016-09-22T13:56:42Z",
    "completionTime": "2016-09-22T13:59:03Z",
    "succeeded": 1
  }

所以我们一直在轮询这个端点,直到它完成。希望这可以帮助某人。

于 2016-09-23T16:30:44.370 回答
3

您可以使用 NewSharedInformer 方法来查看作业的状态。不知道如何用 Java 编写它,这是定期获取工作列表的 golang 示例:

type ClientImpl struct {
    clients *kubernetes.Clientset
}

type JobListFunc func() ([]batchv1.Job, error)

var (
    jobsSelector = labels.SelectorFromSet(labels.Set(map[string]string{"job_label": "my_label"})).String()
)


func (c *ClientImpl) NewJobSharedInformer(resyncPeriod time.Duration) JobListFunc {
    var once sync.Once
    var jobListFunc JobListFunc

    once.Do(
        func() {
            restClient := c.clients.BatchV1().RESTClient()
            optionsModifer := func(options *metav1.ListOptions) {
                options.LabelSelector = jobsSelector
            }
            watchList := cache.NewFilteredListWatchFromClient(restClient, "jobs", metav1.NamespaceAll, optionsModifer)
            informer := cache.NewSharedInformer(watchList, &batchv1.Job{}, resyncPeriod)

            go informer.Run(context.Background().Done())

            jobListFunc = JobListFunc(func() (jobs []batchv1.Job, err error) {
                for _, c := range informer.GetStore().List() {
                    jobs = append(jobs, *(c.(*batchv1.Job)))
                }
                return jobs, nil
            })
        })

    return jobListFunc
}

然后在您的显示器中,您可以通过调整作业列表来检查状态:

func syncJobStatus() {
    jobs, err := jobListFunc()
    if err != nil {
        log.Errorf("Failed to list jobs: %v", err)
        return
    }

    // TODO: other code

    for _, job := range jobs {
        name := job.Name
        // check status...
    }
}
于 2018-07-27T04:12:18.353 回答
2

我发现 JobStatus 在使用 job.getStatus() 进行轮询时没有得到更新,即使在使用 kubectl 从命令提示符检查时状态发生变化。

为了解决这个问题,我重新加载了作业处理程序:

    client.extensions().jobs()
                       .inNamespace(myJob.getMetadata().getNamespace())
                       .withName(myJob.getMetadata().getName())
                       .get();

我检查作业状态的循环如下所示:

    KubernetesClient client = new DefaultKubernetesClient(config);
    Job myJob = client.extensions().jobs()
                      .load(new FileInputStream("/path/x.yaml"))
                      .create();
    boolean jobActive = true;
    while(jobActive){
        myJob = client.extensions().jobs()
                .inNamespace(myJob.getMetadata().getNamespace())
                .withName(myJob.getMetadata().getName())
                .get();
        JobStatus myJobStatus = myJob.getStatus();
        System.out.println("==================");
        System.out.println(myJobStatus.toString());

        if(myJob.getStatus().getActive()==null){
            jobActive = false;
        }
        else {
            System.out.println(myJob.getStatus().getActive());
            System.out.println("Sleeping for a minute before polling again!!");
            Thread.sleep(60000);
        }
    }

    System.out.println(myJob.getStatus().toString());

希望这可以帮助

于 2018-07-26T07:17:10.737 回答
1

您没有提到实际检查作业完成的内容,但不要盲目等待并希望最好的结果,您应该继续status在循环中轮询作业,直到它变为“已完成”。

于 2016-08-26T22:50:22.300 回答
1

既然你说Java;您可以使用 fabric8 中的 kubernetes java 绑定启动作业并添加观察者:

KubernetesClient k = ...
k.extensions().jobs().load(yaml).watch (new Watcher <Job>() {

  @Override
  public void onClose (KubernetesClientException e) {}

  @Override
  public void eventReceived (Action a, Job j) {
    if(j.getStatus().getSucceeded()>0)
      System.out.println("At least one job attempt succeeded");
    if(j.getStatus().getFailed()>0)
      System.out.println("At least one job attempt failed");
  }
});
于 2017-03-15T13:19:42.483 回答
0

我不知道你在说什么类型的任务,但让我们假设你正在运行一些 pod

你可以做

watch 'kubectl get pods | grep <name of the pod>'

或者

kubectl get pods -w

当然,它不会是全名,因为如果您正在运行 nginx 副本或部署,大多数时候 pod 会获得随机名称,您的 pod 最终会得到类似 nginx-1696122428-ftjvy 的名称,因此您会想要这样做

watch 'kubectl get pods | grep nginx'

您可以用您正在做的任何工作替换pod ,即 (rc,svc,deployments....)

于 2016-08-28T14:48:47.147 回答