Cách đặt thời gian hệ thống linh hoạt trong bộ chứa Docker


28

Có cách nào để thiết lập thời gian hệ thống bộ chứa Docker một cách linh hoạt (trong thời gian chạy) mà không ảnh hưởng đến máy chủ không?

Sử dụng

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

đưa ra lỗi sau:

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.

Sử dụng

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

đưa ra lỗi sau:

date: cannot set date: Operation not permitted

Trường hợp sử dụng:

Tôi cần kiểm tra phần mềm nhạy cảm với thời gian (hành vi phụ thuộc vào ngày).

Các trường hợp sử dụng phổ biến khác:

  • chạy phần mềm kế thừa với lỗi y2k
  • phần mềm kiểm tra tuân thủ năm 2038
  • gỡ lỗi các vấn đề liên quan đến thời gian, chẳng hạn như chứng chỉ SSL đã hết hạn
  • phần mềm đang chạy không chạy bên ngoài một khung thời gian nhất định
  • quy trình xây dựng xác định.

Mục đích của việc làm này là gì? trường hợp sử dụng của bạn là gì?
dawud

Xin vui lòng xem chỉnh sửa.
Vingtoft


1
Trên thực tế, tôi vừa tìm và tích cực thử nghiệm một giải pháp bằng cách sử dụng libfaketime github.com/wolfcw/libfaketime tôi sẽ cập nhật với một câu trả lời + ví dụ hoạt động.
Vingtoft

Câu trả lời:


21

Điều đó là có thể

Giải pháp là giả nó trong container. Lib này chặn tất cả các chương trình gọi hệ thống sử dụng để lấy ngày giờ hiện tại.

Việc thực hiện rất dễ dàng. Thêm chức năng vào Dockerfile của bạn nếu thích hợp:

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

Hãy nhớ đặt các biến môi trường LD_PRELOADtrước khi bạn chạy ứng dụng mà bạn muốn áp dụng thời gian giả.

Thí dụ:

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]

Bây giờ bạn có thể thay đổi động thời gian của máy chủ:

Thí dụ:

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
Đối với những người khác đến với giải pháp này, hãy lưu ý rằng điều này sẽ không hoạt động đối với các ứng dụng golang hoặc các exes liên kết tĩnh khác.
Sentinel

5
Cảm ơn @Sentinel. Thật thú vị, tôi vừa tìm thấy câu trả lời này qua google, tôi đặc biệt muốn sử dụng nó với một ứng dụng golang và tôi nhận thấy rằng bạn đã để lại nhận xét này cho câu hỏi 1,5 năm trước chỉ 2 giờ trước. Cảm thấy như nó là dành cho tôi. Cảm ơn! :)
dimonomid

Tại sao không làm việc trong tình huống của bạn? Golang không sử dụng các cuộc gọi hệ thống để lấy thời gian? @dimonomid Tôi khuyên bạn nên dùng thử, thật nhanh chóng để thực hiện giải pháp.
Vingtoft

1
@Vingtoft Hãy cho tôi biết nếu nó thực sự hoạt động, nhưng tìm kiếm xung quanh. Golang không tự động liên kết trong các thư viện.
Sentinel

1
@dimonomid Vâng, tôi đã khá thất vọng. Thất vọng hơn với Docker thực sự. Tôi cần phải thực hiện các bài kiểm tra liên quan đến thời gian. Điều này làm cho Docker khá vô dụng như một "container". Tôi đã nghĩ rằng việc chặn các cuộc gọi thời gian của hệ thống để đồng bộ hóa múi giờ sẽ là mục 1 trong chương trình nghị sự của Docker. Rõ ràng là không.
Sentinel

4

Jenny D đúng ở chỗ mặc định Docker container không cho phép truy cập vào đồng hồ hệ thống.

Tuy nhiên, trên Linux, nếu bạn ổn với bộ chứa của mình có quyền truy cập vào khả năng này, bạn có thể cho phép khả năng này bằng cách sử dụng tùy chọn "--cap-add = SYS_TIME" của lệnh "docker run" khi tạo bộ chứa của bạn:

# 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

Sau đó, bạn có thể thay đổi thời gian từ bên trong container đang chạy:

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

Tài liệu tham khảo: https://docs.docker.com/engine/reference/run/#r nb-privilege-and-linux-capabilities


2
Điều này thay đổi thời gian trên máy chủ. Thời gian trên một hệ thống Linux hiện không được đặt tên, chỉ có một giá trị cho máy chủ lưu trữ và tất cả các thùng chứa.
BMitch

Vâng bạn đã đúng. Điều này thay đổi thời gian của đồng hồ máy chủ. Chỉ cần đọc lại câu hỏi và nhận ra câu hỏi, thực sự, đã đề cập rõ ràng về việc KHÔNG thay đổi đồng hồ của máy chủ. Tôi đứng chính xác :)
Oleg Kazakov

0

Bắt đầu container với một biến môi trường bổ sung:

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

Tôi đang tìm cách để thiết lập thời gian một cách linh hoạt, có nghĩa là nó có thể được đặt trong thời gian chạy. Tôi đã cập nhật câu hỏi của tôi.
Vingtoft

0

giải pháp soạn thảo docker:

Thêm /etc/localtime:/etc/localtime:rovào volumesthuộc tính.

Nhìn vào liên kết này cho một ví dụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.