1. κ°μ
컨ν μ΄λ νκ²½μμ νμμ‘΄(Timezone)μ΄ λ§μ§ μμΌλ©΄ λ‘κ·Έ μκ°μ΄ μ΄κΈλκ³ μ€μΌμ€λ¬κ° μλͺ»λ μκ°μ λμνλ€. λμλ‘μ§ μκ² λκ²Όλ€κ° λμ€μ λλ²κΉ μ΄ λ³΅μ‘ν΄μ§λ κ²½μ°κ° λ§μΌλ―λ‘, 컨ν μ΄λ νμμ‘΄ μ€μ λ°©λ²μ μ λ¦¬ν΄ λμλ€.
2. μ΄μ
μΏ λ²λ€ν°μ€(Kubernetes) μμ λμ μ€μΈ νλ(Pod)λ§λ€ μλ‘ λ€λ₯Έ timezoneμ κ°μ§κ³ μμκ³ , μ΄λ₯Ό GMT+9 (Asia/Seoul)λ‘ μΌκ΄ λ³ννλ λ°©λ²μ΄ νμνλ€.
3. ν΄κ²°
컨ν μ΄λμ νμμ‘΄μ μ€μ νλ μ£Όμ λ°©λ²μ λ€μκ³Ό κ°λ€.
1. Dockerfileμ ν΅ν μ€μ (Build-time)
컨ν μ΄λ μ΄λ―Έμ§λ₯Ό λΉλνλ μμ μ Dockerfile λ΄μμ νμμ‘΄μ μ€μ νλ λ°©λ²μ΄λ€. μ΄ λ°©λ²μ 컨ν μ΄λκ° μμλ λλ§λ€ λ³λμ μ€μ μμ΄ μΌκ΄λ νμμ‘΄μ 보μ₯νμ¬ κ°μ₯ κΆμ₯λλ λ°©μ μ€ νλμ΄λ€.
- μ리: λλΆλΆμ Linux μμ€ν
μ
/etc/timezoneνμΌμ νμμ‘΄ μ 보λ₯Ό μ μ₯νκ±°λ,/etc/localtimeνμΌμ΄ μ€μ νμμ‘΄ λ°μ΄ν° νμΌ(μ:/usr/share/zoneinfo/Asia/Seoul)μ κ°λ¦¬ν€λ μ¬λ³Όλ¦ λ§ν¬λ‘ ꡬμ±λλ€.tzdataν¨ν€μ§λ μ΄λ¬ν νμμ‘΄ λ°μ΄ν° νμΌμ μ 곡νλ€.ENV TZλͺ λ Ήμ΄λ 컨ν μ΄λ λ΄λΆμ νκ²½ λ³μλ₯Ό μ€μ νμ¬ μμ€ν μ΄ ν΄λΉ νμμ‘΄μ μ¬μ©νλλ‘ μ§μνλ€.
# μμ: Ubuntu/Debian κΈ°λ° μ΄λ―Έμ§
FROM ubuntu:latest
# tzdata ν¨ν€μ§ μ€μΉ (νμμ‘΄ λ°μ΄ν° μ 곡)
# noninteractive λͺ¨λλ‘ μ€μΉνμ¬ μ¬μ©μ μ
λ ₯ μμ΄ μ§ν
RUN apt-get update && apt-get install -y tzdata && rm -rf /var/lib/apt/lists/*
# νκ²½ λ³μ TZλ₯Ό Asia/Seoulλ‘ μ€μ
ENV TZ=Asia/Seoul
# μ ν리μΌμ΄μ
μ€ν λͺ
λ Ήμ΄ (μμ)
CMD ["/bin/bash"]μ΄μμ±μ κ°μ₯ μ’μ§λ§, νμμ‘΄μ λ°κΏ λλ§λ€ μ΄λ―Έμ§λ₯Ό λ€μ λΉλν΄μΌ νλ€. λ©ν νκ²½λ§λ€ νμμ‘΄μ΄ λ€λ₯Ό μ μμΌλ νμλ μ μ°μ§ μλλ€.
2. Volume Mountλ₯Ό ν΅ν μ€μ (Run-time)
νΈμ€νΈ μμ€ν μ νμμ‘΄ μ 보λ₯Ό 컨ν μ΄λ λ΄λΆλ‘ λ§μ΄νΈνμ¬ μ¬μ©νλ λ°©λ²μ΄λ€. μ΄ λ°©λ²μ 컨ν μ΄λ μ΄λ―Έμ§λ₯Ό μμ νμ§ μκ³ λ°νμμ νμμ‘΄μ μ μ°νκ² μ€μ ν μ μλ€.
- μ리: νΈμ€νΈ μμ€ν
μ
/etc/localtimeνμΌ λλ/usr/share/zoneinfoλλ ν 리λ₯Ό 컨ν μ΄λ λ΄λΆμ/etc/localtimeκ²½λ‘λ‘ λ§μ΄νΈνλ€. 컨ν μ΄λλ λ§μ΄νΈλ νΈμ€νΈμ νμμ‘΄ μ 보λ₯Ό μ¬μ©νκ² λλ€.
Docker CLI
$ docker run -d \
-v /etc/localtime:/etc/localtime:ro \
-v /usr/share/zoneinfo/Asia/Seoul:/etc/localtime:ro # νΉμ νμμ‘΄ νμΌ λ§μ΄νΈ (λ λͺ
μμ )
your-image-name/etc/localtime:/etc/localtime:ro: νΈμ€νΈμ νμ¬ νμμ‘΄ μ€μ μ 컨ν μ΄λλ‘ μ½κΈ° μ μ©(read-only)μΌλ‘ λ§μ΄νΈνλ€./usr/share/zoneinfo/Asia/Seoul:/etc/localtime:ro: νΈμ€νΈμ νΉμ νμμ‘΄ λ°μ΄ν° νμΌ(Asia/Seoul)μ 컨ν μ΄λμ/etc/localtimeλ‘ λ§μ΄νΈνλ€. μ΄ λ°©λ²μ νΈμ€νΈμ νμ¬ νμμ‘΄ μ€μ κ³Ό 무κ΄νκ² μ»¨ν μ΄λμ νΉμ νμμ‘΄μ κ°μ ν λ μ μ©νλ€.
Kubernetes νκ²½
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-container
image: your-image-name
volumeMounts:
- name: tz-config
mountPath: /etc/localtime # /etc/localtime νμΌμ λ§μ΄νΈ
readOnly: true
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Seoul # νΈμ€νΈμ Asia/Seoul νμμ‘΄ νμΌμ μ¬μ©
type: File # νμΌμμ λͺ
μ- μ₯μ :
- μ΄λ―Έμ§ μ¬λΉλ μμ΄ λ°νμμ νμμ‘΄μ λ³κ²½ν μ μλ€.
- νΈμ€νΈμ νμμ‘΄κ³Ό λκΈ°ννκ±°λ, νΈμ€νΈμ μ‘΄μ¬νλ νΉμ νμμ‘΄ νμΌμ μ ννμ¬ μ¬μ©ν μ μλ€.
- λ¨μ :
- 컨ν μ΄λκ° νΈμ€νΈ μμ€ν μ μμ‘΄νκ² λλ€. νΈμ€νΈμ νμμ‘΄ μ€μ μ΄ λ³κ²½λλ©΄ 컨ν μ΄λμλ μν₯μ λ―ΈμΉλ€.
hostPathμ¬μ© μ λ Έλ κ° μ΄μμ±μ΄ μ νλ μ μλ€ (λͺ¨λ λ Έλμ λμΌν νμμ‘΄ νμΌμ΄ μ‘΄μ¬ν΄μΌ νλ€).- 보μμμ μ΄μ λ‘
hostPathμ¬μ©μ μ ννλ νκ²½λ μλ€.
3. νκ²½ λ³μ TZλ§ μ€μ (Run-time)
컨ν
μ΄λ μ΄λ―Έμ§μ μ΄λ―Έ tzdata ν¨ν€μ§κ° μ€μΉλμ΄ μλ κ²½μ°, TZ νκ²½ λ³μλ§ μ€μ νμ¬ νμμ‘΄μ λ³κ²½ν μ μλ€.
- μ리:
TZνκ²½ λ³μλ C λΌμ΄λΈλ¬λ¦¬(glibc)μμ μκ°μ μ²λ¦¬ν λ μ°Έμ‘°νλ νμμ‘΄μ μ§μ νλ€.tzdataν¨ν€μ§κ° μ€μΉλμ΄ μλ€λ©΄,/usr/share/zoneinfoκ²½λ‘μ λ€μν νμμ‘΄ λ°μ΄ν° νμΌμ΄ μ‘΄μ¬νλ©°,TZλ³μλ μ΄ μ€ μ΄λ€ νμΌμ μ¬μ©ν μ§ μλ €μ£Όλ μν μ νλ€.
Docker CLI
$ docker run -d \
-e TZ=Asia/Seoul \
your-image-nameKubernetes νκ²½
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-container
image: your-image-name
env:
- name: TZ
value: Asia/Seoulκ°μ₯ κ°λ¨νκ³ μ μ°ν΄μ νμκ° μ£Όλ‘ μ°λ λ°©λ²μ΄λ€. tzdataλ§ μ΄λ―Έμ§μ λ€μ΄μμΌλ©΄ νκ²½λ³μ νλλ‘ λλλ€. λ€λ§ tzdataκ° μμΌλ©΄ TZκ° λ¬΄μλκ³ UTCλ‘ λ¨μ΄μ§λ, λ² μ΄μ€ μ΄λ―Έμ§μ ν¬ν¨λμ΄ μλμ§ νμΈμ΄ νμνλ€.
4. timedatectl λͺ
λ Ήμ΄ μ¬μ© (컨ν
μ΄λ λ΄λΆ)
μΌλΆ 컨ν
μ΄λ μ΄λ―Έμ§μλ systemdκ° ν¬ν¨λμ΄ μμ§ μμ timedatectl λͺ
λ Ήμ΄λ₯Ό μ§μ μ¬μ©ν μ μλ κ²½μ°κ° λ§λ€. νμ§λ§ λλ²κΉ
λͺ©μ μ΄λ νΉμ λ² μ΄μ€ μ΄λ―Έμ§μμλ μ μ©ν μ μλ€.
# 컨ν
μ΄λ λ΄λΆμμ μ€ν (μμ)
$ docker exec -it <container_id> /bin/bash
# 컨ν
μ΄λ μ λ΄λΆμμ
$ timedatectl set-timezone Asia/SeoulλλΆλΆμ κ²½λ 컨ν
μ΄λμλ systemdκ° μμ΄μ μ΄ λͺ
λ Ήμ΄λ₯Ό μ¬μ©ν μ μλ€. μ¬μμνλ©΄ μ€μ λ μ μ§λμ§ μμΌλ―λ‘ λλ²κΉ
μ©λ μΈμλ μλ―Έκ° μλ€.
4. νμΈ
컨ν μ΄λ λ΄λΆμμ νμμ‘΄μ΄ μ¬λ°λ₯΄κ² μ€μ λμλμ§ νμΈνλ λ°©λ²μ΄λ€.
# date λͺ
λ Ήμ΄ μ¬μ©
$ date
Tue Nov 22 07:44:20 KST 2022 # μμ μΆλ ₯: KST (νκ΅ νμ€μ)λ‘ νμλμλ€.
# timedatectl λͺ
λ Ήμ΄ μ¬μ© (timedatectlμ΄ μ€μΉλ κ²½μ°)
$ timedatectl
Local time: ν 2022-11-22 07:44:20 KST
Universal time: μ 2022-11-21 22:44:20 UTC
RTC time: μ 2022-11-21 22:44:20
Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
NTP service: active
RTC in local TZ: noμμ½
| λ°©λ² | μ₯μ | λ¨μ | κΆμ₯ μλλ¦¬μ€ |
|---|---|---|---|
| Dockerfile | μ΄λ―Έμ§μ νμμ‘΄ λ΄μ₯, μ΄μμ± λμ, μΌκ΄λ μ€μ 보μ₯ | μ΄λ―Έμ§ μ¬λΉλ νμ, μ΄λ―Έμ§ ν¬κΈ° μ½κ° μ¦κ° | λλΆλΆμ νλ‘λμ νκ²½, μΌκ΄λ νμμ‘΄μ΄ νμν κ²½μ° |
| Volume Mount | μ΄λ―Έμ§ μ¬λΉλ λΆνμ, λ°νμ μ μ°μ±, νΈμ€νΈμ λκΈ°ν κ°λ₯ | νΈμ€νΈ μμ‘΄μ±, λ
Έλ κ° μ΄μμ± μ ν, hostPath 보μ λ¬Έμ | λ°νμμ νμμ‘΄ λ³κ²½μ΄ μ¦κ±°λ νΈμ€νΈμ λκΈ°νκ° νμν κ²½μ° |
νκ²½ λ³μ TZ | κ°μ₯ κ°λ¨, μ΄λ―Έμ§ μ¬λΉλ λΆνμ, λ°νμ μ μ°μ± | tzdata μ€μΉ νμ, μ€μΉλμ§ μμ κ²½μ° κΈ°λ³Έ UTC | tzdataκ° ν¬ν¨λ κ²½λ μ΄λ―Έμ§ μ¬μ© μ, κ°λ¨ν μ€μ |
timedatectl | 컨ν μ΄λ λ΄λΆμμ μ§μ μ€μ κ°λ₯ | λλΆλΆμ κ²½λ μ΄λ―Έμ§μμ μ¬μ© λΆκ°, 컨ν μ΄λ μ¬μμ μ μ€μ μ μ§ μλ¨, λλ²κΉ λͺ©μ μΈ λΉκΆμ₯ | λλ²κΉ λͺ©μ , νΉμ λ² μ΄μ€ μ΄λ―Έμ§ μ¬μ© μ |
μ°Έκ³
- https://dev.to/0xbf/set-timezone-in-your-docker-image-d22
- Docker 곡μ λ¬Έμ: Configure timezone (ENV λͺ λ Ήμ΄ κ΄λ ¨)
- Kubernetes 곡μ λ¬Έμ: Volumes - hostPath (hostPath κ΄λ ¨)
- Linux man page: tzset(3) (TZ νκ²½ λ³μ κ΄λ ¨)