确定 OS 图像的分布 docker
determine OS distribution of a docker image
我需要确定任何 docker 图像的 OS 分发名称。我可以把ubuntu:latest标记为image1:latest,但是应该可以得到[=的分布信息36=] 启动时。
为了实现这一点,我使用下面提到的命令来确定 OS 版本:
$ docker tag ubuntu image1
$
$ docker run -it image1 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
但是,这取决于图像中是否包含 python2 或 python3。 ubuntu:12.04 失败,我需要在那里使用 python2。
$ docker run -it ubuntu /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
/bin/sh: 1: python3: not found
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python2 test.py"
('Ubuntu', '12.04', 'precise')
$
Q1。有没有一种方法可以在不知道特定图像中 python 的哪个版本的情况下实现相同的效果?
注意:目标是确定哪个是用于构建此映像的基础映像。我无权访问用于构建此映像的 Dockerfile。
Q2。还有另一种使用入口点的方法。我可以使用 Dockerfile 从当前图像构建一个单独的图像。或者,我可以在创建容器时在 cmdline 中指定入口点,但我需要脚本可以在容器内访问。我猜我在使用 cmdline 时可能需要共享存储,有没有更好的方法来实现这一点?任何指点都会很有帮助。
谢谢。
您可以将 /etc/issue 文件用于 Debian/Ubuntu:
root@ubuntu_container:/# cat /etc/issue
Ubuntu 14.04.3 LTS \n \l
或 /etc/redhat-release 对于 CentOS/Red Hat/Fedora:
[root@fedora_container /]# cat /etc/redhat-release
Fedora release 23 (Twenty Three)
[root@centos_container /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
文件系统层次结构标准有一个 standard definition for /etc/os-release
,它应该在大多数发行版上可用:
The /etc/os-release and /usr/lib/os-release files contain operating system identification data.
The basic file format of os-release is a newline-separated list of environment-like shell-compatible variable assignments. It is possible to source the configuration from shell scripts.
这意味着您可以只获取 /etc/os-release
并使用 $NAME
或 $ID
来识别分布。例如,在 Fedora 上它看起来像这样:
% source /etc/os-release
% echo $NAME
Fedora
% echo $ID
fedora
在 Debian 上:
% source /etc/os-release
% echo $NAME
Debian GNU/Linux
% echo $ID
debian
您应该使用以下命令来检测 Ubuntu 版本名称:
export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1)
对于 Ubuntu docker 图像,当我需要将多元宇宙添加到 apt.source.lists 并且没有重复行时,我正在使用以下命令:
RUN export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1) &&\
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "removing duplicated strings from /etc/apt/sources.list" && \
awk '!x[[=11=]]++' /etc/apt/sources.list > /tmp/sources.list && \
cat /tmp/sources.list > /etc/apt/sources.list && \
您应该使用以下命令来检测 Debian 版本名称(I am using 它用于我的 docker 图像):
export DEBIAN_RELEASE=$(awk -F'[" ]' '/VERSION=/{print }' /etc/os-release | tr -cd '[[:alnum:]]._-' ) && \
[[ "x${DEBIAN_RELEASE}" = "x" ]] && export DEBIAN_RELEASE="unstable"
在 上展开,一些 sh
没有 source
定义。在这种情况下我们可以使用
grep NAME /etc/*-release
能够看到 OS 是什么。通常PRETTY_NAME
可以说出全名:
PRETTY_NAME="Ubuntu 20.04 LTS"
大部分答案给我们OS释放,但问题也很关注docker。
我很懒,尤其是当我有超过20张图片的时候,所以:
docker image ls | perl -lane 'print "docker run --rm $F[0]:$F[1] cat /etc/os-release" unless /REPOSITORY/' | sh | grep PRETTY
大多数图片都有结果:
> PRETTY_NAME="Ubuntu 16.04.1 LTS"
> PRETTY_NAME="Ubuntu 14.04.3 LTS"
> PRETTY_NAME="Ubuntu 18.04.1 LTS"
> PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
> PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
> PRETTY_NAME="Debian GNU/Linux bullseye/sid"
> PRETTY_NAME="Ubuntu 18.04.3 LTS"
> PRETTY_NAME="Ubuntu 16.04.1 LTS"
> ...
我需要确定任何 docker 图像的 OS 分发名称。我可以把ubuntu:latest标记为image1:latest,但是应该可以得到[=的分布信息36=] 启动时。
为了实现这一点,我使用下面提到的命令来确定 OS 版本:
$ docker tag ubuntu image1
$
$ docker run -it image1 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
但是,这取决于图像中是否包含 python2 或 python3。 ubuntu:12.04 失败,我需要在那里使用 python2。
$ docker run -it ubuntu /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
/bin/sh: 1: python3: not found
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python2 test.py"
('Ubuntu', '12.04', 'precise')
$
Q1。有没有一种方法可以在不知道特定图像中 python 的哪个版本的情况下实现相同的效果?
注意:目标是确定哪个是用于构建此映像的基础映像。我无权访问用于构建此映像的 Dockerfile。
Q2。还有另一种使用入口点的方法。我可以使用 Dockerfile 从当前图像构建一个单独的图像。或者,我可以在创建容器时在 cmdline 中指定入口点,但我需要脚本可以在容器内访问。我猜我在使用 cmdline 时可能需要共享存储,有没有更好的方法来实现这一点?任何指点都会很有帮助。
谢谢。
您可以将 /etc/issue 文件用于 Debian/Ubuntu:
root@ubuntu_container:/# cat /etc/issue
Ubuntu 14.04.3 LTS \n \l
或 /etc/redhat-release 对于 CentOS/Red Hat/Fedora:
[root@fedora_container /]# cat /etc/redhat-release
Fedora release 23 (Twenty Three)
[root@centos_container /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
文件系统层次结构标准有一个 standard definition for /etc/os-release
,它应该在大多数发行版上可用:
The /etc/os-release and /usr/lib/os-release files contain operating system identification data.
The basic file format of os-release is a newline-separated list of environment-like shell-compatible variable assignments. It is possible to source the configuration from shell scripts.
这意味着您可以只获取 /etc/os-release
并使用 $NAME
或 $ID
来识别分布。例如,在 Fedora 上它看起来像这样:
% source /etc/os-release
% echo $NAME
Fedora
% echo $ID
fedora
在 Debian 上:
% source /etc/os-release
% echo $NAME
Debian GNU/Linux
% echo $ID
debian
您应该使用以下命令来检测 Ubuntu 版本名称:
export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1)
对于 Ubuntu docker 图像,当我需要将多元宇宙添加到 apt.source.lists 并且没有重复行时,我正在使用以下命令:
RUN export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1) &&\
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "removing duplicated strings from /etc/apt/sources.list" && \
awk '!x[[=11=]]++' /etc/apt/sources.list > /tmp/sources.list && \
cat /tmp/sources.list > /etc/apt/sources.list && \
您应该使用以下命令来检测 Debian 版本名称(I am using 它用于我的 docker 图像):
export DEBIAN_RELEASE=$(awk -F'[" ]' '/VERSION=/{print }' /etc/os-release | tr -cd '[[:alnum:]]._-' ) && \
[[ "x${DEBIAN_RELEASE}" = "x" ]] && export DEBIAN_RELEASE="unstable"
在 sh
没有 source
定义。在这种情况下我们可以使用
grep NAME /etc/*-release
能够看到 OS 是什么。通常PRETTY_NAME
可以说出全名:
PRETTY_NAME="Ubuntu 20.04 LTS"
大部分答案给我们OS释放,但问题也很关注docker。
我很懒,尤其是当我有超过20张图片的时候,所以:
docker image ls | perl -lane 'print "docker run --rm $F[0]:$F[1] cat /etc/os-release" unless /REPOSITORY/' | sh | grep PRETTY
大多数图片都有结果:
> PRETTY_NAME="Ubuntu 16.04.1 LTS"
> PRETTY_NAME="Ubuntu 14.04.3 LTS"
> PRETTY_NAME="Ubuntu 18.04.1 LTS"
> PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
> PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
> PRETTY_NAME="Debian GNU/Linux bullseye/sid"
> PRETTY_NAME="Ubuntu 18.04.3 LTS"
> PRETTY_NAME="Ubuntu 16.04.1 LTS"
> ...