使用開源工具 k8tz 優雅設置 Kubernetes Pod 時區

作者 | Andy

來源 | 進擊雲原生

容器在主機的核心上運行,並獲得時鐘,但時區不是來自核心,而是來自使用者空間。在大多數情況下,默認使用協調世界時 (UTC)。

時區的不一致,會帶來很多困擾。即使程式碼與時區無關,但容器日誌與系統日誌時間相關聯排查問題也會讓人頭疼。一些應用程序使用機器的時區作為默認時區,並希望使用者設置時區。當集群中容器的時區不一致時,管理會很不容易。

k8tz

k8tz是開源項目,請查看:github.com/k8tz/k8tz

k8tz是一個 Kubernetes 准入控制器和一個將時區注入 Pod 的 CLI 工具。可以用作手動工具來自動轉換 Deployment 和 Pod 可以作為準入控制器安裝並使用註釋來完全自動化創建 Pod 的過程。

k8tz可以使用hostPath的方式,或者將emptyDir注入initContainer並用 TZif(時區資訊格式) 檔案填充卷。然後將emptyDir掛載到 Pod 每個容器的/etc/localtime/usr/share/zoneinfo。為了確保所需的時區有效,它向所有容器添加了TZ環境變數。

安裝

用 Helm 安裝k8tz准入控制器:

helm repo add k8tz https://k8tz.github.io/k8tz/

helm install k8tz k8tz/k8tz --set timezone=Asia/Shanghai

查看 Pod 狀態、Mutatingwebhookconfigurations、Service 等資源是否正常:

# kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io k8tz

NAME WEBHOOKS AGE

k8tz 1 31m

# kubectl get svc -n k8tz

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

k8tz ClusterIP 10.233.212.11 443/TCP 31m

# kubectl get pod -n k8tz

NAME READY STATUS RESTARTS AGE

k8tz-59bb7f7cbd-5dzmq 1/1 Running 0 31m

測試

現在可以創建 Pod,不需要任何額外配置:

# kubectl run -i -t ubuntu --image=ubuntu:21.04 --restart=OnFailure --rm=true --command date

Defaulted container "ubuntu" out of: ubuntu, k8tz (init)

Wed Jun 15 14:11:53 CST 2022

pod "ubuntu" deleted

此時的 Pod yaml 如下,環境變數 TZ 使用安裝時指定的 Asia/Shanghai,以及注入了 initContainers、volumeMounts、volumes 等配置:

apiVersion: v1

kind: Pod

metadata:

labels:

run: ubuntu

name: ubuntu

namespace: default

spec:

containers:

- command:

- date

env:

- name: TZ

value: Asia/Shanghai

image: ubuntu:21.04

imagePullPolicy: IfNotPresent

name: ubuntu

volumeMounts:

- mountPath: /etc/localtime

name: k8tz

readOnly: true

subPath: Asia/Shanghai

- mountPath: /usr/share/zoneinfo

name: k8tz

readOnly: true

initContainers:

- args:

- bootstrap

image: quay.io/k8tz/k8tz:0.5.0

imagePullPolicy: IfNotPresent

name: k8tz

volumeMounts:

- mountPath: /mnt/zoneinfo

name: k8tz

volumes:

- emptyDir: {}

name: k8tz

還可以指定 annotations,例如k8tz.io/timezone=Europe/London選擇 pod 的時區:

# kubectl run -i -t ubuntu --image=ubuntu:21.04 --restart=OnFailure --rm=true --command date --annotations k8tz.io/timezone=Europe/London

Defaulted container "ubuntu" out of: ubuntu, k8tz (init)

Wed Jun 15 07:13:42 BST 2022

pod "ubuntu" deleted

或者使用註解k8tz.io/inject禁用時區注入 Pod :

# kubectl run -i -t ubuntu --image=ubuntu:21.04 --restart=OnFailure --rm=true --command date --annotations k8tz.io/inject=false

Wed Jun 15 06:14:47 UTC 2022

pod "ubuntu" deleted

如果你想使用hostPath而不是initContainer方式注入時區配置,可以使用k8tz.io/strategy註解:

# kubectl run -i -t ubuntu --image=ubuntu:21.04 --restart=OnFailure --rm=true --command date --annotations k8tz.io/strategy=hostPath

Wed Jun 15 14:15:26 CST 2022

pod "ubuntu" deleted

annotations 也可以在名稱空間中指定,並影響在名稱空間中創建的所有 pod。下面創建一個 test-k8tz namespace 用於測試:

# k create ns test-k8tz

namespace/test-k8tz created

# k annotate ns test-k8tz k8tz.io/strategy=hostPath

namespace/test-k8tz annotated

# k annotate ns test-k8tz k8tz.io/timezone=Europe/London

namespace/test-k8tz annotated

上面將策略設置為 hostPath 注入方式。因為安裝 k8tz 時默認時區已經設置為 Asia/Shanghai,所以這裡將 test-k8tz namespace 時區設置為 Europe/London,方便區分。

此時創建的 Pod 不需要加任何註解:

# kubectl run -n test-k8tz -i -t ubuntu --image=ubuntu:21.04 --restart=OnFailure --command date

Wed Jun 15 07:19:48 BST 2022

此時創建的 Pod yaml 如下,此時用的是 hostPath 注入方式:

apiVersion: v1

kind: Pod

metadata:

labels:

run: ubuntu

name: ubuntu

namespace: test-k8tz

spec:

containers:

- command:

- date

env:

- name: TZ

value: Europe/London

image: ubuntu:21.04

imagePullPolicy: IfNotPresent

name: ubuntu

volumeMounts:

- mountPath: /etc/localtime

name: k8tz

readOnly: true

subPath: Europe/London

- mountPath: /usr/share/zoneinfo

name: k8tz

readOnly: true

volumes:

- hostPath:

path: /usr/share/zoneinfo

type: ""

name: k8tz

結論

Kubernetes 中的時區問題有多種解決方案,這些解決方案可以手動實現,但在此過程中存在一些挑戰和限制。

使用k8tz可以自動執行該過程,確保系統中所有元件的時區一致,並且所有元件都可以訪問有關不同時區的資訊。並且無需額外設置或更改現有資源即可工作,即使在節點上沒有所需檔案時也是如此。

相關文章

安卓惡意軟體威脅的識別與應對

安卓惡意軟體威脅的識別與應對

由於新冠疫情的影響,駭客團伙對智慧手機的攻擊正在快速增長,大量惡意軟體在未經使用者允許的情況下被安裝到手機中。據最新調查資料顯示,目前已知的...

編譯器的最佳化真是太難了!

編譯器的最佳化真是太難了!

一個編譯器的好壞,主要是看這個編譯器最佳化的效果是否良好,但曾有一位倍受編譯器困擾的人曾說過:「最佳化設計是科學,但應用的順序是藝術。」 原...

機器學習真能產生智慧決策嗎?

機器學習真能產生智慧決策嗎?

作者 | 劉禮 出品 | AI科技大本營(ID:rgznai100) 歷經三年時間,我們在2022年完成了圖靈獎獲得者、加州大學洛杉磯分校電...