Docker 컨테이너에서 시스템 시간을 동적으로 설정하는 방법


28

호스트 시스템에 영향을 미치지 않고 Docker 컨테이너 시스템 시간을 런타임에 동적으로 설정하는 방법이 있습니까?

사용

hwclock --set --date "Sat Aug 17 08:31:24 PDT 2016"

다음과 같은 오류가 발생합니다.

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --debug option to see the details of our search for an access method.

사용

date -s "2 OCT 2006 18:00:00"

다음과 같은 오류가 발생합니다.

date: cannot set date: Operation not permitted

사용 사례 :

시간에 민감한 소프트웨어를 테스트해야합니다 (행동은 날짜에 따라 다름).

다른 일반적인 사용 사례 :

  • y2k 버그로 레거시 소프트웨어 실행
  • 2038 년 준수를위한 테스트 소프트웨어
  • 만료 된 SSL 인증서와 같은 시간 관련 문제 디버깅
  • 특정 시간대 밖에서 실행이 중단되는 소프트웨어 실행
  • 결정 론적 빌드 프로세스.

그렇게하는 목적은 무엇입니까? 사용 사례는 무엇입니까?
dawud

편집을 참조하십시오.
Vingtoft


1
실제로, 나는 방금 libfaketime github.com/wolfcw/libfaketime을 사용하여 솔루션을 발견하고 긍정적으로 테스트했습니다. 나는 곧 대답 + 작동 예제로 업데이트 할 것입니다.
Vingtoft

답변:


21

것이 가능하다

해결책은 컨테이너에서 가짜로 만드는 것입니다. 이 lib 는 현재 시간과 날짜를 검색하기 위해 사용하는 모든 시스템 호출 프로그램을 차단합니다.

구현이 쉽습니다. Dockerfile에 적절한 기능을 추가하십시오.

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

LD_PRELOAD가짜 시간을 적용하려는 응용 프로그램을 실행하기 전에 환경 변수를 설정해야합니다 .

예:

CMD ["/bin/sh", "-c", "LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 python /srv/intercept/manage.py runserver 0.0.0.0:3000]

이제 서버 시간을 동적으로 변경할 수 있습니다.

예:

import os
def set_time(request):
    print(datetime.today())
    os.environ["FAKETIME"] = "2020-01-01"  # Note: time of type string must be in the format "YYYY-MM-DD hh:mm:ss" or "+15d"
    print(datetime.today())

6
이 솔루션을 사용하는 다른 사용자의 경우 golang 응용 프로그램 또는 다른 정적으로 링크 된 exe에서는 작동하지 않습니다.
Sentinel

5
감사합니다 @Sentinel. 재미있게도, 나는 방금 Google을 통해이 답변을 찾았습니다. 특히 golang 앱과 함께 사용하고 싶습니다 .2 시간 전에 1.5 세의 질문 에이 의견을 남겼습니다. 그것은 나를위한 것 같습니다. 감사! :)
dimonomid

왜 당신의 상황에서 작동하지 않습니까? Golang은 시스템 호출을 사용하여 시간을 검색하지 않습니까? @dimonomid 나는 당신에게 시도해 볼 것을 제안한다. 솔루션을 구현하는 것이 빠르다.
Vingtoft

1
@Vingtoft 실제로 작동하는지 알려 주지만 주변을 검색하십시오. Golang은 라이브러리에서 동적으로 연결되지 않습니다.
Sentinel

1
@dimonomid 그래, 나는 꽤 실망했다. 실제로 Docker에 더 실망했습니다. 타이밍 관련 테스트를 구현해야합니다. 이것은 Docker를 "컨테이너"로 거의 쓸모 없게 만듭니다. 시간대 동기화에 대한 시스템 시간 호출 차단은 Docker 의제에서 항목 1이 될 것이라고 생각했을 것입니다. 분명히 아닙니다.
Sentinel

4

Jenny D는 기본적으로 Docker 컨테이너가 시스템 시계에 대한 액세스를 허용하지 않는다는 점에서 정확합니다.

그러나 Linux에서 컨테이너가이 기능에 액세스 할 수 있으면 컨테이너를 작성할 때 "docker run"명령의 "--cap-add = SYS_TIME"옵션을 사용하여이 기능을 허용 할 수 있습니다.

# docker run --cap-add=SYS_TIME -d --name teamcity-server-instance -v /opt/teamcity/data:/data/teamcity_server/datadir -v /opt/teamcity/logs:/opt/teamcity/logs -p 80:8111 jetbrains/teamcity-server

그런 다음, 실행중인 컨테이너 내부에서 시간을 변경할 수 있습니다.

# docker exec -it teamcity-server-instance /bin/bash
# date +%T -s "15:03:00"
15:03:00
#

참조 설명서 : https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities


2
호스트 시스템의 시간이 변경됩니다. Linux 시스템에서의 시간은 현재 네임 스페이스가 아니며 호스트 및 모든 컨테이너에 대해 하나의 값만 있습니다.
BMitch

네 말이 맞아. 호스트 시스템 시계의 시간이 변경됩니다. 질문을 다시 읽고 실제로 호스트 시스템의 시계를 변경하지 않는 것에 대해 언급 한 질문을 깨달았습니다. 나는 정정했다 :)
Oleg Kazakov

0

추가 환경 변수로 컨테이너를 시작하십시오.

docker run -e "SET_CONTAINER_TIMEZONE=true" \
           -e "CONTAINER_TIMEZONE=US/Arizona" [docker image name]

시간을 동적으로 설정하는 방법을 찾고 있습니다. 즉, 런타임에 설정할 수 있습니다. 내 질문을 업데이트했습니다.
Vingtoft

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.