Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About time incorrect of docker image about aspnet-6 #62545

Closed
tonyjianhu opened this issue Nov 26, 2021 · 30 comments
Closed

About time incorrect of docker image about aspnet-6 #62545

tonyjianhu opened this issue Nov 26, 2021 · 30 comments

Comments

@tonyjianhu
Copy link

Hello:
I ran asp.net core application in docker container , used version of .Net 6 for mcr.microsoft.com/dotnet/aspnet:6.0-focal mirror versions. In my program, executed:
[Console.WriteLine (Datetime.Now.ToString("yyyy-MM-dd HH:mm:ss"))] ,the command output was [2021-11-26 12:58:12]. And then I entered the container and executed [date] command.The output was [Fri Nov 26 20:59:12 CST 2021].
That was almost an eight-hour difference. In.NET 5, there is no such problem.

@mthalman
Copy link
Member

I'm unable to repro this. Here are the steps I took to attempt to repro this:

  1. git clone https://github.com/mthalman/bug-repros.git -b dotnet-docker-3307
  2. cd bug-repros/project
  3. docker build --pull -t test .
  4. docker run --rm test
    Output: 2021-11-29 14:39:15
  5. docker run --rm --entrypoint date test
    Output: Mon Nov 29 14:39:54 UTC 2021

Are you sure you don't have any other configuration in your Dockerfile that may be leading to this behavior? Please provide repro steps.

@tonyjianhu
Copy link
Author

tonyjianhu commented Nov 29, 2021

mcr.microsoft.com/dotnet/aspnet:6.0-focal

when I run the container,I map the local time into it --use -v - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime

@mthalman
Copy link
Member

Thanks, I can repro this now by including -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime with the docker run command.

@mattjohnsonpint - Is this a known change in behavior for .NET 6 to not use the /etc/localtime file? In .NET 6, setting /etc/localtime to /usr/share/zoneinfo/Asia/Shanghai causes the following time zone difference:

  • .NET 5: System.TimeZoneInfo.Local == (UTC+08:00) Coordinated Universal Time
  • .NET 6: System.TimeZoneInfo.Local == (UTC) Coordinated Universal Time

Is this behavior difference documented anywhere?

@mthalman
Copy link
Member

mthalman commented Dec 8, 2021

Triage: Moving this to dotnet/runtime repo to be investigated.

@mthalman mthalman transferred this issue from dotnet/dotnet-docker Dec 8, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Dec 8, 2021
@mattjohnsonpint
Copy link
Contributor

Is tzdata package installed in the container image?

@ghost
Copy link

ghost commented Dec 8, 2021

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Hello:
I ran asp.net core application in docker container , used version of .Net 6 for mcr.microsoft.com/dotnet/aspnet:6.0-focal mirror versions. In my program, executed:
[Console.WriteLine (Datetime.Now.ToString("yyyy-MM-dd HH:mm:ss"))] ,the command output was [2021-11-26 12:58:12]. And then I entered the container and executed [date] command.The output was [Fri Nov 26 20:59:12 CST 2021].
That was almost an eight-hour difference. In.NET 5, there is no such problem.

Author: tonyjianhu
Assignees: -
Labels:

area-System.Globalization, untriaged

Milestone: -

@mthalman
Copy link
Member

mthalman commented Dec 8, 2021

Is tzdata package installed in the container image?

No, not by default. It doesn't exist in the 5.0 image either but it returns the expected result in that version.

@mattjohnsonpint
Copy link
Contributor

Not sure about that from memory, but tzdata would need to be installed to recognize what Asia/Shanghai means.

Also note the old display name was wrong.

@mattjohnsonpint
Copy link
Contributor

See also related dotnet/dotnet-docker#1366

@mthalman
Copy link
Member

mthalman commented Dec 8, 2021

Sorry about that, I was mistaken. Yes, tzdata is installed for both 5.0 and 6.0 on Debian/Ubuntu.

@tarekgh tarekgh added area-System.Runtime and removed area-System.Globalization untriaged New issue has not been triaged by the area owner labels Dec 9, 2021
@ghost
Copy link

