6.1 Знакомство с оптимизацией образов
Docker-образы хоть и компактны, но всё-таки занимают место. Поэтому уменьшение их размеров — задача важная, и она помогает улучшить производительность, ускорить загрузку и развертывание контейнеров, а также снизить затраты на хранение. Оптимизировать образ можно с помощью улучшения Dockerfile, ведь его можно организовывать по-разному. В этой лекции мы рассмотрим несколько стратегий и лучших практик для создания оптимизированных и легковесных Docker-образов.
Почему важно уменьшать размер Docker-образов?
- Скорость развертывания: меньшие образы быстрее загружаются из реестра Docker и разворачиваются в контейнеры, что особенно важно в автоматизированных системах CI/CD.
- Эффективное использование ресурсов: легковесные образы занимают меньше места на диске, экономят сетевые ресурсы при передаче и обеспечивают более эффективное использование вычислительных мощностей.
- Безопасность: меньшие образы обычно содержат меньше ненужных компонентов, что снижает риск потенциальных уязвимостей.
- Упрощение обновлений: обновление легковесных образов происходит быстрее и требует меньше ресурсов, что ускоряет процесс поддержки.
6.2 Стратегии уменьшения размера Docker-образов
1. Использование минимальных базовых образов
Выбор базового образа напрямую влияет на размер конечного Docker-образа. Использование минимальных базовых образов, таких как alpine, позволяет значительно сократить размер образа.
Пример:
Замена образа ubuntu на alpine:
# FROM ubuntu:20.04
FROM alpine:3.12
alpine — это легковесный Linux-дистрибутив, который занимает около 5 MB, в то время как образ ubuntu может занимать сотни мегабайт.
2. Минимизация количества слоев
Каждая инструкция в Dockerfile добавляет новый слой в образ. Объединение нескольких команд в одной инструкции RUN уменьшает количество слоев, что помогает сократить общий размер образа.
Пример:
До оптимизации:
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN rm -rf /var/lib/apt/lists/*
После оптимизации:
RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*
Удаление кэша пакетного менеджера (rm -rf /var/lib/apt/lists/*) дополнительно уменьшает размер образа, удаляя временные файлы, созданные во время установки.
3. Удаление временных файлов
Удаление временных файлов и ненужных данных после установки пакетов помогает поддерживать образ чистым и легковесным.
Пример:
RUN apt-get update && apt-get install -y curl git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
4. Использование .dockerignore
Файл .dockerignore помогает исключить ненужные файлы и директории из контекста сборки, что уменьшает размер образа и ускоряет процесс сборки.
Пример .dockerignore:
node_modules
dist
*.log
Dockerfile*
.dockerignore
5. Многоэтапная сборка (multi-stage builds)
Многоэтапная сборка позволяет использовать несколько промежуточных образов для создания финального легковесного образа, содержащего только необходимые файлы и зависимости.
Пример:
# Этап сборки
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Финальный этап
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
В этом примере первый этап создает сборку приложения, а финальный этап использует только результаты сборки, что уменьшает размер конечного образа.
6. Оптимизация установки пакетов
Установка только необходимых пакетов и использование опций пакетных менеджеров для минимальной установки помогают уменьшить размер образа.
Пример:
Использование параметра --no-install-recommends для apt-get:
RUN apt-get update && apt-get install -y --no-install-recommends curl git && \
rm -rf /var/lib/apt/lists/*
7. Сжатие и минимизация данных
Использование инструментов для сжатия и минимизации данных помогает уменьшить размер образа.
Пример:
Сжатие текстовых файлов и журналов логов:
RUN gzip /path/to/large/file.log
8. Удаление неиспользуемых библиотек и зависимостей
Удаление неиспользуемых библиотек и зависимостей после установки необходимых пакетов помогает поддерживать образ легковесным.
Пример:
Для Python-приложений:
RUN pip install --no-cache-dir -r requirements.txt
6.3 Примеры оптимизированных Dockerfile
Пример 1: Оптимизированный Dockerfile для Node.js
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
Этот пример использует многоэтапную сборку. Сначала приложение собирается в промежуточном этапе, а затем только результаты сборки копируются в финальный образ на базе Nginx.
Пример 2: Оптимизированный Dockerfile для Python
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
В этом примере используется легковесный базовый образ python:3.9-slim. Установка зависимостей вынесена в отдельный шаг, что позволяет использовать кэш Docker, если файл requirements.txt не изменился.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