Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве вы узнаете, как сохранять данные в приложении контейнера. При запуске или обновлении программы данные по-прежнему доступны. Существует два основных типа томов, используемых для сохранения данных. В этом руководстве основное внимание уделяется именованным томам .
Кроме того, вы узнаете о привязки подключений, которые управляют точной точкой подключения на узле. Вы можете использовать подключения привязок для сохранения данных, но они также могут добавлять дополнительные данные в контейнеры. При работе с приложением можно использовать подключение привязки для подключения исходного кода к контейнеру, чтобы он видел изменения кода, отвечать и сразу видеть изменения.
В этом руководстве также описаны слои изображений, кэширование слоев и многоэтапные сборки.
В этом руководстве описано, как:
- Понять данные в разных контейнерах.
- Хранить данные с помощью именованных томов.
- Используйте монтажи с привязкой.
- Просмотр слоя изображения.
- Зависимости кэша.
- Понимание многоэтапных сборок.
Необходимые условия
В этом руководстве продолжается предыдущее руководство. Создание и предоставление общего доступа к приложению-контейнеру с помощью Visual Studio Code. Начните с этого, который включает предварительные требования.
Понимание данных в различных контейнерах
В этом разделе вы запустите два контейнера и создадите файл в каждом из них. Файлы, созданные в одном контейнере, недоступны в другом.
Запустите контейнер
ubuntu
с помощью следующей команды:docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
Эта команда запускает вызов двух команд с помощью
&&
. Первая часть выбирает одно случайное число и записывает его в/data.txt
. Вторая команда отслеживает файл для поддержания работы контейнера.В VS Code в обозревателе контейнеров щелкните правой кнопкой мыши контейнер Ubuntu и выберите "Подключить оболочку".
Откроется терминал, который выполняет оболочку в контейнере Ubuntu.
Выполните следующую команду, чтобы просмотреть содержимое файла
/data.txt
.cat /data.txt
В терминале отображается число от 1 до 10000.
Чтобы просмотреть этот результат, получите идентификатор контейнера с помощью команды
docker ps
и выполните следующую команду.docker exec <container-id> cat /data.txt
Запустите другой контейнер
ubuntu
.docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
Используйте эту команду для просмотра содержимого папки.
docker run -it ubuntu ls /
Там не должно быть файла
data.txt
, так как он был записан в временную область только для первого контейнера.Выберите эти два контейнера Ubuntu. Щелкните правой кнопкой мыши и выберите Удалить. Из командной строки их можно удалить с помощью команды
docker rm -f
.
Сохраняйте данные "todo" с помощью именованных томов
По умолчанию приложение todo сохраняет свои данные в базе данных SQLite SQLite по /etc/todos/todo.db
.
База данных SQLite — это реляционная база данных, которая хранит данные в одном файле.
Этот подход подходит для небольших проектов.
Вы можете сохранить один файл на хосте. Когда вы сделаете его доступным для следующего контейнера, приложение сможет продолжить с того места, на котором остановилось. Создав том и прикрепив или смонтировавего в папку, в которой хранятся данные, можно обеспечить сохранение данных. Контейнер записывает данные в файл todo.db и данные сохраняются на узле в томе.
В этом разделе используется именованный том. Docker сохраняет физическое расположение тома на диске. Обратитесь к имени тома, и Docker предоставит правильные данные.
Создайте том с помощью команды
docker volume create
.docker volume create todo-db
В разделе КОНТЕЙНЕРЫвыберите getting-started и кликните правой кнопкой. Выберите «Остановить», чтобы завершить работу контейнера приложения.
Чтобы остановить контейнер из командной строки, используйте команду
docker stop
.Запустите контейнер getting-started с помощью следующей команды.
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
Параметр тома указывает том для монтирования и его местоположение,
/etc/todos
.Обновите браузер, чтобы перезагрузить приложение. Если вы закрыли окно браузера, перейдите к
http://localhost:3000/
. Добавьте некоторые элементы в список дел.Удалите контейнер getting-started для приложения для задач. Чтобы удалить, щелкните правой кнопкой мыши контейнер в обозревателе контейнеров и выберите Удалить или используйте команды
docker stop
иdocker rm
.Запустите новый контейнер с помощью той же команды:
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
Эта команда подключает тот же диск, что и раньше. Обновите браузер. Добавленные элементы по-прежнему находятся в списке.
Удалите контейнер с отметкой , снова.
Именованные тома и подключения привязок, рассмотренные ниже, являются основными типами томов, поддерживаемых установкой ядра Docker по умолчанию.
Свойство | Именованные тома | Привязка точек монтирования |
---|---|---|
Местоположение хоста | Docker выбирает | Вы управляете |
Пример монтажа (с использованием -v ) |
my-volume:/usr/local/data | /path/to/data:/usr/local/data |
Заполняет новый том содержимым контейнера | Да | Нет |
Поддерживает драйверы томов | Да | Нет |
Существует множество подключаемых модулей драйвера томов для поддержки NFS, SFTP, NetApp и многое другое. Эти плагины особенно важны для запуска контейнеров на нескольких узлах в таких кластерных средах, как Swarm или Kubernetes.
Если вы хотите узнать, где docker фактически хранить данные, выполните следующую команду.
docker volume inspect todo-db
Посмотрите на выходные данные, аналогичные этому результату.
[
{
"CreatedAt": "2019-09-26T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
Mountpoint
— это место, где хранятся данные.
На большинстве компьютеров требуется корневой доступ для доступа к этому каталогу с узла.
Используйте привязанные точки монтирования
При использовании привязкивы управляете точной точкой подключения на узле. Этот подход сохраняет данные, но часто используется для предоставления дополнительных данных в контейнеры. Вы можете использовать привязанный том для монтирования исходного кода в контейнер, чтобы отслеживать изменения кода, реагировать на них и сразу видеть произошедшие изменения.
Чтобы запустить контейнер для поддержки рабочего процесса разработки, выполните следующие действия:
Удалите все контейнеры
getting-started
.В папке
app
выполните следующую команду.docker run -dp 3000:3000 -w /app -v ${PWD}:/app node:lts-alpine sh -c "yarn install && yarn run dev"
Эта команда содержит следующие параметры.
-
-dp 3000:3000
То же, что и раньше. Запустите в отсоединяемом режиме и создайте сопоставление портов. -
-w /app
рабочая директория внутри контейнера. -
-v ${PWD}:/app"
Привязать текущий каталог из узла в контейнере в каталог/app
. -
node:lts-alpine
Используемое изображение. Это базовый образ приложения на основе Dockerfile. -
sh -c "yarn install && yarn run dev"
команду A. Она запускает оболочку с помощьюsh
и запускаетyarn install
для установки всех зависимостей. Затем он запускаетсяyarn run dev
. При просмотре вpackage.json
, скриптdev
начинаетсяnodemon
.
-
Журналы можно просматривать, используя
docker logs
.docker logs -f <container-id>
$ nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000
Когда вы увидите последнюю запись в этом списке, приложение запущено.
После просмотра журналов нажмите любую клавишу в окне терминала или выберите комбинацию клавиш Ctrl+C во внешнем окне.
В VS Code откройте src/static/js/app.js. Измените текст кнопки Добавить элемент в строке 109.
- {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
Сохраните изменения.
Обновите браузер. Вы увидите изменение.
node:lts-alpine
Удалите контейнер.В папке
app
выполните следующую команду, чтобы удалитьnode_modules
папку, созданную на предыдущих шагах.rm -r node_modules
Просмотр слоев изображений
Вы можете посмотреть на слои, составляющие изображение.
Выполните команду docker image history
, чтобы увидеть команду, которая использовалась для создания каждого слоя в изображении.
Используйте
docker image history
, чтобы просмотреть слои в изображении по изучаемой теме, созданном ранее в руководстве.docker image history getting-started
Результат должен выглядеть примерно так.
IMAGE CREATED CREATED BY SIZE COMMENT a78a40cbf866 18 seconds ago /bin/sh -c #(nop) CMD ["node" "/app/src/ind… 0B f1d1808565d6 19 seconds ago /bin/sh -c yarn install --production 85.4MB a2c054d14948 36 seconds ago /bin/sh -c #(nop) COPY dir:5dc710ad87c789593… 198kB 9577ae713121 37 seconds ago /bin/sh -c #(nop) WORKDIR /app 0B b95baba1cfdb 13 days ago /bin/sh -c #(nop) CMD ["node"] 0B <missing> 13 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B <missing> 13 days ago /bin/sh -c #(nop) COPY file:238737301d473041… 116B <missing> 13 days ago /bin/sh -c apk add --no-cache --virtual .bui… 5.35MB <missing> 13 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.21.1 0B <missing> 13 days ago /bin/sh -c addgroup -g 1000 node && addu… 74.3MB <missing> 13 days ago /bin/sh -c #(nop) ENV NODE_VERSION=12.14.1 0B <missing> 13 days ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:e69d441d729412d24… 5.59MB
Каждая из строк представляет слой в изображении. В выходных данных показана база внизу с самым новым слоем в верхней части. С помощью этой информации можно просмотреть размер каждого слоя, помогая диагностировать большие изображения.
Несколько линий усечены. Если добавить параметр
--no-trunc
, вы получите полные выходные данные.docker image history --no-trunc getting-started
Зависимости кэша
После изменения слоя все нижние слои также должны быть повторно созданы. Вот Dockerfile еще раз:
FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "/app/src/index.js"]
Каждая команда в Dockerfile становится новым слоем на изображении.
Чтобы свести к минимуму количество слоев, можно изменить структуру Dockerfile для поддержки кэширования зависимостей.
Для приложений на основе узлов эти зависимости определяются в файле package.json
.
Подход заключается в том, чтобы скопировать только этот файл в первую очередь, установить зависимости и затем скопировать все остальное.
Процесс воссоздаёт зависимости yarn только в том случае, если в package.json
произошло изменение.
Обновите Dockerfile, чтобы сначала скопировать их в
package.json
, установить зависимости и скопировать все остальное. Вот новый файл:FROM node:lts-alpine WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --production COPY . . CMD ["node", "/app/src/index.js"]
Создайте новый образ с помощью
docker build
.docker build -t getting-started .
Выходные данные должны выглядеть следующим образом:
Sending build context to Docker daemon 219.1kB Step 1/6 : FROM node:lts-alpine ---> b0dc3a5e5e9e Step 2/6 : WORKDIR /app ---> Using cache ---> 9577ae713121 Step 3/6 : COPY package* yarn.lock ./ ---> bd5306f49fc8 Step 4/6 : RUN yarn install --production ---> Running in d53a06c9e4c2 yarn install v1.17.3 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@1.2.9: The platform "linux" is incompatible with this module. info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 10.89s. Removing intermediate container d53a06c9e4c2 ---> 4e68fbc2d704 Step 5/6 : COPY . . ---> a239a11f68d8 Step 6/6 : CMD ["node", "/app/src/index.js"] ---> Running in 49999f68df8f Removing intermediate container 49999f68df8f ---> e709c03bc597 Successfully built e709c03bc597 Successfully tagged getting-started:latest
Все слои были перестроены. Этот результат ожидается, так как вы изменили Dockerfile.
Внесите изменения в src/static/index.html. Например, измените название, чтобы сказать "Удивительное приложение Todo".
Создайте образ Docker теперь с помощью
docker build
еще раз. На этот раз выходные данные должны выглядеть немного иначе.Sending build context to Docker daemon 219.1kB Step 1/6 : FROM node:lts-alpine ---> b0dc3a5e5e9e Step 2/6 : WORKDIR /app ---> Using cache ---> 9577ae713121 Step 3/6 : COPY package* yarn.lock ./ ---> Using cache ---> bd5306f49fc8 Step 4/6 : RUN yarn install --production ---> Using cache ---> 4e68fbc2d704 Step 5/6 : COPY . . ---> cccde25a3d9a Step 6/6 : CMD ["node", "/app/src/index.js"] ---> Running in 2be75662c150 Removing intermediate container 2be75662c150 ---> 458e5c6f080c Successfully built 458e5c6f080c Successfully tagged getting-started:latest
Так как вы используете кэш сборки, он должен выполняться гораздо быстрее.
Многоэтапные сборки
Многоэтапные сборки — это невероятно мощный инструмент, помогающий использовать несколько этапов для создания образа. Существует несколько преимуществ для них:
- Разделение зависимостей во время сборки от зависимостей среды выполнения
- Уменьшите общий размер изображения, оставив только то, что необходимо для работы вашего приложения.
В этом разделе приведены краткие примеры.
Пример Maven/Tomcat
При создании приложений на основе Java JDK требуется для компиляции исходного кода в байт-код Java. Этот JDK не нужен в рабочей среде. Вы можете использовать такие инструменты, как Maven или Gradle, чтобы создать приложение. Эти инструменты также не нужны в конечном изображении.
FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package
FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps
В этом примере используется один этап build
для выполнения фактической сборки Java с помощью Maven.
Второй этап, начиная с "FROM tomcat", копирует файлы с этапа build
.
Окончательный образ — это только последний этап создания, который можно переопределить с помощью параметра --target
.
Пример React
При создании приложений React требуется среда Node для компиляции кода JavaScript, таблиц стилей Sass и многое другое в статический HTML, JavaScript и CSS. Если вы не выполняете отрисовку на стороне сервера, вам даже не нужна среда Node для рабочей сборки.
FROM node:lts-alpine AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
В этом примере для выполнения сборки используется образ node:lts-alpine
, который максимизирует кэширование слоев, а затем копирует выходные данные в контейнер nginx.
Очистка ресурсов
Сохраните все, что вы сделали до сих пор, чтобы продолжить эту серию учебных материалов.
Дальнейшие действия
Вы узнали о вариантах сохранения данных для приложений-контейнеров.
Что вы хотите сделать дальше?
Работа с несколькими контейнерами с помощью Docker Compose:
создание многоконтейнерных приложений с помощью MySQL и Docker Compose
Развертывание в приложениях контейнеров Azure:
Развертывание в Службе приложений Azure