ghost commented Dec 9, 2021

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Issue Details

Hello:
I ran asp.net core application in docker container , used version of .Net 6 for mcr.microsoft.com/dotnet/aspnet:6.0-focal mirror versions. In my program, executed:
[Console.WriteLine (Datetime.Now.ToString("yyyy-MM-dd HH:mm:ss"))] ,the command output was [2021-11-26 12:58:12]. And then I entered the container and executed [date] command.The output was [Fri Nov 26 20:59:12 CST 2021].
That was almost an eight-hour difference. In.NET 5, there is no such problem.

Author: tonyjianhu
Assignees: -
Labels:

area-System.Runtime

Milestone: -

@tarekgh tarekgh added this to the 6.0.x milestone Dec 9, 2021
@tarekgh
Copy link
Member

tarekgh commented Dec 9, 2021

@mthalman @tonyjianhu could you please check if the environment variable TZ somehow is defined on this docker container?

Also, were you running .NET 5.0 and .NET 6.0 on the same container?

@mthalman
Copy link
Member

mthalman commented Dec 9, 2021

could you please check if the environment variable TZ somehow is defined on this docker container?

Nope, there is no TZ variable. This command returns nothing: docker run --rm mcr.microsoft.com/dotnet/aspnet:6.0-focal echo $TZ

Also, were you running .NET 5.0 and .NET 6.0 on the same container?

No, this behavior occurs with the mcr.microsoft.com/dotnet/aspnet:6.0-focal container image which only has .NET 6.0 installed.

@tarekgh
Copy link
Member

tarekgh commented Dec 9, 2021

No, this behavior occurs with the mcr.microsoft.com/dotnet/aspnet:6.0-focal container image which only has .NET 6.0 installed.

Thanks for the info. Is there a chance to install and try .NET 5.0 on this container? I don't think we changed anything between .NET 5.0 and .NET 6.0 on the way getting the local time zone. So, my guess here is somehow it is container image configuration. Sorry, I am currently on vacation, and I don't have a handy environment to quickly try it myself. Thanks!

@mthalman
Copy link
Member

mthalman commented Dec 9, 2021

The only difference is the addition of an environment variable, Logging__Console__FormatterName=Json, to the aspnet 6.0 Dockerfile. I can't imagine that has any impact on this scenario. Everything else is the same except for the .NET versions of course.

@tarekgh
Copy link
Member

tarekgh commented Dec 9, 2021

The only difference is the addition of an environment variable, Logging__Console__FormatterName=Json, to the aspnet 6.0 Dockerfile. I can't imagine that has any impact on this scenario.

Agree, I don't think logging will affect the time zones at all.

Everything else is the same except for the .NET versions of course.

Could be. But looking at the code, I am seeing we are doing the same thing in both .NET 5.0 and .NET 6.0. We had some code refactoring in .NET 6.0, but I don't expect it will break reading local time zone file.

Note, the code depends on the symbolic link of the localtime file. You may look at the code in .NET 6.0 and .NET 5.0. So, if the symbolic link somehow not working in the same way between the two container images that can affect the result.

Anyway, all what I mentioned here are guesses. Still there is a chance .NET has a regression which I am not seeing from reading the code. I'll try to take a look later when I get a chance.

@tarekgh
Copy link
Member

tarekgh commented Dec 10, 2021

I have looked briefly at the issue, and here is what I am seeing:

  • I confirm there is a behavior difference between .NET 5.0 and .NET 6.0. I was running both .NET 5.0 and .NET 6.0 on exact same container. So, there is no problem with the container itself.
  • I don't know exactly what is causing this behavior change yet but the docker container will have very strange configuration when starting it with the option -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime. Here is why:

running the following command:

 ls -la /etc/localtime
lrwxrwxrwx 1 root root 27 Dec  1 22:42 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC

which means the localtime is linked symbolically to /usr/share/zoneinfo/Etc/UTC. which means the default time should be UTC. But, because you have started the docker container with -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime, when reading the file will get the contents from the host file /usr/share/zoneinfo/Asia/Shanghai and not from the symbolic file /usr/share/zoneinfo/Etc/UTC.

