LINUX.ORG.RU
ФорумAdmin

Ошибка при установке deb-пакетов в Docker-контейнер на базе Astra Linux

 , , , ,


0

1

Всем привет! Недавно начал осваивать Docker. Руководствуясь документацией создал образ с Astra Linux. Далее, раскомментировав репозитории в sources.list, начал через apt накатывать пакеты: делал это в оболочке внутри контейнера через docker run -it astralinux:latest /bin/bash, а потом выходил и коммитил при помощи docker commit <id контейнера> <нужное мне название>.

Вчера при попытке накатить туда git столкнулся с ошибкой:

dpkg: ошибка при обработке архива /var/cache/apt/archives/perl-base_5.28.1-6+deb10u1+ci202305241311+astra2+b2_amd64.deb (--unpack):
 не удалось создать резервную ссылку на «./usr/bin/perl» перед установкой новой версии: Отказано в доступе
dpkg-deb: ошибка: вставка subprocess was killed by signal (Обрыв канала)
При обработке следующих пакетов произошли ошибки:
 /var/cache/apt/archives/perl-base_5.28.1-6+deb10u1+ci202305241311+astra2+b2_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

Что пытался делать для решения:

  1. Интернет говорил пробовать запускать apt через sudo, но в ответ мне выдавало bash: sudo: команда не найдена. Установка sudo через apt проблему не решила: выдавало всё туже же dpkg ошибку.

  2. Также пробовал через setfacl давать пользователю _apt права на чтение и выполнение для директорий /var/cache/apt/archives/ и /usr/bin/perl, что результата также не дало:

setfacl -R -m u:_apt:rx <пути, о которых я писал выше>
  1. Команда dpkg --configure -a также не дала результата

До этого я уже сталкивался с данной проблемой, но она пропадала как-то сама. Что для этого потребовалось - я так и не понял.

Поитогу решить вопрос всё-таки удалось. Проблема исчезла, как только я взял изначальный образ, на основе которого создавал все контейнеры.

Могут знающие люди подсказать, из-за чего описанная мною проблема возникает, и какие есть методы её решения?

UPD: Столкнулся с той же проблемой, когда собирал образ с pvs-studio через докерфайл.Через apt-get накатил wget, make и ca-certificates, а потом потёр всё через purge и… Короче, проще фрагмент файла кинуть (sed в начале - это я раскомменчиваю репозитории с нужными пакетами):

RUN sed '7 s/#//' /etc/apt/sources.list -i && \
    apt-get update -q && \
    apt-get -yq install make g++ wget ca-certificates --no-install-recommends && \
    ...
    apt-get purge -qy wget ca-certificates && \
    apt-get autoremove -y && \
    apt-get clean && \
    rm /etc/apt/sources.list.d/viva64.list && \
    rm -rf /var/lib/lists

Потом следующим RUN-ом пытался накатить g++ для cmake (сверху уже итоговый докерфайл, в котором я ставлю g++ вначале). Ключевое слово, как вы понимаете «пытался». Вылезла та же ошибка, но в этот раз он ругался на libc6, который apt пометил для обновления. На основании этого всего я предположил, что корень проблемы лежит в зависимостях между пакетами: возможно система не даёт трогать либс потому что на нём много завязано. А без этого обновления g++ поставить не получилось (невозможность установки g++ после apt-mark на libc явно дала это понять). apt с флагами -f и --no-upgrade результатов не дали.

Возможно решение кроется в установке всех зависимых пакетов по-одному вручную (через apt download и apt install *.deb), но проверять это у меня нет никакого желания. Возможно, это кому-то поможет



Последнее исправление: snake_0 (всего исправлений: 4)

Изнутри контейнера проблем быть не должно, разве что пакет с перлом действительно кривой. А вот снаружи… Снаружи у тебя что? Если тоже астра, проверь, не поехали ли у тебя там метки, например, от использования томов в другом контейнере или ещё что.

Ну и да, докер это больше про то чтобы сделать, поработать и снести, а потом сделать ещё раз, чем про то, чтобы долго и неуклонно накапливать изменения. Не то, чтобы это запрещено, просто мало кто так делает.

Aceler ★★★★★
()

для обеспечения повторяемости, да и просто для удобства, лучше для подготовки контейнеров использовать образы (docker image), которые готовить с помощью Dockerfile + docker build

aol ★★★★★
()

Почему падает - так просто не разобраться.

Но сама идея строить образ через установку в базовый вручную, и docker commit - идеологически неправильная.

Правильно говорят, что надо делать свой образ на основе базового, написав Dockerfile, начинающийся с FROM astralinux:... и дописав в него RUN apt install perl...

Я лично docker commit использую только в целях отладки (где-то для отладки чего-то не хватает на тестовом сервере, и чтобы не проходить всю цепочку с самого начала, доустанавливаю в образ, и коммичу). Но даже это требуется исключительно редко, не чаще 1-2 раз в год.

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

А чисто технически разница есть? Просто лично мне удобнее собирать образы ручками, чтобы в случае ошибки быстро всё переделать, а не лазить по 100 раз докерфайл и не ждать, пока оно снова соберётся.

Собирать образы через build и докерфайл - это просто правило хорошего тона? Или у такого подхода есть какие-то свои технические обоснования?

snake_0
() автор топика
Ответ на: комментарий от snake_0

чтобы в случае ошибки быстро всё переделать, а не лазить по 100 раз докерфайл

вот как раз докерфайл про «быстро всё переделать», а не вспоминать, «чо я туда ставил и правил»

и не ждать, пока оно снова соберётся.

слои кешируются. грамотно составленный докерфайл пересобирается быстро

aol ★★★★★
()
Ответ на: комментарий от snake_0

Собирать образы через build и докерфайл - это просто правило хорошего тона? Или у такого подхода есть какие-то свои технические обоснования?

Потому что это просто и повторимо. Образы докер обычно не в вакууме используются, а используются для работы в команде, CI/CD, деплоя, и т.д. и т.п.

Не будешь же всем раздавать инструкции: «Запустите этот образ, и выполните вот эту портянку команд», или обмениваться образами вручную через docker push/docker pull, тем более, через docker save/docker docker load.

Проще один раз написать Dockerfile, и использовать его всюду, например, чтобы билдить образ в CI/CD.

И да, времени много это занимает только в самом начале. А так, образ строится по слоям, и если не было изменений, влияющих на слой, то при пересборке этот слой будет переиспользоваться из кеша, потому сборка не занимает уйму времени, да и нужна пересборка редко.

Chiffchaff
()

Вообщем, сделал всё то же самое но через Докерфайл. Никакой ошибки не было, так оказалось действительно проще. Спасибо всем большое за ваши ответы, было очень интересно почитать

snake_0
() автор топика