如何在构建时在 Docker 容器中设置时间
How to set time in Docker container at build time
所以我正在尝试构建一个 Alpine 容器,包括一个需要 bash
和 curl
才能安装的应用程序。
问题是 Alpine 似乎认为年份是 2037(可能是因为主机 Pi 缺少硬件时钟)忽略了正确的主机 OS/system 时间(由 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
如何在构建时安装 curl
和 bash
?
尝试次数
- 已尝试按指定设置时区here:无效
- 尝试在
apk
命令之前强制 apk 使用带有 RUN sed -i 's/https/http/g' /etc/apk/repositories
的 HTTP (TY @jan-garaj):我只得到一个 new/additional 错误: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
我会回答“如何在构建时安装 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
.
所以@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]
,网络搜索让我找到这个 post:https://blog.samcater.com/fix-workaround-rpi4-docker-libseccomp2-docker-20/
使用其中的步骤升级 libseccomp[2]
对 alpine:3.13
和 alpine:3.14
!!
都有效
修复步骤(来自post)
The steps for libseccomp2 are well documented, as this has been a problem on multiple platforms (not just RPI4). You could do a 'oneshot' installation of a newer version, which can be found here https://github.com/itzg/docker-minecraft-server/issues/755#issuecomment-781615497
Personally I feel the better method is to install it from the Buster Backports repo, which is very safe to add. It also means any future updates to libseccomp will be applied to the 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
现在进入下一个构建时错误消息
所以我正在尝试构建一个 Alpine 容器,包括一个需要 bash
和 curl
才能安装的应用程序。
问题是 Alpine 似乎认为年份是 2037(可能是因为主机 Pi 缺少硬件时钟)忽略了正确的主机 OS/system 时间(由 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
如何在构建时安装 curl
和 bash
?
尝试次数
- 已尝试按指定设置时区here:无效
- 尝试在
apk
命令之前强制 apk 使用带有RUN sed -i 's/https/http/g' /etc/apk/repositories
的 HTTP (TY @jan-garaj):我只得到一个 new/additional 错误: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
我会回答“如何在构建时安装 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
.
所以@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]
,网络搜索让我找到这个 post:https://blog.samcater.com/fix-workaround-rpi4-docker-libseccomp2-docker-20/
使用其中的步骤升级 libseccomp[2]
对 alpine:3.13
和 alpine:3.14
!!
修复步骤(来自post)
The steps for libseccomp2 are well documented, as this has been a problem on multiple platforms (not just RPI4). You could do a 'oneshot' installation of a newer version, which can be found here https://github.com/itzg/docker-minecraft-server/issues/755#issuecomment-781615497
Personally I feel the better method is to install it from the Buster Backports repo, which is very safe to add. It also means any future updates to libseccomp will be applied to the 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
现在进入下一个构建时错误消息