在Docker容器中配置时区
在 Linux 中, 通过 /etc/timezone
这个文件设置。 可以通过如下命令 持久化 时区设置, 其中 Asia/Shanghai
是我们需要的时区。
1 | cp -a /usr/share/zoneinfo/Asia/Shanghai /etc/timezone |
另外,也可以通过如下方式配置:
1 2 3 4 5 6 7 | #修改时区 rm -f /etc/localtime ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime timedatectl set-timezone "Asia/Shanghai" timedatectl set-ntp true systemctl restart ntpd systemctl status ntpd |
容器中设置时区一直是独立于宿主机的。可以通过挂载 /etc/timezone
的方式保持与宿主机时间一致。
1 | docker run --rm -it -v /etc/timezone:/etc/timezone debian bash |
这种方法只适合 本地的、简单的、临时的 容器。
也可以在创建容器的时候配置如下的参数:
1 | -e "TZ=Asia/Shanghai" |
容器有一个很重要的特点, 就是 一处编译, 处处运行。另外, 容器运行环境本身应该是 独立/隔离 的, 即使是时区也不应该依赖于宿主机。
通过TZ 环境变量设置时区
在 Linux 中, 还可以通过 TZ
这个环境变量来设置时区。但是这种设置并不能实现持久化, 只能在 当前进程和其子进程 中生效。
1 | export TZ=Asia/Shanghai |
这种方式在 Linux 系统中不合适, 但是在容器中却相当合适。因为容器核心就是 单进程应用, 不会像 Linux 系统上启动很多。
1 2 3 4 5 6 | $ date Wed Dec 21 14:06:44 UTC 2022 $ export TZ=Asia/Shanghai $ date Wed Dec 21 22:06:52 CST 2022 |
如果需要是用 TZ 环境变量 实现时区控制, 需要安装 tzdata
这个包。
在 debian/ubuntu 中安装。
debian
的基础镜像默认情况下已经安装了 tzdata
,而 ubuntu
并没有。tzdata
安装时有交互操作, 需要选择默认时区。通过 DEBIAN_FRONTEND=noninteractive
进入非交互模式, 直接安装。
1 | DEBIAN_FRONTEND=noninteractive apt install -y tzdata |
在 alpine 中安装
1 | apk add --no-cache tzdata |
容器中通过TZ 环境变量实现时区控制
- 我们需要在构建业务镜像的时候安装
tzdata
并设置 默认时区。 - 在容器启动的时候, 根据需要再通过注入环境变量的方式设置时区。
Dockerfile 以 nginx:debian 为例
1 2 3 4 5 6 7 8 9 10 11 | FROM nginx:1.23 # 安装 tzdata RUN apk update \ && DEBIAN_FRONTEND=noninteractive apt install -y tzdata \ && rm -rf /var/lib/apt/lists/* # 设置默认时区 ENV TZ=Asia/Shanghai # ...省略 |
假设通过上述 Dockerfile 构建的镜像名为 nginx:1.23-tz-shanghai
。通过 注入变量 修改时区。
直接使用, 我们将得到 CST 时区。
以下就不通过上述 Dockerfile 构建镜像了。时区反着来。
默认 nginx:1.23
使用的是 Etc/UTC
时间。
1 2 | $ docker run --rm nginx:1.23 date Wed Dec 21 14:23:03 UTC 2022 |
在启动的时候, 注入上海时区的环境变量
1 2 | $ docker run --rm -e "TZ=Asia/Shanghai" nginx:1.23 date Wed Dec 21 22:23:30 CST 2022 |
docker-compose
或 Kubernetes
通过各自的方式注入环境变量即可。
全球所有可用时区, 参考地址 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List