Docker中的时区问题处理
背景
这两天在打docker的时候,发现自己的容器启动之后,里面date -R的输出时区是UTC,总是和北京时间差了8个小时.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/bF/jG/W1/1WjFGbm8HLFtAH_u0xOtdhfC92EQfavM58MQx7QeQ5YlJm0JKzc_41h60OGF8FZu5XWaVxmjvVjJbLlYHmqtBDR8yKtH_sBJavXhwFduB3o.jpeg)
标准镜像
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/bF/jG/W1/1WjFGbm8HLFtAH_u0xOtdhfC92EQfavM58MQx7QeQ5ZWuzOCeCu2-vC0SkGqZje_1up6vYcSL-Q3q3Mw7ZLJkPcLd_4q7womo6wNIl0ycy8.jpeg)
时区是UTC
查看/etc/localtime,发现默认指向的是Etc/UTC时区.而且TZ环境变量也没有被设置.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/S6/Vw/SY/YSV6wSY-OkQYFU1zfJYNlhfC92EQfavM58MQx7QeQ5b_844i0ArZKV3dvGiRT9HWGkV5bJ8a03FczeOq-TU0BANJWSStAazPprqyixfc4HI.jpeg)
linux中的时区问题到底是怎么处理的
实际上,我们所有关于时区处理的问题都是glibc中处理时区的问题. 这个问题最权威的文档就是glibc的官方文档,里面关于TZ环境变量的描述介绍了时区问题的处理.
https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html#TZ-Variable
其中和我们相关的部分如下.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/S6/Vw/SY/YSV6wSY-OkQYFU1zfJYNlhfC92EQfavM58MQx7QeQ5YD9OTOyX-W9rQpxBCfbxiTCqtnLouMcZExAMQd4a3yzOP2-iXenDIwq3kjuvNIgNo.jpeg)
核心意思如下: 在glibc中,TZ环境变量的值是一个文件的名字,这个文件的内容描述了时区相关的信息.
如果TZ这个环境变量没有设置,那么系统会选择一个默认值,在glibc中,其默认值为/etc/localtime. 如果TZ环境变量有值,并且这个值是以/开头的,那么是一个绝对路径的文件名,否则文件名为/usr/share/zoneinfo/$TZ. /usr/share/zoneinfo目录下面有世界各地的本地时间信息,比如Asia/Shanghai.一般这个目录下面的文件是被tzdata这个包安装的.
按照这个思路,我们强制指定TZ环境变量为Asia/Shanghai,时区正确
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/bF/jG/W1/1WjFGbm8HLFtAH_u0xOtdhfC92EQfavM58MQx7QeQ5bWc-1vVhwVsvpZTgk0OMd9f_Z3AdGR5IP8p-h1_mkQgWgNhZf6_bQFbhBNsW4kLIA.jpeg)
强制修改/etc/localtime文件,时区也正确.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/S6/Vw/SY/YSV6wSY-OkQYFU1zfJYNlhfC92EQfavM58MQx7QeQ5ZCpCywMZ_tSk5MTE2MPvS17mz9S1bSDJzReQiZBbqHmepCsPT81EprhLFAmBI7Ru4.jpeg)
docker容器处理时区的方法
根据上面的描述,在docker容器中设置时区其实有两个主要的方法. 一个是直接进行TZ环境变量设置,另一个是不设置TZ环境变量,直接修改/etc/localtime的内容(通过软链接或者文件直接复制都可以)
这里以设置TZ环境变量为例(我自己比较喜欢这样做,感觉比修改/etc/localtime更方便).
首先,我们可以在Dockerfile里面添加ENV TZ=Asia/Shanghai,这样docker build出来的镜像默认TZ环境变量就是我们要的值了.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/S6/Vw/SY/YSV6wSY-OkQYFU1zfJYNlhfC92EQfavM58MQx7QeQ5abBojii02z3GeYR0qCFvB-lJNpFuja6oxrH7IY7rSJAY8-w93UrksapkeLNnSvj0k.jpeg)
其次,我们也可以在容器拉起的时候使用-e TZ=Asia/Shanghai进行TZ环境变量设置,这个设置就是动态的,同一个镜像我们可以在拉起的时候设置不同的值.
![Docker中的时区问题处理 Docker中的时区问题处理](https://cdn.ancii.com/article/image/v1/l7/qi/bN/Nbq7ilYF1suGxDU6bIGQUxfC92EQfavM58MQx7QeQ5b9Mh6lP4TOpXJp8C-JtSA0Wr402TJHSEA6WI8bUpFbN7Lca3uliGehxQ-OTF_ukf0.jpeg)