简体   繁体   English

如何找出docker镜像中安装了哪个Linux?

[英]How to find out which Linux is installed inside docker image?

I am new to docker and this is just a fascinating tool.我是 docker 新手,这只是一个迷人的工具。 However, I can't understand one thing about it.但是,我无法理解其中的一件事。 Simple Dockerfile usually begins with OS name and version, like:简单的 Dockerfile 通常以操作系统名称和版本开头,例如:

FROM ubuntu:xenial
....

But which Linux OS will be used for Dockerfile like但是哪个 Linux 操作系统将用于 Dockerfile,例如

FROM perl
....

or或者

FROM python:3.6
....

Of course I can find this out by running a container from this image and printing out the OS info, like:当然,我可以通过从该图像运行容器并打印出操作系统信息来找到这一点,例如:

docker run  -it  --rm  perl  bash
# cat /etc/*-release

or或者

docker run  -it  --rm  python:3.6  bash
# cat /etc/*-release

BTW, In both cases the OS is "Debian GNU/Linux 10 (buster)".顺便说一句,在这两种情况下,操作系统都是“Debian GNU/Linux 10 (buster)”。

So, my questions are:所以,我的问题是:

  1. How do I find out which OS will be run for a specific docker image without actually creating a docker container from it (the docker inspect command does not provide this info: docker inspect perl | grep -i Debian )如何在不实际从中创建 docker 容器的情况下找出特定 docker 映像将运行哪个操作系统( docker inspect命令不提供此信息: docker inspect perl | grep -i Debian

  2. How do I change the OS type for existing docker image.如何更改现有 docker 映像的操作系统类型。 For example, I have an image that uses Ubuntu 14.04, and I want to change it to Ubuntu 18.04..例如,我有一个使用 Ubuntu 14.04 的映像,我想将其更改为 Ubuntu 18.04..

Thank you for your help:)感谢您的帮助:)

A docker image doesn't need an OS. docker 镜像不需要操作系统。 There's a possibility of extending the scratch image which is purposely empty and the container may only contain one binary or some volume.有可能扩展故意为空的临时映像,并且容器可能只包含一个二进制文件或某个卷。

Having an entire OS is possible but also misleading: The host shares its kernel with the container.拥有一个完整的操作系统是可能的,但也有误导性:主机与容器共享其内核。 (This is not a virtual machine.) (这不是虚拟机。)

That means that no matter what "OS" you are running, the same kernel in the container is found:这意味着无论您运行什么“操作系统”,都会在容器中找到相同的内核:

Both:两个都:

docker run --rm -it python:3.6 uname -a
docker run --rm -it python:3.6-alpine uname -a

will report the same kernel of your host machine.将报告与您的主机相同的内核。

So you have to look into different ways :所以你必须研究不同的方法

docker run --rm -it python:3.6 cat /etc/os-release

or或者

lsb_release -sirc

or for Cent OS:或 Cent 操作系统:

cat /etc/issue

In stead of scratch, a lot of images are also alpine-based to avoid the size overhead.除了从头开始,许多图像也是基于 alpine 的,以避免大小开销。 An ubuntu base image can easily have 500MB fingerprint whereas alpine uses around 5MB;一个 ubuntu 基础镜像很容易有 500MB 的指纹,而 alpine 使用大约 5MB; so I rather check for that as well.所以我也宁愿检查一下。

Also avoid the trap of manually installing everything onto one Ubuntu image inside one big Dockerfile.还要避免将所有内容手动安装到一个大 Dockerfile 中的一个 Ubuntu 映像的陷阱。 Docker works best if each service is its own container that you link together.如果每个服务都是链接在一起的自己的容器,则 Docker 效果最佳。 (For that check out docker-compose .) (为此,请查看docker-compose 。)

In the end, you as an user shouldn't care about the OS of an image, but rather its size.最后,您作为用户不应该关心图像的操作系统,而应该关心它的大小。 Only as a developer of the Dockerfile is it relevant to know the OS and that you'll find out either by looking into the Dockerfile the image was built (if it's on docker hub you can read it there).只有作为 Dockerfile 的开发人员才需要了解操作系统,并且您可以通过查看构建的 Dockerfile 找到镜像(如果它在 docker hub 上,您可以在那里阅读)。

You basically have to look what was used to create your image an use the appropriate tools for the job.您基本上必须查看用于创建图像的内容,并使用适合该工作的工具。 (Debian-based images use apt-get , alpine uses apk , and Fedora uses yum .) (基于 Debian 的镜像使用apt-get , alpine 使用apk ,而 Fedora 使用yum 。)

How do I find out which OS will be run for a specific docker image without actually creating a docker container from it如何在不实际从中创建 docker 容器的情况下找出将为特定 docker 映像运行哪个操作系统

The only way to determine what os is being used is as you have described: spawn a container and print the os information.确定正在使用的操作系统的唯一方法是您所描述的:生成一个容器并打印操作系统信息。 There is no metadata that says "this image was build using <x> ".没有元数据显示“此映像是使用<x>构建的”。

In many (but not all) situations, this information may not be especially important.在许多(但不是全部)情况下,此信息可能不是特别重要。

How do I change the OS type for existing docker image.如何更改现有 docker 映像的操作系统类型。 For example, I have an image that uses Ubuntu 14.04, and I want to change it to Ubuntu 18.04..例如,我有一个使用 Ubuntu 14.04 的映像,我想将其更改为 Ubuntu 18.04..

If you have access to the Dockerfile used to build the image, you can of course change the base image (the image named in the FROM line) and build a new one, but you may find that this requires a number of other changes due to different software versions in your updated image.如果您有权访问用于构建镜像的Dockerfile ,您当然可以更改基础镜像(在FROM行中命名的镜像)并构建一个新镜像,但您可能会发现这需要进行许多其他更改,因为更新图像中的不同软件版本。

You can use " docker cp " to extract the " /etc/os-release " file without starting the container:您可以在不启动容器的情况下使用“ docker cp ”提取“ /etc/os-release ”文件:

$ docker pull ubuntu:latest
Status: Image is up to date for ubuntu:latest

$ docker create ubuntu:latest
2e5da8bf02312870acd0436e0cc4eb28fbcc998f766cd9639c37101f65739553

$ docker cp -L 2e5da8bf02312870acd0436e0cc4eb28fbcc998f766cd9639c37101f65739553:/etc/os-release .

$ docker rm 2e5da8bf02312870acd0436e0cc4eb28fbcc998f766cd9639c37101f65739553

$ cat ./os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

Note: I had to use " docker cp -L " because /etc/os-release is a symlink on ubuntu:latest .注意:我必须使用“ docker cp -L ”,因为/etc/os-releaseubuntu:latest上的符号链接。

Honestly, I find this to be a lot of trouble just to avoid starting the container, and it requires the "/etc/os-release" file to be present.老实说,我发现这只是为了避免启动容器很麻烦,并且它需要存在“/etc/os-release”文件。 If you're willing to (very) briefly run the container, I find this more convenient, and a little more robust.如果您愿意(非常)简短地运行容器,我发现这更方便,也更健壮。 Note: it's very important to specify --entrypoint="" , otherwise the container will start invoking its normal startup routine!注意:指定--entrypoint=""非常重要,否则容器将开始调用其正常的启动例程!

$ docker run --rm -i -a STDOUT --entrypoint="" \
    ubuntu:latest  sh -c 'head -n 1000 /etc/hostname /etc/*[Rr][Ee][Ll]*'

==> /etc/hostname <==
b243ff33e245

==> /etc/lsb-release <==
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"

==> /etc/os-release <==
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

Here's the same command against "alpine:latest":这是针对“alpine:latest”的相同命令:

docker run --rm -i -a STDOUT --entrypoint="" \
    alpine:latest  'sh' '-c' 'head -n 1000 /etc/hostname /etc/*[Rr][Ee][Ll]*'

==> /etc/hostname <==
a8521c768aeb

==> /etc/alpine-release <==
3.13.4

==> /etc/os-release <==
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.13.4
PRETTY_NAME="Alpine Linux v3.13"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

Note: I add "/etc/hostname" to the list of files to "head" to make sure it finds 2 or more files, to ensure "head" to uses its "==> file <==" output style.注意:我将“/etc/hostname”添加到“head”的文件列表中以确保它找到2个或更多文件,以确保“head”使用其“==>文件<==”输出样式。 Whereas if it only runs against a single file it doesn't print the filename.而如果它仅针对单个文件运行,则不会打印文件名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM