【问题标题】:Openshift 3 CronJob inside running container正在运行的容器内的 Openshift 3 CronJob
【发布时间】:2018-07-29 16:38:39
【问题描述】:

如果我理解正确,您可以将 Openshift 配置为运行 cronjobs,它会定期运行作业。此外,每次 cronjob 触发时,作业似乎都会运行一个新容器。

我需要一种方法来每分钟运行一个命令,但在一个正在运行的容器/pod/deployment 中,而不是每次都创建一个新容器。 我们使用 Openshift 来部署我们的 php 7 / Laravel 应用程序。这个框架使用一个内置的调度器。为了让它工作,你必须每分钟用“php artisan run”触发框架。

据我了解,不应更改容器映像 (php+apache) 以包含 cron 服务。但是我应该怎么做呢?

【问题讨论】:

    标签: php laravel cron openshift scheduler


    【解决方案1】:

    对此我有一个有点非常规的解决方案。 OpenShift/Kubernetes 有"Application Health Checks" 的概念。这基本上是平台经常运行的东西(按照定义),可以进行 HTTP 调用、TCP 连接或在容器内执行操作。这样做的副作用是容器中运行的命令失败,你的 pod 将被重新启动。这通常用于检查应用程序是否不再响应并允许平台将其关闭并重新启动。

    但是,它完全可以完全按照您的需要进行操作,并且不需要使用目前仅在技术预览中可用的 CronJobs。

    您应该能够运行以下命令,这将 patch 您当前的 DeploymentConfig 包含一个 livenessProbe,它将每分钟运行一次 php artisan run

    oc patch dc/<deployment-name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"<deployment-name>","livenessProbe":{"exec":{"command":["/bin/bash","-c","php","artisan","run","||","true"]},"initialDelaySeconds":60,"periodSeconds":60,"timeoutSeconds":120}}]}}}}'

    请注意,您需要在上述命令中提供两次deployment-name

    这将告诉 OpenShift 在 pod 启动 60 秒后运行 /bin/bash -c php artisan run || true,继续每 60 秒运行一次,如果命令运行时间超过 120 秒,则认为它失败。如果命令超时超过 3 次,则 pod 将被视为不健康并重新启动(|| true 确保即使命令失败,它也不会杀死 pod。

    【讨论】:

    • 非常感谢!我能够通过 openshift 的 UI 创建一个 livenessProbe。我唯一需要更改的是 periodSeconds(通过 yaml),因为 UI 中没有这样的选项(默认为 10 秒)。直到今天,我通过创建自定义映像的部署构建了另一个解决方案,该映像通过 oc 二进制文件登录到 openshift,通过特定标签 (laravel=uses-scheduler) 过滤所有 pod,然后对过滤后的 pod 执行 oc exec。无论如何,您的解决方案要轻量级得多。
    【解决方案2】:

    我想附加到这个问题,因为我刚刚让它与 Openshift 的本机 cron 作业功能一起使用。此功能使用您选择的现有映像构建一个新 pod,运行您选择的命令(在本例中为“php artisan schedule:run”),然后关闭 pod。 Openshift 的在线文档中对此进行了概述。我使用 YAML 以及界面中的“使用 YAML/JSON 导入到项目”选项来创建 pod。如果我需要删除 cron 作业,我在 CLI 中使用“oc delete cronjob/myCron”。

    这里是 YAML 示例:

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: myCron
    spec:
      schedule: "*/1 * * * *"  
      jobTemplate:             
        spec:
          template:
            metadata:
              labels:          
                parent: "myCron"
            spec:
              containers:
              - name: myCron
                image: docker-registry.default.svc:5000/adv-dev/myApplication
                command: [php, artisan, "schedule:run"]
                envFrom:
                - configMapRef:
                    name: my-config-map
              restartPolicy: OnFailure
    

    注意:

    • myCron 是一个任意名称,但使用特定于需要运行 cron 的应用程序的名称。
    • "*/1 * * * *" 是经典的 crontab 调度格式。在这里,它将作业设置为每分钟运行一次。
    • 映像“docker-registry.default.svc:5000/adv-dev/myApplication”是需要 cron 的 pod 的现有映像。请记住,此 cron 作业不会在现有 pod 中运行。相反,openshift 将使用具有完全相同代码库的相同映像启动一个新 pod,并在该新 pod 中运行命令行。在它运行后,openshift 将拆除 cron 作业 pod,留下带有日志的历史记录以供查看。默认情况下,将保留 3 个最近的 pod 历史记录。
    • envFrom 部分是您为 cron 作业 pod 注入 env 变量(DB/SMTP 用户名/密码等)的地方。它们需要是一个配置映射,以便它们可以被导入并可供代码使用。这意味着您还可以在运行应用程序的“永久”pod 中使用相同的配置映射以避免重复。

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      相关资源
      最近更新 更多