Reputation: 1228
I'm using kubernetes secret as my environment variable (http://kubernetes.io/docs/user-guide/secrets/#using-secrets-as-environment-variables).
I've check whether env vars set correctly by
kubectl exec -it my_pod bash
1.
echo $RAILS_ENV #=> staging
2.
bin/rails c;
puts ENV['RAILS_ENV'] #=> staging
It works fine for my rails application and bash command, but doesn't work when executing cron process.
I've read some post to understand cron process (e.g. https://unix.stackexchange.com/questions/27289/how-can-i-run-a-cron-command-with-existing-environmental-variables) and know that I should source .profile or .bashrc before executing cron command like.
$ 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'
but both doesn't work for me ˊˋ
result
rails_env=
Any help will be appreciated!
===
[update: add kubernetes yaml config]
Both environment variables assign by kubernetes config and kubernetes secret can read in bash and rails application, but doesn't work in cron process.
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
Upvotes: 2
Views: 6415
Reputation: 1228
I found the solution after discussion with some guys.
The problem should be docker level not kubernetes level. https://ypereirareis.github.io/blog/2016/02/29/docker-crontab-environment-variables/
Cron process doesn't run as normal login-shell, so it didn't act as our expectation for read environment variables set by docker/k8s.
To solve the problem, we have to make cron process read environment variables first.
STEP1.
Add one line to dump environment variables at run_cron.sh
#!/bin/bash
# dump environment variables
printenv | sed 's/^\(.*\)$/export \1/g' >> /etc/profile.d/rails_env.sh
cron -f
STEP2.
Make cron read environment variables before executing command.
* * * * * . /etc/profile.d/rails_env.sh; ruby my_job.rb >> /tmp/cron.log 2>&1
or using bash --login option, which would every file under /etc/profile.d
* * * * * /bin/bash -l -c 'ruby my_job.rb >> /tmp/cron.log 2>&1'
Then cron work as expectation!
Upvotes: 3
Reputation: 178
Instead of running cron scripts inside the container, you should probably use CronJobs, where you can set env vars from secrets in the same way you do for deployments.
Upvotes: 3