解决.net core3.1部署到Linux CentOS docker时区问题 原创

解决.net core3.1部署到Linux CentOS docker时区问题
Posted By : 蓝狐 Updated On : 2020-06-02

最近遇到一个“.net core3.1部署到Linux CentOS docker时区“问题,总是不对,始终晚8个小时,程序取到的是UTC时间而不是我想要的东8北京时间。


一、主要技术及框架
1、.Net Core3.1

2、Docker(镜像:mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine)

3、Linux CentOS

4、ElasticSearch,Kibana

5、NLog

二、问题现象
看日志记录的时间戳,始终晚了8个小时,导致通过NLog根据日期没提案生成一个日志索引就有问题,比如6月1号8点之前的日志数据就会落在了5月31号的索引中。如下图:

 

这个问题虽然通过Kibana选择时间筛选最终可以选择到对应的日志(会自动做一个时区转换),但是始终存在一个问题(8小时的差异),有些日志要到前一天的索引中去查询。这就给我们统计查询带来了不便。

那么我们要怎么修正这个问题呢?

三、分析原因
首先先,我们来看看ES记录的原始信息:

 

@timestamp记录的是es的date类型,被自动转换成了带时区的字符串:2020-05-31T16:00:00.1209997+00:00

后面加就是相对UTC的时区,加00就表示是UTC时间。

最开始我通过构建docker镜像的时候使用下面命令:

docker cp /usr/share/zoneinfo/Asia/Shanghai lanhusoft-docker:/etc/localtime

其中lanhusoft-docker为容器名。

刚开始以为解决了,最后才知道是暂时解决了,把容器的时间改为了CST,通过date命令查看时间是北京时间了。

但是,过了一段时间重新使用jenkin重新构建,又发现不对了。但是在另外一个程序相同代码,相同构建时间又是正常啊的。(不知道为啥?不知道是不是.net core bug?)

进入容器使用date查看时间又是北京时间,而且宿主机器也是北京时间。奇怪的是.NET Core程序取到的当前时间却是UTC时间。

通过TimeZoneInfo.Local.DisplayName查看找到了原因,返回的是UTC时区时间,而且直接打印DateTime.Now到页面也是跟北京时间晚了8个小时。

看来通过上面的的方法不是完美和根本解决办法,因为alpine镜像先默认是UTC时间。

推荐:

需要指定北京时间,需要安装包tzdata。

四、解决方案
alpine安装包命令是apk add,如果每次构建镜像的时候现安装包tzdata,因为网络原因会很慢,导致影响Jenkin构建的速度。所以我自己写了一个镜像。

aspnet-3.1-alpine-lanhu.dockerfile:


FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine
MAINTAINER www.lanhusoft.com <2351310751@qq.com>

#设置alpine时区
ENV TIMEZONE Asia/Shanghai

# Install base packages
RUN apk update && apk add curl bash tree tzdata \
&& cp -r -f /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
&& echo -ne "Alpine Linux 3.4 image. (`uname -rsv`)\n" >> /root/.built
# Define bash as default command
CMD ["/bin/bash"]

以上脚本apk除了安装tzdata,还安装了其他基础常用的工具包,curl,bash,tree。

在docker文件aspnet-3.1-alpine-lanhu.dockerfile所在目录运行下面命令构建docker镜像:

docker build -f aspnet-3.1-alpine-lanhu.dockerfile -t aspnet-3.1-alpine-lanhu:latest .

说明:-f镜像脚本文件,-t镜像名称,冒号后面是tag。

最后,在项目的Dockerfile中引用这个新生成的镜像:


FROM aspnet-3.1-alpine-lanhu AS base

ARG app_env=development

WORKDIR /app
EXPOSE 80
COPY . ./

ENV ASPNETCORE_ENVIRONMENT $app_env

ENTRYPOINT ["dotnet", "XX.Web.dll"]

说明:aspnet-3.1-alpine-lanhu就是之前我们自定义的alpine镜像,其中XX.Web.dll是asp.net core的启动dll。

这样每次构建就会很快,基本上10多秒就搞定。

 


-----------------------------------
©著作权归作者所有:来自51CTO博客作者编程的世界你不懂的原创作品,请联系作者获取转载授权,否则将追究法律责任
解决.net core3.1部署到Linux CentOS docker时区问题
https://blog.51cto.com/u_11990719/4994115

posted @   dreamw  阅读(350)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2022-03-09 [学习笔记] 哈希函数和 SHA-256
2021-03-09 Vue CLI配置原理详解
点击右上角即可分享
微信分享提示