【问题标题】:How can I run a cron command with environmental variables set by kubernetes secret如何使用 kubernetes secret 设置的环境变量运行 cron 命令
【发布时间】:2017-05-05 19:58:15
【问题描述】:

我使用 kubernetes secret 作为我的环境变量 (http://kubernetes.io/docs/user-guide/secrets/#using-secrets-as-environment-variables)。

我检查了 env vars 设置是否正确

kubectl exec -it my_pod bash

1.

echo $RAILS_ENV #=> staging

2.

bin/rails c;
puts ENV['RAILS_ENV'] #=> staging

它适用于我的 rails 应用程序和 bash 命令,但在执行 cron 进程时不起作用。

我已经阅读了一些帖子以了解 cron 进程(例如 https://unix.stackexchange.com/questions/27289/how-can-i-run-a-cron-command-with-existing-environmental-variables)并且知道在执行 cron 命令之前我应该​​获取 .profile 或 .bashrc。

$ crontab -l

* * * * * . $HOME/.profile; /bin/bash -l -c 'echo rails_env=$RAILS_ENV >> /tmp/cron_test.log'

* * * * * . $HOME/.bashrc; /bin/bash -l -c 'echo rails_env=$RAILS_ENV >> /tmp/cron_test.log'

但两者都不适合我ˊˋ

结果

rails_env=

任何帮助将不胜感激!

===

[更新:添加 kubernetes yaml 配置]

kubernetes config 和 kubernetes secret 分配的环境变量都可以在 bash 和 rails 应用程序中读取,但在 cron 进程中不起作用。

deployment.yaml

spec:
  containers:
  - name: my_rails
  ...
    command:
    - bash
    args:
    - /tmp/run_cron.sh
  ...
    env:
      - name: RAILS_ENV
        value: staging
      - name: MYSQL_PASSWORD
        valueFrom:
          secretKeyRef:
            name: rails-secret
            key: MYSQL_PASSWORD

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: rails-secret
type: Opaque
data:
  MYSQL_PASSWORD: ENCODED_PASSWORD

【问题讨论】:

  • 您在哪个文件中将RAILS_ENV 设置为“暂存”?
  • @Brian 我使用 kubernetes secret 作为环境变量,但我不了解 kubernetes 如何实现的细节。
  • RAILS_ENV 与“kubernetes secret”有什么关系?
  • @Brian RAILS_ENV 是 kubernetes secret 设置的环境变量之一,还有 MYSQL_PASSWD 这样的其他值,您可以将 secret 视为键/值对数据存储。生命周期可能像 1. kubernetes 启动一个 pod(容器) 2. 将 secret 作为环境变量加载(我不完全理解) 3. 在 Dockerfile CMD 执行命令分配(这里运行一个 cron 进程)。
  • 你能告诉我们这个 cron 在哪里/如何被执行吗?您使用的是 k8s 作业还是 cronjob?请添加您正在使用的 yaml 规范文件。

标签: ruby-on-rails bash cron debian kubernetes


【解决方案1】:

我和一些人讨论后找到了解决方案。

问题应该是 docker 级别而不是 kubernetes 级别。 https://ypereirareis.github.io/blog/2016/02/29/docker-crontab-environment-variables/

Cron 进程不会像正常的 login-shell 一样运行,因此它没有像我们预期的那样读取 docker/k8s 设置的环境变量。

要解决这个问题,我们得先让cron进程读取环境变量。

第 1 步。

在run_cron.sh添加一行dump环境变量

#!/bin/bash

# dump environment variables
printenv | sed 's/^\(.*\)$/export \1/g' >> /etc/profile.d/rails_env.sh

cron -f

第二步。

让cron在执行命令前读取环境变量。

* * * * * . /etc/profile.d/rails_env.sh; ruby my_job.rb >> /tmp/cron.log 2>&1

或使用 bash --login 选项,这将 /etc/profile.d 下的每个文件

* * * * * /bin/bash -l -c 'ruby my_job.rb >> /tmp/cron.log 2>&1'

然后 cron 按预期工作!

【讨论】:

  • 我使用了类似的方法,但在sed 命令中使用了export >> /etc/profile.d/rails_env.sh 而不是printenv。然后我 source 文件并在我的 crontab 中运行脚本。
【解决方案2】:

您可能应该使用CronJobs,而不是在容器内运行 cron 脚本,您可以在其中以与部署相同的方式从秘密中设置环境变量。

【讨论】:

  • 我看过CronJob 文档,但没有做更多调查。我有两个问题,1.是否可以通过容器内的系统 cron 读取由 k8s secret 设置的环境变量? 2. 使用 CronJob 代替系统 cron 有什么好处吗?而 CronJob 目前处于 alpha 阶段,这是否意味着它还不稳定?谢谢
  • 您可以继续使用 CronJob 而不必担心太多。 Amanpreet 是对的,您绝对应该使用 CronJob、ScheduledJob 或至少一个 Job。您现在正在使用部署吗?
  • @iamnat 嗯...我必须说服我们的 devops 领导升级 k8s 集群并首先使用 alpha 功能。是的,我现在正在使用部署。
猜你喜欢
  • 2014-06-01
  • 1970-01-01
  • 2021-12-25
  • 2013-08-08
  • 2022-11-20
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多