#linux #docker #dockerfile
#linux #docker #dockerfile
Вопрос:
Я новичок в docker, и это просто увлекательный инструмент. Однако я не могу понять одну вещь об этом. Простой файл Dockerfile обычно начинается с имени ОС и версии, например:
FROM ubuntu:xenial
....
Но какая ОС Linux будет использоваться для Dockerfile, например
FROM perl
....
или
FROM python:3.6
....
Конечно, я могу выяснить это, запустив контейнер из этого образа и распечатав информацию об ОС, например:
docker run -it --rm perl bash
# cat /etc/*-release
или
docker run -it --rm python:3.6 bash
# cat /etc/*-release
Кстати, в обоих случаях ОС является «Debian GNU / Linux 10 (buster)».
Итак, мои вопросы:
-
Как мне узнать, какая ОС будет запущена для определенного образа docker, фактически не создавая из него контейнер docker (
docker inspect
команда не предоставляет эту информацию:docker inspect perl | grep -i Debian
) -
Как мне изменить тип ОС для существующего образа docker. Например, у меня есть образ, который использует Ubuntu 14.04, и я хочу изменить его на Ubuntu 18.04..
Спасибо за вашу помощь 🙂
Ответ №1:
Образу docker не нужна операционная система. Существует возможность расширения исходного образа, который намеренно пуст, и контейнер может содержать только один двоичный файл или некоторый объем.
Наличие целой операционной системы возможно, но также вводит в заблуждение: хост разделяет свое ядро с контейнером. (Это не виртуальная машина.)
Это означает, что независимо от того, какую «ОС» вы используете, в контейнере будет найдено одно и то же ядро:
Оба:
docker run --rm -it python:3.6 uname -a
docker run --rm -it python:3.6-alpine uname -a
сообщит о том же ядре вашего хост-компьютера.
Итак, вам нужно искать разные способы:
docker run --rm -it python:3.6 cat /etc/os-release
или
lsb_release -sirc
или для Cent OS:
cat /etc/issue
Вместо scratch многие изображения также основаны на Alpine, чтобы избежать накладных расходов на размер. Базовый образ Ubuntu может легко содержать отпечаток 500 МБ, в то время как alpine использует около 5 МБ; поэтому я предпочитаю проверить и это.
Также избегайте ловушки ручной установки всего на один образ Ubuntu внутри одного большого файла Dockerfile. Docker работает лучше всего, если каждая служба представляет собой отдельный контейнер, который вы связываете вместе. (Для этого ознакомьтесь docker-compose
.)
В конце концов, вас, как пользователя, должна волновать не ОС образа, а его размер. Только как разработчику файла Dockerfile важно знать ОС, и это вы узнаете, либо заглянув в файл Dockerfile, в котором был создан образ (если он есть в docker hub, вы можете прочитать его там).
В основном вам нужно посмотреть, что использовалось для создания вашего образа, и использовать соответствующие инструменты для работы. (Изображения на основе Debian используют apt-get
, alpine использует apk
и Fedora использует yum
.)
Комментарии:
1. Спасибо за ответ.. Но если ОС не важна, как мне узнать, какие инструменты установки (например, Ubuntu «apt-get» или CentOS «yum» и т. Д.) Следует использовать в файле Docker, который основан на изображениях, таких как «perl» или «python» и т. Д.?
2. @Ivan Если вы используете файл Dockerfile разных людей, не должно быть особой необходимости устанавливать что-либо еще, вам в основном понадобится только образ. Если вы создаете файл Dockerfile, ОС — это ваш выбор. Можете ли вы пояснить, почему вы хотите переместить одно изображение с 14.04 на 18.04?
3. Ну, я пытаюсь создать образ Docker для веб-приложения, основанного на платформе Catalyst framework Perl ( mysql db). Я нашел этот образ catalyst docker на github, основанный на Ubuntu 14.04 hub.docker.com/r/rsrchboy/perl-catalyst-latest С другой стороны, производственный сервер, на котором запущено приложение Catalyst, использует Ubuntu 18.04. Итак, я просто хотел сделать образ docker как можно ближе к производственному серверу, чтобы убедиться, что все будет работать таким же образом 🙂
4. Этот образ, который вы хотите использовать, является устаревшим, и у него были родители, а у родителя есть родитель. Вы могли бы попробовать скопировать все три файла Dockerfile вместе, чтобы сохранить его на основе ubuntu: bionic.
5. Да, это то, что я собирался сделать) Спасибо за помощь, чувак)
Ответ №2:
Как мне узнать, какая ОС будет запущена для определенного образа docker, фактически не создавая из него контейнер docker
Единственный способ определить, какая ОС используется, таков, как вы описали: создайте контейнер и распечатайте информацию об ОС. Нет метаданных, в которых говорится «этот образ был собран с использованием <x>
«.
Во многих (но не во всех) ситуациях эта информация может быть не особенно важной.
Как мне изменить тип ОС для существующего образа docker. Например, у меня есть образ, который использует Ubuntu 14.04, и я хочу изменить его на Ubuntu 18.04..
Если у вас есть доступ к тому, Dockerfile
который использовался для создания образа, вы, конечно, можете изменить базовый образ (образ, указанный в FROM
строке) и создать новый, но вы можете обнаружить, что для этого требуется ряд других изменений из-за разных версий программного обеспечения в вашем обновленном образе.
Ответ №3:
Вы можете использовать « 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
Примечание: мне пришлось использовать « docker cp -L
«, потому что /etc/os-release
это символическая ссылка на ubuntu:latest
.
Честно говоря, я нахожу, что это доставляет много хлопот только для того, чтобы избежать запуска контейнера, и для этого требуется наличие файла «/ etc / os-release». Если вы готовы (очень) кратко запустить контейнер, я нахожу это более удобным и немного более надежным. Примечание: очень важно указать --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
Вот та же команда для «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/"
Примечание: я добавляю «/etc /hostname» в список файлов в «head», чтобы убедиться, что он находит 2 или более файлов, чтобы убедиться, что «head» использует свой стиль вывода «==> file <==». Принимая во внимание, что если он выполняется только с одним файлом, он не выводит имя файла.