在 Kubernetes 中,从 CronJob 创建的容器如何知道它何时被调度?

在 Kubernetes 中,从 CronJob 创建的容器如何知道它何时被调度?

我们有一个 Kubernetes CronJob 资源,用于运行作业每一分钟我需要作业产生的容器来了解它计划何时运行。这可能吗?


背景信息以防有用

Kubernetes 资源的层次结构如下:CronJob -> Job -> Pod -> initContainer -> Container -> PHP CLI 命令。

我注意到容器将在我们希望它运行的时间之后的 20 秒到 10 分钟之间启动。启动时间过长有两个原因:

  1. init-container做了相当多的事情,包括拉取 docker 镜像,还将cp>300MB 的应用程序源代码放入卷中。
  2. 资源container限制相当高,例如 2G 内存,这意味着有时集群中没有足够的容量,因此集群自动扩缩器必须提供一个新节点来运行 Job Pod,并且在新节点加入集群之前,引导过程可能需要一段时间。

这种启动延迟可能会产生有趣的效果,例如,稍后安排的作业可以击败先安排的作业运行,因为它恰好具有运行所需的容量,而前一个作业没有,因此正在等待新节点启动。


到目前为止,我已经研究过一些可以解决我的问题的方法

  1. 我看了看向下 API因此 pod 可以查看/etc/labels它有什么标签,但不幸的是它不提供 pod 启动时间,只提供 pod 名称。
  2. 我考虑过在 Pod 标签中使用动态值,即当前时间戳。但据我所知,这是不可能的?

版本

Kubernetes v1.10,在 AWS EKS 中运行。作业是 PHP 7.2 CLI 命令。


重现步骤

  1. 设置一个 Kubernetes 集群,并安装并启用集群自动扩缩器。
  2. 创建一个CronJob。将以下 yaml 放入名为cron_test.yaml

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: tomtest
      labels:
        app: test
        tier: test
        tester: tom

    spec:
     schedule: "* * * * *"
     jobTemplate:
       metadata:
         name: tomtest-crons

       spec:
         template:
           metadata:
             labels:
                app: test
                tier: test
                tester: tom
                build_id: tom3

           spec:

             containers:
             - name: cron
               image: giantswarm/tiny-tools
               imagePullPolicy: IfNotPresent
               env:
               - name: TOMTEST
                 value: "3"
               args:
               - /bin/sh
               - -c
               - date;echo hi;sleep 600;echo bye;date
             restartPolicy: Never
             resources:
               requests:
                 cpu: "1"
                 memory: "2G"
               limits:
                 cpu: "1"
                 memory: "2G"
  1. 在您的集群上启动 CronJob:kubectl create -f cron_test.yaml
  2. 这将每分钟启动一个容器,该容器除了休眠 10 分钟外不执行任何操作。
  3. 等待几分钟,容器将开始堆积,并且由于它们具有较高的资源限制,因此集群自动缩放器可能会启动并添加一个或两个新节点。如果没有,则进一步增加资源限制。
  4. 查找kubectl get pods看起来迟到的 Pod - 即启动时间与前一个 Pod 相差不到一分钟的 Pod。
  5. 检查 Pod 信息:kubectl get pod tomtest-123-456 -o=yaml——注意有一个creationTimestamp字段和一个,startTime但这些不是 Pod 实际调度的时间。
  6. 完成后,清理:(kubectl delete CronJob tomtest这也会删除所有作业和 Pod)

答案1

我需要作业产生的容器来了解其计划运行的时间。这可能吗?

简短的回答是肯定的。

您可以从 API 服务器获取有关作业和 pod 启动/创建时间戳的信息。

您只需拨打电话$api-server-ip:port/api/v1/namespace/$namespace-name/pods/$podname

它将收到包含有关 pod 详细信息的 JSON。您可以解析此 JSON 并获取时间戳。唯一需要的是 pod 名称(通常是其主机名)。这就是获取时间戳所需的全部内容。对于解析 JSON,您可以使用任何编程语言的任何 JSON 库。

答案2

记住 Kubernetes 资源的层次结构是这样的:CronJob-> Job-> Pod-> initContainer-> Container->PHP CLI command

CronJob创建时container,确实可能container不会准确按计划启动,因为可能会出现延迟,例如集群可能没有足够的空间容纳父 Pod。但是,任务立即创建。因此,当容器最终启动时,它可以使用 API 服务器查找有关其父作业的信息,以查看作业的启动时间。作业的启动时间应与 调度容器的时间相同CronJob


容器如何找到它的父作业?

我还没有找到解决方案,但我曾经curl做过一些实验来证明我可以从 Pod 内部获取有关作业的信息

# Get a bash shell in a container in a Pod
$ kubectl exec -it myPod -c php -- bash

# Get the Bearer Token:
$ export TESTTOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

# Get all api endpoints available
$ curl --insecure --header "Authorization: Bearer $TESTTOKEN" https://kubernetes.default.svc/api/v1/

# List Jobs
$ curl --insecure --header "Authorization: Bearer $TESTTOKEN" https://kubernetes.default.svc/api/v1/namespaces/default/jobs

需要一个脚本来查找父作业并查询其“创建时间”。

相关内容