Even doing

cat /etc/timezone
Etc/UTC

Again, the system seeing the local time zone is Utc but the data of the zone is coming from Shanghai.

Although this seems a regression in .NET 6.0, but this configuration looks not good to use as it will create confusion on such systems. You already can see the display name using .NET 5.0 showing the zone name is Utc and the Id is Etc/UTC while the time is reported from Shanghai!

I suggest to you, instead of using -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime, you can do:

set the default time zone using timedatectl

or execute commands like:

unlink /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

I'll keep this issue open to look more at what has changed in .NET 6.0. I'll reduce the priority of this issue as from my analysis it is not right to use such configuration and there is an easy workaround that can be used.

@XieJJ99
Copy link

XieJJ99 commented Jan 13, 2022

This is probably a regression in .net 6.0.1 .
I test in my 6.0.1 container:

root@1a2e2f4396ed:/# echo "Asia/Shanghai" > /etc/timezone
root@1a2e2f4396ed:/# cat /etc/timezone
Asia/Shanghai
root@1a2e2f4396ed:/# rm -rf /etc/localtime
root@1a2e2f4396ed:/# ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
root@1a2e2f4396ed:/# ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 Jan 13 15:06 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
root@1a2e2f4396ed:/# date
Thu Jan 13 15:06:57 CST 2022
root@1a2e2f4396ed:/# pwsh
PowerShell 7.2.1
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS /> [System.DateTime]::Now

Thursday, 13 January 2022 07:07:11

@oruchreis
Copy link

I have same issue. I've tried 6.0, 6.0.1-focal and bullseye but it didn't fixed.
We are using kubernetes, and we mount /etc/localtime as a hostPath to change timezone:

volumeMounts:
            - name: tz-config
              mountPath: /etc/localtime
  - name: tz-config
          hostPath:
            path: /usr/share/zoneinfo/Europe/Istanbul

It was working for .net 3 and .net 5 until upgraded to .net 6 images. So I've tried @tarekgh workaround for .net 6 images, and it seems that worked:

    spec:
      containers: 
          command: #TODO: remove this command when this bug is fixed: https://github.com/dotnet/runtime/issues/62545
            - /bin/sh
            - -c
            - |
              unlink /etc/localtime
              ln -s /usr/share/zoneinfo/Europe/Istanbul /etc/localtime
              dotnet MyApplication.dll

I don't know why overwritten the localtime file in .net 6 image, but the hostPath mount was working before .net 6.

@tarekgh
Copy link
Member

tarekgh commented Jan 14, 2022

It is wrong to hostPath the timezone file. I explained before in my comment #62545 (comment). The file you are mounting was symbolically linked too inside the OS. That causes confusion in general when reporting the time. In .NET 5.0 was reporting the time from one zone and reporting the zone name from a different zone (UTC). so even it looks it was working in .NET 5.0, but the behavior for sure was wrong. The .NET 6.0 is more consistent and following the OS symbolic link which results in the expected result as how the time zone is setup on such container.

Please try to avoid using -v for the zone files and configure the zone in the container instead when launching it as you configure anything else.

@mattjohnsonpint
Copy link
Contributor

I'd like to drop a friendly reminder here that it continues to remain a best practice (IMHO) for servers (and by extension containers) to be set to UTC, and for the applications running on them to be designed such that they are time zone agnostic.

If the application you're running requires the environment's time zone to be set to anything in particular, that's generally a smell that you should revisit what "local time" means in the context of your application. For .NET, some APIs that use the concept of "local time" are: DateTime.Today, DateTime.Now, DateTimeOffset.Now, TimeZoneInfo.Local, DateTimeKind.Local, DateTime.ToLocalTime, DateTimeOffset.ToLocalTime, DateTime.ToUniversalTime and TimeZoneInfo.ConvertTimeToUtc when the input Kind is Local or Unspecified, etc. Avoid those in your application and you won't have to worry about setting the server's time zone (or container's time zone).

As a brief example, instead of calling DateTimeOffset.Now, call TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, someTimeZone). You can control someTimeZone any way you'd like in your application - either application-wide, or under some particular context.

