我们有一个 Kubernetes CronJob 资源,用于运行作业每一分钟我需要作业产生的容器来了解它计划何时运行。这可能吗?
背景信息以防有用
Kubernetes 资源的层次结构如下:CronJob -> Job -> Pod -> initContainer -> Container -> PHP CLI 命令。
我注意到容器将在我们希望它运行的时间之后的 20 秒到 10 分钟之间启动。启动时间过长有两个原因:
- 它
init-container
做了相当多的事情,包括拉取 docker 镜像,还将cp
>300MB 的应用程序源代码放入卷中。 - 资源
container
限制相当高,例如 2G 内存,这意味着有时集群中没有足够的容量,因此集群自动扩缩器必须提供一个新节点来运行 Job Pod,并且在新节点加入集群之前,引导过程可能需要一段时间。
这种启动延迟可能会产生有趣的效果,例如,稍后安排的作业可以击败先安排的作业运行,因为它恰好具有运行所需的容量,而前一个作业没有,因此正在等待新节点启动。
到目前为止,我已经研究过一些可以解决我的问题的方法
- 我看了看向下 API因此 pod 可以查看
/etc/labels
它有什么标签,但不幸的是它不提供 pod 启动时间,只提供 pod 名称。 - 我考虑过在 Pod 标签中使用动态值,即当前时间戳。但据我所知,这是不可能的?
版本
Kubernetes v1.10,在 AWS EKS 中运行。作业是 PHP 7.2 CLI 命令。
重现步骤
- 设置一个 Kubernetes 集群,并安装并启用集群自动扩缩器。
- 创建一个
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"
- 在您的集群上启动 CronJob:
kubectl create -f cron_test.yaml
- 这将每分钟启动一个容器,该容器除了休眠 10 分钟外不执行任何操作。
- 等待几分钟,容器将开始堆积,并且由于它们具有较高的资源限制,因此集群自动缩放器可能会启动并添加一个或两个新节点。如果没有,则进一步增加资源限制。
- 查找
kubectl get pods
看起来迟到的 Pod - 即启动时间与前一个 Pod 相差不到一分钟的 Pod。 - 检查 Pod 信息:
kubectl get pod tomtest-123-456 -o=yaml
——注意有一个creationTimestamp
字段和一个,startTime
但这些不是 Pod 实际调度的时间。 - 完成后,清理:(
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
需要一个脚本来查找父作业并查询其“创建时间”。