Как создать файл сборки Docker, который может запускать мою программу на C ++ в busybox? - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь играть и изучать использование докера во встроенном мире.В качестве начала я использую образ докера busybox и пытаюсь скопировать бинарный файл моей программы на C ++ в контейнер докера.Тем не менее, я вижу, что я не могу выполнить двоичный файл в поле занят.Я не уверен, что мне не хватает.Используется ли занятая док-станция как-то так?

Вот то, что я пробовал до сих пор -

Dockerfile

FROM busybox:1.30
COPY ./test4.out /home/
CMD  /home/test4.out

Теперь вот мой код на C ++.

#include <iostream>

using namespace std;

int main()
{

  return 120;
}

Я скомпилировал этот код на своем хост-компьютере -

#gcc test4.cpp  -o test4.out

Создайте докер

docker build -t abc/busybox-smarter:1.0 .

docker build -t abc/busybox-smarter:1.0 .
Sending build context to Docker daemon  12.29kB
Step 1/3 : FROM busybox:1.30
 ---> af2f74c517aa
Step 2/3 : COPY ./test4.out /home/
 ---> Using cache
 ---> 1d6fe02933c1
Step 3/3 : CMD  /home/test4.out
 ---> Using cache
 ---> dd590ef4059d
Successfully built dd590ef4059d
Successfully tagged abc/busybox-smarter:1.0

Теперь я запускаю этот образ.

docker run --rm -ti abc/busybox-smarter:1.0 /bin/sh

/home # ./test4.out 
/bin/sh: ./test4.out: not found

1 Ответ

1 голос
/ 01 мая 2019

Образ busybox содержит минимальную коллекцию статически скомпилированных двоичных файлов (большинство из которых на самом деле просто жесткие ссылки на busybox). Вывод вашей команды gcc, с другой стороны, представляет собой динамически связанный исполняемый файл:

$ g++ -o test4.out test4.cpp
$ file test4.out
test4.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9c3a99f3baa5f699f4e32fa65acc58ac8ddc099c, not stripped

Для выполнения требуется соответствующий динамический загрузчик (обычно что-то вроде /lib64/ld-linux-x86-64.so.2).

Это не существует в образе busybox, что приводит к ошибке «not found».

В дополнение к динамическому загрузчику, ваш код имеет несколько дополнительных зависимостей от общей библиотеки:

$ ldd prog
        linux-vdso.so.1 (0x00007fff01dbb000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f566279e000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f566240a000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f56621f2000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f5661e34000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5662b30000)

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

Вы можете попытаться статически скомпилировать ваш код. Сначала вам нужно организовать статические версии любых необходимых библиотек в вашей системе. В моей среде Fedora 28 это означало, что мне сначала нужно было выполнить:

yum -y install libstdc++-static glibc-static

И тогда мне удалось сгенерировать статическую версию двоичного файла:

$ g++ --static -o test4.out test4.cpp
$ file test4.out
test4.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=d0f3b446020e1b067ededb59ec491bff9634f550, not stripped

Я могу запустить этот образ в busybox контейнере без проблем.

ПРЕДУПРЕЖДЕНИЕ! Существуют некоторые функции (обычно те, которые имеют дело с разрешением имени хоста и пользователями / группами), которым требуются динамические разделяемые библиотеки во время выполнения, даже когда они скомпилированы с --static.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...