【问题标题】:How to set time in Docker container at build time如何在构建时在 Docker 容器中设置时间
【发布时间】:2021-11-18 01:49:16
【问题描述】:

所以我正在尝试构建一个 Alpine 容器,包括一个需要安装 bashcurl 的应用程序。

问题是 Alpine 似乎认为年份是 2037 年(可能是因为主机 Pi 缺少硬件时钟)忽略了正确的主机操作系统/系统时间(由 NTP 保持最新),因此 apk 调用失败:

fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/armv7/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/armv7/APKINDEX.tar.gz
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.14/main: temporary error (try again later)
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.14/community: temporary error (try again later)
ERROR: unable to select packages:
  bash (no such package):
    required by: world[bash]
  curl (no such package):
    required by: world[curl]

可以使用docker run -it --privileged ...以交互模式启动容器,并且时间会设置正确,因此安装顺利进行。 我发现的参考资料表明 privileged 构建是不可能的(参考?)。

我尝试了很多方法在构建时将时间传递到容器中,但均未成功:

# syntax=docker/dockerfile:1
FROM alpine:3.14
# Pass build-time using `--build-arg time=$(date +%s)` (w/ default value)
ARG time=1632511895
#RUN ["/bin/date", "-s", "@$time"]      # `invalid date @$time`
#RUN ["/bin/date", "-s", "@"$time]      # `/bin/date/` not found
#RUN echo $(date)       # no output
#RUN date -s @$time     # `date: can't set date: Operation not permitted`
#RUN sudo date -s @$time        # /bin/sh: sudo: not found

# cannot build with `--privileged` so clock will be in 2037 and apk will fail
RUN apk add --no-cache curl bash
WORKDIR /tmp

如何在构建时安装curlbash??

尝试

  • 尝试将时区设置为指定here:无效
  • 尝试在 apk 命令 (TY @jan-garaj) 之前强制 apk 使用带有 RUN sed -i 's/https/http/g' /etc/apk/repositories 的 HTTP:我只收到一个新/附加错误:The command '/bin/sh -c apk add --no-cache curl bash' returned a non-zero code: 2

更多信息

# date       
Sat Oct 23 13:17:47 EDT 2021

# docker info
    Client:
     Debug Mode: false
    
    Server:
     Containers: 4
      Running: 0
      Paused: 0
      Stopped: 4
     Images: 19
     Server Version: 19.03.15
     Storage Driver: overlay2
      Backing Filesystem: extfs
      Supports d_type: true
      Native Overlay Diff: true
     Logging Driver: json-file
     Cgroup Driver: cgroupfs
     Plugins:
      Volume: local
      Network: bridge host ipvlan macvlan null overlay
      Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
     Swarm: inactive
     Runtimes: runc
     Default Runtime: runc
     Init Binary: docker-init
     containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b
     runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
     init version: fec3683
     Security Options:
      seccomp
       Profile: default
     Kernel Version: 4.19.66-v7+
     Operating System: Raspbian GNU/Linux 9 (stretch)
     OSType: linux
     Architecture: armv7l
     CPUs: 4
     Total Memory: 858.7MiB
     Name: rpi0.crcondo
     ID: WW63:IXLY:OBPE:AX4O:45H7:OAUH:CELE:ALDG:ZHC3:RTQW:I32M:GSDL
     Docker Root Dir: /var/lib/docker
     Debug Mode: false
     Registry: https://index.docker.io/v1/
     Labels:
     Experimental: false
     Insecure Registries:
      127.0.0.0/8
     Live Restore Enabled: false
    
    WARNING: No swap limit support
    WARNING: No cpu cfs quota support
    WARNING: No cpu cfs period support

【问题讨论】:

  • 那篇文章指的是设置时区——我不是按小时计算,而是按年计算。另外,我使用的是 Alpine,而不是 Ubuntu。它确实链接了here,但这也是特定于时区的。 (反正我试过了:没有效果)
  • Alpine 在从主机系统继承时间的方式上有些奇怪。过去,我通过在运行容器时设置 SYS_TIME 功能来解决这个问题。虽然这个功能只需要在 docker 容器中设置主机的时间,它似乎确实会强制将时钟同步到容器。诚然,我无法重现您的问题,所以我不确定这是否能解决您的问题,但它很容易测试。
  • 我发现提到使用--cap-adddocker run;除了这是一个构建问题,我找不到任何文档指定如何利用 --cap-adddocker build
  • 果然。我挖出了一个旧的 rasp pi 并重新格式化,我现在可以重现你的问题,所以至少你的环境并不奇怪。不过,无论是使用 vanilla docker build 还是 kaniko(在允许使用或 --privileged 设置时间的容器内构建一个容器),我都无法找到解决方法,我在这两种情况下都遇到了问题。跨度>
  • 当然它是在 Pi 中设置的(否则 HTTPS 和许多其他东西会中断);问题是 docker build 没有将正确的时间传递给构建映像

标签: docker date dockerfile alpine


【解决方案1】:

我会回答“如何在构建时安装 curl 和 bash”而不是“如何在构建时在 Docker 容器中设置时间”:

我猜 apk 失败是因为 repo TLS 证书 dl-cdn.alpinelinux.org 在 2037 年之后无效 = 可以创建有效的 TLS 连接。您只需要安装包,因此在这种情况下您可能会牺牲 TLS 安全性,并且可以使用与存储库的纯 HTTP 连接作为解决方法。例如

RUN \
  sed -i 's/https/http/g' /etc/apk/repositories && \
  apk add --no-cache curl bash

很遗憾,apk doesn't have any flag to ignore TLS verification,所以目前只能使用这种解决方法。

顺便说一句:我会尝试在主机 Pi 上使用良好的旧 NTP。容器使用主机时间,因此主机级别的正确时间配置(通过 NTP 同步)也应该解决容器级别的问题(以及 TLS 证书验证的问题)。


更新:

https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.14.0:

所以你需要升级你的 Docker 版本(20.10.0+),你只有19.03.15

【讨论】:

  • 感谢您参与其中!不幸的是,与上述完全相同的错误仍然存​​在;唯一的区别是一个新错误:The command '/bin/sh -c sed -i 's/https/http/g' /etc/apk/repositories && apk add --no-cache curl bash' returned a non-zero code: 2
  • @AdamSmooch 这只是一个例子,因为我没有你的设置。看起来你有非常奇怪的 docker 设置。请提供docker info 输出。在容器中手动运行命令而不是在构建中 - 不清楚哪个命令失败。
  • 错误来自apk命令(在sed之后):The command '/bin/sh -c apk add --no-cache curl bash' returned a non-zero code: 2。如前所述 - 在容器中运行 apk 命令(使用 --privileged)工作正常,因为时间设置正确。 docker info 已添加到问题中。
  • @AdamSmooch 查看更新和 Alpine 发行说明
  • 尝试了alpine:3.13,因为它需要 Docker 19.03.09+,但同样的错误...我将尝试 docker upgrade 接下来...
【解决方案2】:

所以@JanGaraj 的回答给了我一个重要的线索:Alpine 3.14's release notes 提到它需要Docker >=20.10.0(我目前在19.03.15)。

回到Alpine 3.13's release notes:

  • Docker 版本要求是19.03.9 [我有]
  • 还有 libseccomp 2.4.2

仅仅使用FROM alpine:3.13还是不行。

检查第二个要求,我有一个以前版本的 libseccomp[2] 并且网络搜索将我带到了这个帖子:https://blog.samcater.com/fix-workaround-rpi4-docker-libseccomp2-docker-20/

使用其中的步骤升级libseccomp[2]两个 alpine:3.13alpine:3.14 都有效!!

修复步骤(来自帖子)

libseccomp2 的步骤有据可查,因为这在多个平台(不仅仅是 RPI4)上一直存在问题。您可以“一次性”安装较新版本,可在此处找到 https://github.com/itzg/docker-minecraft-server/issues/755#issuecomment-781615497

我个人觉得更好的方法是从 Buster Backports repo 安装它,添加起来非常安全。这也意味着将来对 libseccomp 的任何更新都将应用于 Pi。

# Get signing keys to verify the new packages, otherwise they will not install
rpi ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138

# Add the Buster backport repository to apt sources.list
rpi ~$ echo 'deb http://httpredir.debian.org/debian buster-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list.d/debian-backports.list

rpi ~$ sudo apt update
rpi ~$ sudo apt install libseccomp2 -t buster-backports

现在转到下一个构建时错误消息?

【讨论】:

    猜你喜欢
    • 2014-12-20
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2014-12-28
    • 2021-05-16
    • 2021-04-07
    相关资源
    最近更新 更多