@meirkr
Copy link

meirkr commented Apr 24, 2022

Happens also when mapping to the host's /etc/localtime.

Ubuntu
(GMT+3)

Example:

Starting a simple new console app for both targets 5 and 6:

Program.cs

Console.WriteLine("Now: " + DateTime.Now.ToString());

tmpProj.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>net5.0;net6.0</TargetFrameworks>
    <LangVersion>preview</LangVersion>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

Running dotnet build

Test

.net 5 docker - works fine:

docker run --rm -it -v /etc/localtime:/etc/localtime:ro -v ~/tmp_net_time_docker/tmpProj/bin/Debug/net5.0/:/app mcr.microsoft.com/dotnet/aspnet:5.0-focal bash
root@4828c5d1344a:/# /app/tmpProj
Now: 04/24/2022 12:33:48
root@4828c5d1344a:/# date
Sun Apr 24 12:34:02 IDT 2022

.net 6 docker - BAD! we see the output doesn't include the GMT+3 of the host:

docker run --rm -it -v /etc/localtime:/etc/localtime:ro -v ~/tmp_net_time_docker/tmpProj/bin/Debug/net6.0/:/app mcr.microsoft.com/dotnet/aspnet:6.0 bash
root@f2fed401c0dc:/# /app/tmpProj
Now: 04/24/2022 09:35:17
root@f2fed401c0dc:/# date
Sun Apr 24 12:35:19 IDT 2022

@danmoseley
Copy link
Member

@MichaelSimons fyi

@tarekgh
Copy link
Member

tarekgh commented Apr 24, 2022

@meirkr as mentioned earlier in this issue it is wrong to use -v to map time zone files. Please have a look at my comment #62545 (comment). The right thing to do here is to configure the container by setting time zones there using tools like timedatectl or any other way as you set it on VMs/machines.

.NET 6.0 behavior is right as the containers internally hard linking the time zone file and always report consistent zone info. Also, .NET 5.0 was wrong as indicated before it reports wrong data (like when you request the display name of the time zone).

I am closing this issue, please send any more questions if there is anything unclear here.

@tarekgh tarekgh closed this as completed Apr 24, 2022
@arashkarami
Copy link

We have same problem with net6.0 on the docker engine.

@meirkr
Copy link

meirkr commented May 2, 2022

@meirkr as mentioned earlier in this issue it is wrong to use -v to map time zone files. Please have a look at my comment #62545 (comment). The right thing to do here is to configure the container by setting time zones there using tools like timedatectl or any other way as you set it on VMs/machines.

.NET 6.0 behavior is right as the containers internally hard linking the time zone file and always report consistent zone info. Also, .NET 5.0 was wrong as indicated before it reports wrong data (like when you request the display name of the time zone).

I am closing this issue, please send any more questions if there is anything unclear here.

But I don't need spcific TZ. I need the container to use host's TZ whatever it is, automatically.
What do you suggest to do in such case?

P.S
Pay attention in my previous comment, that "date" command within the container always showed the time using host's TZ. IMO, it expected from any other app running in the container to behave the same. .Net app shall not be an exception.

@Clockwork-Muse
Copy link
Contributor

But I don't need spcific TZ. I need the container to use host's TZ whatever it is, automatically.

docker run --rm -e TZ=$(cat /etc/timezone) mcr.microsoft.com/dotnet/aspnet:6.0-focal date

... but it's extremely unusual to care about host timezone at all on a server/in a container.

@meirkr
Copy link

meirkr commented May 2, 2022

... but it's extremely unusual to care about host timezone at all on a server/in a container.

When running on premise dockerized apps....

I'll try that approach, hopefully to find a docker compose solution... tx.

@Clockwork-Muse
Copy link
Contributor

When running on premise dockerized apps....

The physical location of the server should be irrelevant; requiring configuration of the host's timezone is going to cause problems/confusion if you move the server. For that matter, it can cause you problems if you want to start hosting this application for people (since it would require to use a container per customer/region). Server applications should be written to use timezones and other data from relevant entities referenced during web requests.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 2, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants