Skip to content

k8tz/k8tz

Repository files navigation

Kubernetes Timezone Controller

Build Workflow Status Go Report Card codecov Go Version Contributor Covenant License

k8tz Logo

k8tz is a kubernetes admission controller and a CLI tool to inject timezones into Pods and CronJobs1.

Containers do not inherit timezones from host machines and have only accessed to the clock from the kernel. The default timezone for most images is UTC, yet it is not guaranteed and may be different from container to container. With k8tz it is easy to standardize selected timezone across pods and namespaces automatically with minimal effort.

Features

⚡ Coordinate timezone for all pods in clusters and/or namespaces (force UTC by default)

⚡ Standardize tzdata version across all pods in cluster

⚡ Does not require tzdata installed in images or nodes

⚡ Easy to configure with Helm values and Annotations

CLI tools for manual timezone injection

⚡ Supports Kubernetes 1.16+ and OpenShift 4.X

Read more: Timezone in Kubernetes With k8tz

Install Admission Controller (Helm)

Short Demo

tl;dr:

helm repo add k8tz https://k8tz.github.io/k8tz/
helm install k8tz k8tz/k8tz --set timezone=Europe/London

Read more in the chart README.

CLI

k8tz can be used as a command-line tool to inject timezone into yaml files or to be integrated inside another deployment script that don't want to use the admission controller automation.

Examples

You can process the test-pod.yaml from file-to-file or directly to kubectl:

# to a file
k8tz inject --strategy=hostPath test-pod.yaml > injected-test-pod.yaml

# or directly to kubectl
k8tz inject --timezone=Europe/London test-pod.yaml | kubectl apply -f -

Or you can inject to all existing deployments in current namespace:

kubectl get deploy -oyaml | k8tz inject - | kubectl apply -f -

NOTE: The injection process is idempotent; you can do it multiple times and/or use the CLI injection alongside the admission controller. Subsequent injections have no effect.

Download GitHub Release

You can install k8tz binary file by downloading precompiled binary and use it

wget -c https://github.com/k8tz/k8tz/releases/download/v0.16.0/k8tz_0.16.0_linux_amd64.tar.gz -O - | tar xz
chmod +x k8tz
./k8tz version

then install it to your $PATH with:

sudo install k8tz /usr/local/bin/k8tz

Go Install

If you have go installed, you can install k8tz with:

go install github.com/k8tz/k8tz@latest

Use Docker

You can use k8tz directly from Docker, here are some examples:

docker run -i quay.io/k8tz/k8tz --help

cat test-pod.yaml | docker run -i quay.io/k8tz/k8tz inject -tPortugal - | kubectl create -f

kubectl get deploy -oyaml | docker run -i quay.io/k8tz/k8tz inject - | kubectl apply -f

From Source

You can build k8tz binary from source yourself by simple running:

make compile

The created binary will be located at build/k8tz, you can then install it to your PATH using:

make TARGET=/usr/local/bin install

To uninstall, use sudo rm -v /usr/local/bin/k8tz.

Injection Strategy

Timezone information is defined using Time Zone Information Format files (TZif, RFC-8536). The Timezone Database contains TZif files that represent the local time for many locations around the globe. To set the container's timezone, /etc/localtime inside the container should point to a valid TZif file which represents the requested timezone. In most images these files do not exist by default, so we need to make them available from inside the container mounted at /etc/localtime.

Currently, there are 2 strategies how it can be done:

Using hostPath

If those files (which are located under /usr/share/zoneinfo) exist in every node on the cluster (it is the user's responsibility to ensure that), hostPath volume can be used to supply the required TZif file into the pod. If the required timezone will be missing on the host machine, the pod will be stuck in PodInitializing status and will not be started.

Using bootstrap initContainer

Another solution, which is generally safer, is to inject initContainer (bootstrap image) to the pod and supply the required TZif file using a shared emptyDir volume. This is the default method of k8tz.

Annotations

The behaviour of the controller can be changed using annotations on both Pod and/or Namespace objects. If the same annotation specified in both, the Pod's annotation value will take place.

Annotation Description Default
k8tz.io/inject Decide whether k8tz should inject timezone or not true
k8tz.io/timezone Decide what timezone should be used, e.g: Africa/Addis_Ababa UTC
k8tz.io/strategy Decide what injection strategy to use, i.e: hostPath/initContainer initContainer

Roadmap

  • Support StatefulSet injection
  • Support CronJob injection
  • Better way to lookup pod owner annotations
  • Test and document installation on OpenShift
  • Implement make install for easier installation from source
  • Add VERBOSE flag to helm
  • Write verbose logs for webhook
  • Separate README for Helm chart

Footnotes

  1. Timezones for CronJobs are available only from kubernetes >=1.24.0-beta.0 with CronJobTimeZone feature gate enabled.