쿠버네티스 시간대 컨트롤러
Build Workflow Status
Go Report Card
codecov
Go Version
Contributor Covenant
License
k8tz Logo
k8tz는 Pod와 CronJob에 시간대(timezone)를 주입하는 쿠버네티스 어드미션 컨트롤러(admission controller)이자 CLI 도구입니다1.
컨테이너는 호스트 머신으로부터 시간대를 상속받지 않으며 커널로부터의 클럭 접근만 가능합니다. 대부분의 이미지에서 기본 시간대는 UTC이지만, 이는 보장되지 않으며 컨테이너마다 다를 수 있습니다. k8tz를 사용하면 최소한의 노력으로 선택된 시간대를 Pod와 네임스페이스 전반에 걸쳐 자동으로 표준화하기 쉽습니다.
기능 (Features)
:zap: 클러스터 및/또는 네임스페이스 내 모든 Pod의 시간대 조정 (기본값은 UTC 강제 적용)
:zap: 클러스터 내 모든 Pod에서 tzdata 버전을 표준화합니다.
:zap: 이미지나 노드에 tzdata가 설치되어 있을 필요가 없습니다.
:zap: Helm values와 Annotations를 사용하여 설정하기 쉽습니다.
:zap: 수동 시간대 주입을 위한 CLI 도구를 제공합니다.
:zap: Kubernetes 1.16+ 및 OpenShift 4.X를 지원합니다.
더 알아보기: k8tz를 사용한 쿠버네티스에서의 시간대
어드미션 컨트롤러 설치 (Helm)
Short Demo
요약:
helm repo add k8tz https://k8tz.github.io/k8tz/
helm install k8tz k8tz/k8tz --set timezone=Europe/London
차트의 README에서 더 자세한 내용을 읽어보세요.
CLI
k8tz는 YAML 파일에 시간대를 주입하는 명령줄 도구로 사용되거나, 어드미션 컨트롤러 자동화를 사용하고 싶지 않은 다른 배포 스크립트 내부에 통합될 수 있습니다.
예시 (Examples)
파일 간(file-to-file) 또는 kubectl에 직접 test-pod.yaml을 처리할 수 있습니다:
# 파일로 저장하기
k8tz inject --strategy=hostPath test-pod.yaml > injected-test-pod.yaml
...
현재 네임스페이스의 모든 기존 배포본(deployment)에 주입할 수도 있습니다:
kubectl get deploy -oyaml | k8tz inject - | kubectl apply -f -
참고: 이 주입 프로세스는 멱등성(idempotent)을 가지므로 여러 번 수행하거나 어드미션 컨트롤러와 함께 CLI 주입을 사용할 수 있습니다. 이후의 주입은 아무런 영향을 미치지 않습니다.
GitHub 릴리스 다운로드
사전 컴파일된 바이너리를 다운로드하여 k8tz 바이너리 파일을 설치하고 사용할 수 있습니다:
wget -c https://github.com/k8tz/k8tz/releases/download/v0.21.0/k8tz_0.21.0_linux_amd64.tar.gz -O - | tar xz
chmod +x k8tz
./k8tz version
그런 다음 다음 명령어로 $PATH에 설치합니다:
sudo install k8tz /usr/local/bin/k8tz
Go로 설치
go가 설치되어 있다면, 다음 명령어를 사용하여 k8tz를 설치할 수 있습니다:
go install github.com/k8tz/k8tz@latest
Docker 사용
k8tz를 Docker에서 직접 사용할 수 있으며, 몇 가지 예시가 있습니다:
docker run -i quay.io/k8tz/k8tz --help
cat test-pod.yaml | docker run -i quay.io/k8tz/k8tz inject -tPortugal - | kubectl create -f
...
소스에서 빌드
다음과 같이 간단히 실행하여 직접 k8tz 바이너리를 빌드할 수 있습니다:
생성된 바이너리는 build/k8tz에 위치하며, 다음 명령어를 사용하여 PATH에 설치할 수 있습니다:
make TARGET=/usr/local/bin install
제거하려면 sudo rm -v /usr/local/bin/k8tz를 사용하십시오.
주입 전략 (Injection Strategy)
시간대 정보는 시간대 정보 형식 파일(TZif, RFC-8536)을 사용하여 정의됩니다. 시간대 데이터베이스에는 전 세계 여러 위치의 현지 시간을 나타내는 TZif 파일이 포함되어 있습니다. 컨테이너의 시간대를 설정하려면, 컨테이너 내부의 /etc/localtime이 요청된 시간대를 나타내는 유효한 TZif 파일을 가리켜야 합니다. 대부분의 이미지에서는 기본적으로 이러한 파일이 존재하지 않으므로, 우리는 이 파일들을 컨테이너 내부에서 /etc/localtime에 마운트하여 사용할 수 있도록 만들어야 합니다.
현재 이를 수행할 수 있는 2가지 전략이 있습니다:
hostPath 사용
만약 해당 파일들(경로: /usr/share/zoneinfo)이 클러스터의 모든 노드에 존재한다면(이는 사용자 책임임), hostPath 볼륨을 사용하여 필요한 TZif 파일을 파드(pod) 내부로 공급할 수 있습니다. 만약 필요한 시간대 정보가 호스트 머신에 누락된 경우, 해당 파드는 PodInitializing 상태에 갇히게 되어 시작되지 않습니다.
부트스트랩 initContainer 사용하기
또 다른 방법은 initContainer(부트스트랩 이미지)를 파드에 주입하고 공유되는 emptyDir 볼륨을 사용하여 필요한 TZif 파일을 공급하는 것입니다. 이는 k8tz의 기본 방식입니다.
imageVolume 사용하기
Kubernetes 1.33 버전 이상에서는 k8tz가 imageVolume 전략을 사용하여 공유되는 emptyDir 볼륨이 필요 없이 /usr/share/zoneinfo를 k8tz 이미지에서 직접 마운트할 수 있습니다. 하지만 현재 imageVolume은 이미지로부터 /etc/localtime을 마운트하는 것을 지원하지 않기 때문에, 여전히 initContainer가 권장되는 전략입니다.
어노테이션 (Annotations)
컨트롤러의 동작 방식은 Pod 및/또는 Namespace 객체에 적용된 어노테이션을 사용하여 변경할 수 있습니다. k8tz는 모든 어노테이션 키를 독립적으로 해석하므로, 특정 어노테이션을 정의하는 Pod에 가장 가까운 객체가 해당 어노테이션에 대해 우선권을 가집니다.
| 어노테이션 | 설명 | 기본값 |
|---|
k8tz.io/inject | k8tz가 시간대를 주입할지 여부를 결정합니다 | true |
| ... | | |
| 기본적으로 파드 승인 어노테이션 상속 순서는 다음과 같습니다: | | |
Pod -> Namespace -> webhook 기본값
베타(Beta) 파드 소유자 조회는 웹훅 --podOwnerLookup 플래그 또는 Helm의 podOwnerLookup=true 값을 통해 활성화할 수 있습니다. 이 기능이 활성화되면 어노테이션 상속 순서는 다음과 같습니다:
Pod -> 컨트롤러 소유자(controller owners) -> Namespace -> webhook 기본값
지원되는 컨트롤러 소유자 체인(controller owner chains)은 ReplicaSet -> Deployment, Job -> CronJob, 그리고 직접적인 StatefulSet 또는 DaemonSet 소유권입니다.
로드맵