Есть ли способ объединить изображения Docker в 1 контейнер?

у меня есть несколько Dockerfiles прямо сейчас.

для Кассандры 3.5, и это FROM cassandra:3.5

у меня тоже есть файла Docker для Кафки, но вполне немного более сложным. Это FROM java:openjdk-8-fre и он запускает длинную команду для установки Кафки и Zookeeper.

наконец, у меня есть приложение, написанное на Scala, которое использует SBT.

для этого Dockerfile это FROM broadinstitute/scala-baseimage, который получает меня Java 8, Scala 2.11.7 и STB 0.13.9, которые являются тем, что я необходимость.

возможно, я не понимаю, как работает Docker, но моя программа Scala имеет Кассандру и Кафку в качестве зависимостей и для целей разработки, я хочу, чтобы другие могли просто клонировать мое РЕПО с помощью Dockerfile и затем иметь возможность построить его с Кассандрой, Кафкой, Scala, Java и SBT все запеченные, так что они могут просто скомпилировать источник. У меня с этим много проблем.

как объединить эти Dockerfiles? Как я могу просто создать среду с помощью эти штуки запеченные?

5 ответов


вы не можете комбинировать dockerfiles, поскольку могут возникнуть конфликты. Вы хотите создать новый файл dockerfile или создать пользовательский образ.

TL; DR; Если ваш текущий контейнер разработки содержит все необходимые инструменты и работает, сохраните его как изображение и на нем в репо и создайте dockerfile, чтобы вытащить из этого изображения из этого РЕПО.

подробности: Создание пользовательского образа намного проще, чем создание dockerfile с использованием общедоступного образа, поскольку вы можете хранить все хаки и моды в изображение. Для этого запустите пустой контейнер с базовым образом Linux (или broadinstitute/scala-baseimage), установите все необходимые инструменты и настройте их, пока все не будет работать правильно, а затем сохраните его (контейнер) как образ. Создайте новый контейнер с этого изображения и проверьте, можете ли вы построить свой код поверх него через docker-compose (или как вы хотите это сделать/построить). Если это работает, то у вас есть рабочий базовый образ, который вы можете загрузить в репо, чтобы другие может потянуть.

чтобы создать dockerfile с публичным изображением, вам нужно будет поместить все хаки, Моды и настройки на самом dockerfile. То есть вам нужно будет поместить каждую используемую вами командную строку в текстовый файл и уменьшить любые хаки, Моды и настройки в командные строки. В конце концов, ваш dockerfile создаст изображение автоматически, и вам не нужно хранить это изображение в репо, и все, что вам нужно сделать, это дать другим dockerfile, и они могут вращать изображение на их собственный докер.

обратите внимание, что как только у вас есть рабочий dockerfile, вы можете легко настроить его, так как он будет создавать новое изображение каждый раз, когда вы используете dockerfile. С пользовательским изображением могут возникнуть проблемы, при которых необходимо перестроить изображение из-за конфликтов. Например, все ваши инструменты работают с openjdk, пока вы не установите тот, который не работает. Исправление может включать удаление openjdk и использование oracle one, но вся конфигурация, которую вы сделали для всех установленных инструментов сломал.


Вы можете, с многоступенчатые сборки функция введена в Docker 1.17

взгляните на это:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  

затем создайте изображение нормально:

docker build -t alexellis2/href-counter:latest

From:https://docs.docker.com/develop/develop-images/multistage-build/

конечный результат такое же малюсенькое изображение продукции как раньше, с значительно уменьшением в сложности. Вам не нужно создавать какие-либо промежуточные изображения и вам вообще не нужно извлекать артефакты в локальную систему.

Как это работает? Второй из инструкции начинает новый этап сборки с alpine: последнее изображение в качестве его базы. Строка COPY --from=0 копирует только встроенный артефакт с предыдущего этапа в этот новый этап. GO SDK и любые промежуточные артефакты остаются позади и не сохраняются в конечном изображении.


Да, вы can сверните много программного обеспечения в один образ Docker (GitLab делает это, с одним изображением, которое включает Postgres и все остальное), но generalhenry правильно - это не типичный способ использования Docker.

Как вы говорите, Кассандра и Кафка зависимости для вашего приложения Scala они не являются частью приложения, поэтому они не все принадлежат к одному изображению.

иметь оркестровать много контейнеры с Docker Compose добавляют дополнительный слой администратора, но это дает вам гораздо большую гибкость:

  • ваши контейнеры могут иметь различную продолжительность жизни, поэтому, когда у вас есть новая версия вашего приложения для развертывания, вам нужно только запустить новый контейнер приложения, вы можете оставить зависимости запущенными;
  • вы можете использовать один и тот же образ приложения в любой среде, используя разные конфигурации для ваших зависимостей-например, в dev вы можете запустить базовый контейнер Kafka и в prod он кластеризован на многих узлах, ваш контейнер приложения одинаков;
  • ваши зависимости могут использоваться и другими приложениями - поэтому несколько потребителей могут работать в разных контейнерах и работать с одними и теми же контейнерами Kafka и Cassandra;
  • плюс вся масштабируемость, ведение журнала и т. д. уже упомянутый.

Docker не выполняет слияния изображений, но ничто не мешает вам комбинировать файлы Dockerfile, если они доступны, и сворачивать их в жирное изображение, которое вам нужно будет построить. Однако иногда это имеет смысл, поскольку для запуска нескольких процессов в контейнере большинство догм Docker укажет на это как на менее желательное, особенно с архитектурой микросервиса (однако правила должны быть нарушены правильно?)


вы не смогли объединить изображения docker в 1 контейнер. См. подробные обсуждения в выпуске Moby,Как объединить несколько изображений в одно с помощью Dockerfile.

для вашего случая лучше не включать все изображения Кассандры и Кафки. Приложению понадобится только драйвер Cassandra Scala и драйвер Kafka Scala. Контейнер должен включать только драйверы.