Reputation: 26300
Let's say I and the partner company I'm dealing with live in a country that employs Daylight Saving Time.
I have a CronJob in a kubernetes cluster that uploads files to the partner company daily at, say, 4:00, 10:00, 16:00, and 22:00. E.g. 0 4,10,16,22 * * *
.
Kubernetes SIG decided that CronJob object will not support local timezone and will always run in the default one, which is UTC.
I can change the schedule, so that it reflects local time specified above in UTC and give the CronJob that schedule. However every time daylight saving kicks in (twice a year) I would need somehow modify all the CronJobs to use the new time, and I need to modify my deployment pipeline to create new releases of the CronJobs with the new time.
I cannot keep the CronJob running on the same schedule past daylight saving change, as the job will upload files not during the times expected by the partner.
What is the easiest way to manage this?
Option 1
It was suggested that writing a new kubernetes controller could do, but it does not seem that anyone raised up to that challenge and published working solution.
Option 2
Another option I have considered is changing the timezone of the entire cluster. But if you google it it does not seem to be very popular solution, and some people strongly believe that kubernetes being a cloud application should be run in UTC.
From what I understand cron
uses a local time zone which, in case of kubernetes will be the timezone of the controller manager, which is not necessary a timezone of the node it is running on. On the other hand, changing time zone of the controller manager container, sounds risky, as it is not clear how it will interact with other components of the kubernetes, such as etcd and kubelets.
Option 3
Doing it manually twice a year. Since people in the organisation come and go it would be difficult to retain the knowledge when and how. I do not want our partner to complain twice a year. Also it might be tricky to set up notifications for this as the dates change every year.
Option 4
Write some homegrown automation to run twice a year and hope that when time comes it works as expected. That is actually triggers, triggers at the right time and does everything it's supposed to do. (the latter is easier to test but the former is harder).
All these options feel quite unsatisfactory. I googled a lot and I have not found a lot, I feel it should be quite common issue, and yet nothing comes up in the search. Am I overlooking something? Is there an easy and natural way to solve it?
Upvotes: 16
Views: 12134
Reputation: 26300
Time Zones was added to CronJob in Kubernetes 1.22. To cite github thread
Just to clarify, it's available in 1.22.
It was implemented in a very strange way that's not exposed in the schema, though. I'm not aware of any explanation for why that was done, and it ignores core concepts behind Kubernetes. I think this still needs work.
It can be done via CRON_TZ
variable, as described here.
# ┌────────────────── timezone (optional)
# | ┌───────────── minute (0 - 59)
# | │ ┌───────────── hour (0 - 23)
# | │ │ ┌───────────── day of the month (1 - 31)
# | │ │ │ ┌───────────── month (1 - 12)
# | │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# | │ │ │ │ │ 7 is also Sunday on some systems)
# | │ │ │ │ │
# | │ │ │ │ │
# CRON_TZ=UTC * * * * *
Update
This feature is to be marked as unsupported
Update
Since Kubernetes 1.27 time zones in CronJobs are now supported.
kind: CronJob
apiVersion: batch/v1
metadata:
name: myCronjob
spec:
schedule: "10 1 * * *"
timeZone: Pacific/Auckland
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
metadata:
name: myCronjob
labels:
app: myCronjob
spec:
...
Upvotes: 2
Reputation: 241
Starting from kubernetes 1.24/1.25 there is a feature gate CronJobTimeZone
that allows you to set .spec.timeZone
to the name of a valid time zone. For example, setting .spec.timeZone
: "Etc/UTC" instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time. The feature gate is disabled by default in version 1.24 and enabled by default in version 1.25
Upvotes: 1
Reputation: 26481
Maybe I come a bit late to the party, but I believe that the easiest is to have two cronjobs running in combination with a tz-check
. When the time-zone matches the expected value, only then run command
A very nice post of detecting Daylight Saving Time, can be found here. Copying its examples, we can show that for the time-zone TZ=Europe/Stockholm, the time-zone changes to summer time depending on the date :
$ TZ=Europe/Stockholm date +%Z # CET or CEST depending of when its run
$ TZ=Europe/Stockholm date --date=20170101 +%Z # CET
$ TZ=Europe/Stockholm date --date=20170601 +%Z # CEST
$ TZ=CET date --date=20170101 +%Z # CET
$ TZ=CET date --date=20170601 +%Z # CEST, note that its auto adjusted to CEST
So, when staying in this example and assume the OP wants to run his cron on different times depending on if we are in DST or not, we could write the following crontab:
# Example of job definition:
# .--------------------- minute (0 - 59)
# | .---------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# command only runs in Europe/Stockholm Winter time
0 4-23/6 * * * tz-test "Europe/Stockholm" "CET" && command
# command only runs in Europe/Stockholm Summer time
0 3-23/6 * * * tz-test "Europe/Stockholm" "CEST" && command
Here, the times in the crontab definition are given in UTC (as the cron runs in UTC) and the tz-test
command is something like:
#!/usr/bin/env bash
tz=$(TZ="$1" date "+%Z")
[ "$tz" == "$2" ]
Note: You still have to be careful here. It might be possible that, due to the time-selection, your crontab runs twice or even more on the day the hour changes. In the above example, this is not the case.
Note: while this question was for Kubernetes, I'm convinced a similar implementation can be achieved within that framework.
Upvotes: 0
Reputation: 72
I know this is an old question but argo workflows has a Cron Workflows CRD that supports timezones and daylight saving. https://argoproj.github.io/argo-workflows/cron-workflows/#daylight-saving.
Upvotes: 0