Назад | Перейти на главную страницу

Как в Kubernetes контейнер, созданный из CronJob, узнать, когда он был запланирован?

У нас есть ресурс Kubernetes CronJob, который запускает задание каждую минуту. Мне нужен контейнер, полученный в результате задания, чтобы знать, когда он должен быть запущен. Это возможно?


Справочная информация на всякий случай, если это будет полезно

Иерархия ресурсов Kubernetes такова: CronJob -> Job -> Pod -> initContainer -> Container -> PHP CLI command.

Я заметил, что контейнер запускается между 20 секундами и 10 минутами после той минуты, которую мы хотели запустить. Есть 2 причины значительного времени запуска:

  1. В init-container делает довольно много вещей, в том числе извлекает образы докеров, а также выполняет cp исходного кода приложения размером более 300 МБ в том.
  2. В container ограничения ресурсов довольно высоки, например, 2 ГБ памяти, что означает, что иногда в кластере не хватает емкости, поэтому кластер-автоматическое масштабирование должен подготовить новый узел для запуска модуля заданий, а процесс начальной загрузки может занять некоторое время, прежде чем новый узел присоединяется к кластеру.

Эта задержка запуска может иметь интересные эффекты, такие как Задание, запланированное позже, может превзойти Задание, запланированное для выполнения ранее, потому что у него есть емкость, необходимая для запуска, тогда как предыдущая не имела, поэтому ожидает запуска нового узла.


Некоторые вещи, на которые я смотрел до сих пор, чтобы решить свою проблему

  1. Я посмотрел на DownWards API так что капсула может заглянуть в /etc/labels чтобы знать, какие у него ярлыки, но, к сожалению, он не предоставляет время запуска модуля, а только имя модуля.
  2. Я рассмотрел использование динамического значения в метке Pod, то есть текущей метки времени. Но насколько я знаю, это невозможно?

Версии

Kubernetes v1.10, работающий в AWS EKS. Job - это команда интерфейса командной строки PHP 7.2.


Действия по воспроизведению

  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. Подождите несколько минут, контейнеры начнут складываться в стек, и, поскольку у них высокие ограничения ресурсов, вероятно, включится автоматическое масштабирование кластера и добавит новый узел или 2. Если нет, увеличьте ограничения ресурсов дальше.
  4. Делать kubectl get pods чтобы найти модули, которые кажутся запаздывающими, т. е. время запуска которых отличается от предыдущего.
  5. Осмотрите информацию о модуле: kubectl get pod tomtest-123-456 -o=yaml - обратите внимание, что есть creationTimestamp поле и startTime но это не то время, когда стручок был запланирован.
  6. Когда закончите, уберите: kubectl delete CronJob tomtest (Это также удаляет все задания и контейнеры)

Мне нужен контейнер, полученный в результате задания, чтобы знать, когда он должен быть запущен. Это возможно?

Краткий ответ: да.

Вы можете получить информацию о задании и времени запуска / создания пода с API-сервера.

Все, что вам нужно, это позвонить $api-server-ip:port/api/v1/namespace/$namespace-name/pods/$podname

Он получит JSON с подробной информацией о pod. Вы можете проанализировать этот JSON и получить отметку времени. Единственное, что необходимо, - это имя модуля (обычно это имя хоста). Это все, что вам нужно для получения отметки времени. Для парсинга JSON вы можете использовать любую библиотеку JSON для любого языка программирования.

(Вспомним иерархию ресурсов Kubernetes так: CronJob -> Job -> Pod -> initContainer -> Container -> PHP CLI command)

Когда CronJob создает containerэто правда container может не запуститься точно в то время, когда он был запланирован, потому что могут быть задержки, например, в кластере может не хватить емкости для родительского модуля. Тем не мение, Работа создается без промедления. Поэтому, когда контейнер в конечном итоге запускается, он может использовать сервер API, чтобы найти информацию о своем родительском задании, чтобы узнать, когда оно было запущено. Время запуска задания должно совпадать с временем, когда контейнер был запланирован CronJob.


Как Контейнер может узнать о своей родительской работе?

У меня пока нет решения, но я использовал curl чтобы провести несколько экспериментов, чтобы доказать, что я могу получать информацию о вакансиях из модуля

# 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

Сценарий необходим, чтобы найти родительское задание и запросить у него «время создания».