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

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

Один для Cassandra 3.5, и это FROM cassandra:3.5

У меня также есть Dockerfile для Kafka, но t довольно немного сложнее. Это FROM java:openjdk-8-fre и он выполняет длинную команду для установки Kafka и Zookeeper.

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

Для этого файла Dockerfile это FROM broadinstitute/scala-baseimage, который получает мне Java 8, Scala 2.11.7 и STB 0.13.9, которые мне нужны.

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

Как объединить эти файлы Docker? Как просто создать среду с этими вещами?

Ответ 1

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

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

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

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

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

Ответ 2

Вы можете, используя функцию многоступенчатой сборки, представленную в 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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

Вы не можете комбинировать изображения докеров в 1 контейнер. См. Подробные обсуждения в проблеме Moby. Как объединить несколько изображений в один файл через Dockerfile.

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