【问题标题】:How do I run delayed_jobs in Kubernetes?如何在 Kubernetes 中运行延迟作业?
【发布时间】:2019-02-04 19:48:09
【问题描述】:

我可以从其中一个 pod(在 kubernetes 上)登录控制台并运行以下命令:

RAILS_ENV=production bin/delayed_job start

作业运行正常。但是,当 pod 被删除或重新启动时,作业将停止运行。

我还尝试在初始化文件(例如 config/initializers/delayed_jobs_runner.rb)中添加上述命令,但在启动应用程序时出现递归循环。

我尝试做的另一件事是创建一个名为 my-jobs.yaml 的新文件

apiVersion: batch/v1
kind: Job
metadata:
  name: job
spec:
  template:
    spec:
      containers:
      - name: job
        image: gcr.io/test-app-123/somename:latest
        command: ["/bin/bash", "-l", "-c"]
        args: ["RAILS_ENV=production bundle exec rake jobs:work"]
      restartPolicy: Never
  backoffLimit: 4

然后我执行kubectl apply -f my-jobs.yaml,但作业没有运行。

知道如何在 kubernetes 中正确运行 delay_jobs 吗?

编辑:这是我的 Dockerfile:

FROM gcr.io/google_appengine/ruby

# Install 2.5.1 if not already preinstalled by the base image
RUN cd /rbenv/plugins/ruby-build && \
    git pull && \
    rbenv install -s 2.5.1 && \
    rbenv global 2.5.1 && \
    gem install -q --no-rdoc --no-ri bundler 
    # --version 1.11.2

ENV RBENV_VERSION 2.5.1

# Copy the application files.
COPY . /app/

# Install required gems.
RUN bundle install --deployment && rbenv rehash

# Set environment variables.
ENV RACK_ENV=production \
    RAILS_ENV=production \
    RAILS_SERVE_STATIC_FILES=true

# Run asset pipeline.
RUN bundle exec rake assets:precompile


CMD ["setup.sh"]


# Reset entrypoint to override base image.
ENTRYPOINT ["/bin/bash"]




################### setup.sh ############################
cd /app && RAILS_ENV=production bundle exec script/delayed_job -n 2 start
bundle exec foreman start --formation "$FORMATION"
#########################################################

【问题讨论】:

  • 这更像是一个建议,您是否尝试过查看此gem。它提供了专门运行作业、任务等的方法。
  • 您的工作失败或根本没有开始?您的日志/事件显示什么?
  • Nicola,工作开始很好。只是每次在 kubernetes 上创建/删除/重新创建新的 Pod 时,我都必须手动启动 delay_jobs 脚本。我必须登录到其中一个 pod 的 shell 并在控制台中运行“RAILS_ENV=production bin/delayed_job start”。有没有办法自动做到这一点?
  • tekuri,我用上面的 my-jobs.yaml 试过了,但不幸的是工作没有开始。

标签: ruby-on-rails kubernetes delayed-job


【解决方案1】:

现在我正在这样做:

this_pid=$$
(while [[ $(ps -ef | grep delayed_job | grep -v -e grep -e tail | head -c1 | wc -c) -ne 0 ]]; do sleep 10; done; kill -- -$this_pid) &

在启动多个工人之后。在此之后,我tail -f 日志,以便将它们转到容器的标准输出。我很疯狂,所以我也在运行 logrotate 来检查日志。无论如何,rails 环境非常大,所以容器需要非常大,我们需要能够运行许多作业,我不希望运行许多 pod 来这样做。这似乎很有效,如果工人因某种原因死亡,它将停止并重新启动。

【讨论】:

    【解决方案2】:

    在一个 docker 容器中运行多个进程是有问题的,因为您无法轻易观察特定进程的生命周期 - 每个容器都需要一个“主”进程,当它退出时,容器也会退出。

    在查看 Github (https://github.com/collectiveidea/delayed_job#user-content-running-jobs) 时,我强烈建议您更改一些启动命令以在前台运行它,因为现在当您使用守护程序启动 Kubernetes 作业时 - 作业将立即结束,因为 docker 容器的生命周期与“主”前台进程的生命周期直接相关,因此当您仅运行后台进程时,您的主进程和容器也会立即退出。

    将您的命令更改为:

    RAILS_ENV=production script/delayed_job run
    

    在前台启动 worker 以使您的 Kubernetes 作业不会退出。另请注意,Kubernetes 作业不适用于此类不定式任务(作业应具有开始和结束),因此我建议为此使用 ReplicaSet

    【讨论】:

    • 哇 Jakub!有用!我将 Dockerfile setup.sh 中的“cd /app && RAILS_ENV=production bundle exec script/delayed_job -n 2 start”更改为“cd /app && RAILS_ENV=production bundle exec script/delayed_job run”。但是,当我将它改回上一个命令(没有“运行”delayed_jobs 命令)时,delayed_jobs 在部署后仍然运行。这是预期的吗?我仍在测试它,但这看起来很有希望。非常感谢 Jakub!
    • 如果您将它们作为 Kubernetes 作业运行,请注意它们是不可变的,这意味着您无法在启动后更改它们的命令。您需要杀死特定的作业,删除并再次创建。
    • 好东西 Jakub。感谢您在这方面的大力帮助。我从你那里学到了很多关于 Kubernetes 的东西。太感谢了!!现在奖励你赏金:)
    • 感谢您在容器世界的冒险中的赏金和好运:)!
    • Rails 在很多情况下需要运行多个进程才能提高效率。我正在寻找一种方法来做好这件事。我们让它运行,并且我们正在放置一个tail命令来将日志作为前台。但是我们遇到的问题是,如果工作人员由于某种原因崩溃,它不会终止,例如云数据库重新启动或其他原因。我们在我们的 rails web pod 中运行 6 个 puma 服务器,并为此进行了健康检查。所以我也在对工作容器进行健康检查。诚然,一个不完美的解决方案。但比运行一个工人更有效率。
    猜你喜欢
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 2013-02-18
    • 2013-05-28
    相关资源
    最近更新 更多