Appearance
Docker 时区设置
1. 概述
大部分 Docker 镜像都是基于 Alpine、Ubuntu、Debian、CentOS 等基础镜像制作而成。基本上都采用 UTC 时间,默认时区为零时区。
Bash
docker run --rm -it --name test alpine /bin/sh
/ # date
Fri Nov 29 08:14:49 UTC 2019而我们主要用的是 CST 时间,北京时间,位于东八区。时区代号:Asia/Shanghai。
Bash
docker run --rm -it --name test -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro alpine /bin/sh
/ # date
Fri Nov 29 16:13:55 CST 2019对比一下,我们会发现,时间上相差 8 小时。
经过一系列探索实践,我们总结了一些 Docker 时区调整方案。
2. 解决方案
2.1. 运行 Docker 容器时调整时区
在 Linux 系统中,控制时区和时间的主要是两个地方:
/etc/timezone一个文本文件,通常只包含时区的名称;/etc/localtime是一个二进制文件(实际上通常是指向/usr/share/zoneinfo里具体时区文件的符号链接)。
2.1.1. 通用 Docker 时区修改方案
当宿主机为 Linux 系统时,我们可以直接将宿主机上的 /etc/timezone 和 /etc/localtime 挂载到容器中,这样可以保持容器和宿主机时区和时间一致。
Bash
-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro2.1.2. 通过传递环境变量改变容器时区
- 适用于:基于 Debian、CentOS 基础镜像制作的 Docker 镜像;
- 不适用于:基于 Alpine、Ubuntu 基础镜像制作的 Docker 镜像。
对于基于 Debian、CentOS 基础镜像制作的 Docker 镜像,在运行 Docker 容器时,传递环境变量 -e TZ=Asia/Shanghai 进去,能修改 Docker 容器时区。
Bash
-e TZ=Asia/Shanghai2.2. 制作 Docker 镜像时调整时区
通过编写 Dockerfile, 构建自己的 Docker 镜像,从构建阶段解决时区问题。
2.2.1. Alpine
根据 Alpine Linux - Setting the timezone 提示,我们可以将以下代码添加到 Dockerfile 中:
Dockerfile
ENV TZ=Asia/Shanghai
RUN apk update \
&& apk add tzdata \
&& ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone \
&& apk del tzdata2.2.2. Debian
Debian 基础镜像中已经安装了 tzdata 包,我们可以将以下代码添加到 Dockerfile 中:
Dockerfile
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*2.2.3. Ubuntu
Ubuntu 基础镜像中没有安装 tzdata 包,因此我们需要先安装 tzdata 包。我们可以将以下代码添加到 Dockerfile 中:
Dockerfile
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN apt update \
&& apt install -y tzdata \
&& ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*2.2.4. CentOS
CentOS 基础镜像中已经安装了 tzdata 包,我们可以将以下代码添加到 Dockerfile 中:
Dockerfile
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone原文链接