Volumes, bind mounts, tmpfs — работа с данными в контейнерах
Контейнеры по умолчанию не сохраняют данные. Изучите механизмы хранения: volumes, bind mounts и tmpfs.
Сравним производительность разных типов монтирования:
# Тест записи 1GB данных
docker run --rm -v test-volume:/data alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=1024
docker run --rm -v /tmp:/data alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=1024
docker run --rm --tmpfs /tmp:size=1g alpine \
dd if=/dev/zero of=/tmp/testfile bs=1M count=1024| Тип монтирования | Запись (MB/s) | Чтение (MB/s) | IOPS |
|---|---|---|---|
| Volume (Linux) | 500-800 | 600-900 | 50K+ |
| Bind mount (Linux) | 400-700 | 500-800 | 40K+ |
| tmpfs | 2000-5000 | 3000-7000 | 500K+ |
| Volume (macOS) | 50-150 | 100-200 | 5K |
| Bind mount (macOS) | 30-100 | 50-150 | 3K |
| Bind mount (WSL2) | 200-400 | 300-500 | 20K |
# Используйте :cached для данных, которые читаются чаще чем записываются
docker run -v $(pwd):/app:cached myapp
# Используйте :delegated для данных, которые записываются чаще
docker run -v $(pwd):/app:delegated myapp
# Для gRPC/FSEvent используйте osxfs
# В Docker Desktop включите "Use gRPC for file sharing"# Монтирование из WSL2 имеет лучшую производительность
# Используйте пути WSL вместо Windows paths
# ❌ Медленно (через 9p)
docker run -v C:/Users/app:/app myapp
# ✅ Быстро (из WSL2 filesystem)
docker run -v /home/user/app:/app myapp# Для максимальной производительности используйте volumes
# Разместите Docker data directory на быстром SSD
# Проверка расположения
docker info | grep "Docker Root Dir"
# Изменение в /etc/docker/daemon.json
{
"data-root": "/mnt/fast-ssd/docker"
}# Мониторинг I/O контейнера в реальном времени
docker stats --no-stream
# Детальная информация через iostat
iostat -x 1
# Отслеживание операций с файлами
docker exec container_name strace -e trace=file command
# Использование iotop на хосте
sudo iotop -oPa# Проверка статуса
getenforce
# Контекст безопасности для volume
docker run -v my-volume:/data:z myapp
# :z — общий контент (изменяет метку)
# :Z — приватный контент (уникальная метка)
# Пример с bind mount
docker run -v /host/data:/data:ro,Z myapp# Проверка статуса
sudo aa-status
# Профиль по умолчанию применяется автоматически
# Для отключения (не рекомендуется в production)
docker run --security-opt apparmor=unconfined myapp# ❌ ОПАСНО: Доступ ко всей директории пользователя
docker run -v /home/user:/app myapp
# ✅ Безопасно: Только необходимая директория
docker run -v /home/user/app/data:/app/data myapp
# ✅ Ещё лучше: volume с ограниченным доступом
docker volume create --opt type=tmpfs app-data# Volume с ограниченным доступом
docker volume create \
--opt type=tmpfs \
--opt device=tmpfs \
--opt o=size=100m,mode=1777 \
secure-volume
# Проверка настроек
docker volume inspect secure-volume# Использование trivy для сканирования
docker run --rm -v my-volume:/data:ro \
aquasec/trivy fs /data
# Использование clamav для антивирусной проверки
docker run --rm -v my-volume:/data:ro \
clamav/clamav clamscan -r /dataМинимальные привилегии
# Read-only где возможно
docker run -v data:/app/data:ro myapp
# Конкретный пользователь
docker run -u 1000:1000 -v data:/app/data myappИзоляция чувствительных данных
# tmpfs для секретов
docker run --tmpfs /run/secrets:size=10m,mode=1700 myapp
# Docker secrets (Swarm)
echo "mysecret" | docker secret create db_password -Регулярный аудит
# Проверка всех volumes
docker volume ls -q | xargs -I {} docker volume inspect {}
# Поиск world-readable файлов
docker run --rm -v my-volume:/data alpine \
find /data -perm -002 -type fversion: '3.8'
services:
app:
image: myapp:latest
volumes:
# Краткий синтаксис
- my-volume:/app/data
- ./config:/app/config:ro
- /absolute/path:/app/logs
# Полный синтаксис (type: bind/volume/tmpfs)
- type: volume
source: my-volume
target: /app/data
read_only: false
- type: bind
source: ./config
target: /app/config
read_only: true
- type: tmpfs
target: /tmp
tmpfs:
size: 10000000 # bytes
volumes:
my-volume:
# Named volume
name: my-custom-volume
db-data:
# Volume с драйвером
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/exports/data"
cache-volume:
# tmpfs volume
driver: local
driver_opts:
type: tmpfs
device: tmpfs
o: size=100m# docker-compose.yml (базовый)
version: '3.8'
services:
db:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
# docker-compose.override.yml (разработка)
version: '3.8'
services:
db:
volumes:
- ./pg-data:/var/lib/postgresql/data
# docker-compose.prod.yml (production)
version: '3.8'
services:
db:
volumes:
- db-data:/var/lib/postgresql/data
- ./backups:/backups:ro
volumes:
db-data:
driver: local
driver_opts:
type: ext4
device: /dev/sdb1version: '3.8'
services:
postgres:
image: postgres:15
volumes:
# ✅ Именованный — управляется вами
- postgres-data:/var/lib/postgresql/data
# ⚠️ Анонимный — Docker создаёт случайное имя
- /var/lib/postgresql/data
# ⚠️ Анонимный с driver_opts
- type: volume
target: /app/cache
volume:
nocopy: true
volumes:
postgres-data: # Будет создан с именем проекта# Запуск с volumes
docker-compose up -d
# Остановка (volumes сохраняются)
docker-compose down
# Остановка с удалением volumes
docker-compose down -v
# Удаление конкретного volume
docker-compose volume rm db-data
# Просмотр volumes
docker-compose volume ls| Характеристика | Docker Volumes | Kubernetes PV |
|---|---|---|
| Управление | Docker | Kubernetes |
| Оркестрация | Docker Swarm | K8s Scheduler |
| Динамическое создание | Volume drivers | StorageClass |
| Snapshots | Driver-dependent | VolumeSnapshot |
| Multi-node | Plugin required | Native support |
# Docker Compose
version: '3.8'
services:
postgres:
image: postgres:15
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:
# Kubernetes Deployment + PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pg-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
template:
spec:
containers:
- name: postgres
image: postgres:15
volumeMounts:
- name: pg-data
mountPath: /var/lib/postgresql/data
volumes:
- name: pg-data
persistentVolumeClaim:
claimName: pg-dataapiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true# Размер всех volumes
docker system -v
# Детальная информация с размером
docker volume ls -q | xargs -I {} sh -c \
'echo "Volume: {}"; du -sh /var/lib/docker/volumes/{}/_data'
# Через Docker API
curl -s --unix-socket /var/run/docker.sock \
http://localhost/volumes | jq '.Volumes[] | {Name, Mountpoint}'# docker-compose.yml с экспортером
version: '3.8'
services:
docker-exporter:
image: prom/prometheus-docker-exporter
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "9323:9323"
# prometheus.yml
scrape_configs:
- job_name: 'docker-volumes'
static_configs:
- targets: ['docker-exporter:9323']Ключевые метрики для мониторинга:
# Использование места на volume
docker_volume_size_bytes - docker_volume_used_bytes
# Количество активных volumes
count(docker_volume_info)
# Volume без контейнеров
count(docker_volume_info) without (container_id)# alertmanager.yml
alerts:
- alert: VolumeSpaceLow
expr: docker_volume_used_bytes / docker_volume_size_bytes > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "Volume {{ $labels.volume }} заполнен на {{ $value | humanizePercentage }}"
- alert: VolumeNotMounted
expr: count by (volume) (docker_volume_container_info) == 0
for: 10m
labels:
severity: info
annotations:
summary: "Volume {{ $labels.volume }} не используется"# Включение аудита Docker
# /etc/docker/daemon.json
{
"log-driver": "syslog",
"log-opts": {
"syslog-facility": "daemon",
"tag": "docker"
}
}
# Просмотр логов операций
journalctl -u docker | grep -E "volume|mount"# Контейнер-инициализатор
docker run --rm -v shared-data:/data \
alpine sh -c "echo 'initial data' > /data/init.txt"
# Контейнеры с доступом к данным
docker run -d --name app1 -v shared-data:/data myapp
docker run -d --name app2 -v shared-data:/data myapp
# Проверка
docker exec app1 cat /data/init.txt
docker exec app2 cat /data/init.txt# Создание NFS volume
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw,vers=4.1 \
--opt device=:/export/docker-volumes \
nfs-shared
# Использование в Swarm
docker service create \
--mount type=volume,source=nfs-shared,target=/data \
--replicas 3 \
myapp# Использование encfs для шифрования
docker volume create \
--driver local \
--opt type=encfs \
--opt o=--cipher=AES-256-SSL \
--opt device=/path/to/encrypted:/path/to/mount \
encrypted-volume
# Или используйте Docker secrets (Swarm)
echo "encryption-key" | docker secret create enc_key -# Установка плагина
docker plugin install rexray/ebs \
EBS_REGION=us-east-1 \
LIBSTORAGE_LOGLEVEL=debug
# Создание volume с плагином
docker volume create \
--driver rexray/ebs \
--opt size=10 \
--opt type=gp3 \
ebs-volume
# Проверка плагинов
docker plugin ls# Volume с nocopy (данные не копируются из образа)
docker run -v \
type=volume,source=my-volume,target=/app/data,volume-nocopy=true \
myapp# 1. Хранение данных в слое образа
FROM ubuntu
RUN mkdir /data && echo "data" > /data/file.txt # ❌
# 2. Использование host paths в production
docker run -v /var/lib/mysql:/var/lib/mysql mysql # ❌
# 3. Игнорирование прав доступа
docker run -v $(pwd):/app myapp # Файлы будут root # ❌
# 4. Отсутствие бэкапов
docker run -v db-data:/var/lib/postgresql/data postgres # ❌ No backup plan
# 5. Использование anonymous volumes
docker run -v /var/lib/postgresql/data postgres # ❌ Неуправляемо# 1. Явное объявление volumes
VOLUME ["/data"]
RUN mkdir /data # ✅
# 2. Именованные volumes
docker volume create db-data
docker run -v db-data:/var/lib/postgresql/data postgres # ✅
# 3. Управление правами
docker run -u $(id -u):$(id -g) -v $(pwd):/app myapp # ✅
# 4. Регулярные бэкапы
0 2 * * * docker run --rm -v db-data:/data:ro -v $(pwd):/backup \
alpine tar czf /backup/db-$(date +\%F).tar.gz -C /data . # ✅
# 5. Read-only где возможно
docker run -v config:/app/config:ro myapp # ✅| Ошибка | Причина | Решение |
|---|---|---|
Permission denied | Несоответствие UID/GID | docker run -u $(id -u):$(id -g) |
Volume in use | Контейнер использует volume | docker ps --filter volume=name |
No space left | Volume заполнен | docker system df, очистка |
Mount point not found | Опечатка в пути | Проверить docker volume inspect |
Invalid mount config | Неправильный синтаксис | Использовать --mount вместо -v |
# Создание
docker volume create [OPTIONS] [VOLUME]
# Список
docker volume ls [OPTIONS]
docker volume ls -q # Только имена
# Информация
docker volume inspect VOLUME [VOLUME...]
docker volume ls --format "{{.Name}}: {{.Driver}}"
# Использование
docker volume prune [OPTIONS]
docker volume prune -a # Все неиспользуемые
docker volume prune --filter "label=env=dev"
# Удаление
docker volume rm VOLUME [VOLUME...]# Краткий синтаксис
docker run -v volume_name:/container/path[:options]
# Полный синтаксис
docker run --mount type=volume,source=volume_name,target=/container/path,readonly
# Типы: volume, bind, tmpfs| Опция | Описание |
|---|---|
:ro | Read-only |
:rw | Read-write (по умолчанию) |
:cached | Кэширование (macOS) |
:delegated | Делегирование (macOS) |
:consistent | Консистентность (macOS) |
:z | SELinux shared |
:Z | SELinux private |
Цель: Научиться использовать volumes для сохранения данных базы данных.
Задание:
# Создание volume
docker volume create postgres-data
# Запуск PostgreSQL
docker run -d \
--name postgres \
-e POSTGRES_USER=testuser \
-e POSTGRES_PASSWORD=testpass \
-e POSTGRES_DB=testdb \
-v postgres-data:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:15
# Подключение и создание данных
docker exec -it postgres psql -U testuser -d testdb -c \
"CREATE TABLE users (id serial PRIMARY KEY, name VARCHAR(100));"
docker exec -it postgres psql -U testuser -d testdb -c \
"INSERT INTO users (name) VALUES ('Alice'), ('Bob');"
# Проверка данных
docker exec -it postgres psql -U testuser -d testdb -c "SELECT * FROM users;"
# Удаление контейнера (volume сохраняется!)
docker rm -f postgres
# Создание нового контейнера с тем же volume
docker run -d \
--name postgres-new \
-e POSTGRES_USER=testuser \
-e POSTGRES_PASSWORD=testpass \
-e POSTGRES_DB=testdb \
-v postgres-data:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:15
# Проверка, что данные сохранились
docker exec -it postgres-new psql -U testuser -d testdb -c "SELECT * FROM users;"
# Очистка
docker rm -f postgres-newОжидаемый результат: Данные сохраняются после удаления контейнера и доступны в новом контейнере.
Цель: Научиться использовать bind mounts для разработки с авто-обновлением кода.
Задание:
# Создание директории с файлом
mkdir -p ./nginx-html
cat > ./nginx-html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Dev Server</title></head>
<body><h1>Hello from Bind Mount!</h1></body>
</html>
EOF
# Запуск nginx с bind mount
docker run -d \
--name nginx-dev \
-v $(pwd)/nginx-html:/usr/share/nginx/html:ro \
-p 8080:80 \
nginx:alpine
# Проверка
curl http://localhost:8080
# Изменение файла на хосте
cat > ./nginx-html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Dev Server v2</title></head>
<body><h1>Updated via Bind Mount!</h1></body>
</html>
EOF
# Проверка изменений (без перезапуска контейнера!)
curl http://localhost:8080
# Очистка
docker rm -f nginx-dev
rm -rf ./nginx-htmlОжидаемый результат: Изменения в HTML-файле сразу отражаются в браузере без пересборки образа.
Цель: Научиться создавать бэкапы volumes и восстанавливать данные.
Задание:
# Создание volume с данными
docker volume create backup-test
docker run --rm -v backup-test:/data alpine \
sh -c "echo 'Important data' > /data/file.txt && echo 'More data' > /data/file2.txt"
# Проверка данных
docker run --rm -v backup-test:/data alpine ls -la /data/
# Создание бэкапа
docker run --rm \
-v backup-test:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf /backup/backup.tar.gz -C /data .
# Проверка бэкапа
ls -la backup.tar.gz
tar tzf backup.tar.gz
# Удаление volume
docker volume rm backup-test
# Восстановление из бэкапа
docker volume create backup-test
docker run --rm \
-v backup-test:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/backup.tar.gz -C /data
# Проверка восстановления
docker run --rm -v backup-test:/data alpine cat /data/file.txt
# Очистка
docker volume rm backup-test
rm backup.tar.gzОжидаемый результат: Данные успешно восстанавливаются из бэкапа.
Цель: Научиться использовать tmpfs для хранения временных чувствительных данных.
Задание:
# Запуск с tmpfs
docker run -d \
--name tmpfs-secret \
--tmpfs /run/secrets:size=10m,mode=1777 \
alpine \
sleep 1000
# Запись секретных данных
docker exec tmpfs-secret sh -c "echo 'SUPER_SECRET_KEY=abc123' > /run/secrets/secret.key"
# Проверка
docker exec tmpfs-secret cat /run/secrets/secret.key
# Проверка, что файл не на диске
docker exec tmpfs-secret df -h /run/secrets
# Остановка контейнера
docker rm -f tmpfs-secret
# Проверка, что данные потеряны (контейнер удалён)
# Данные в tmpfs не сохраняются!Ожидаемый результат: Данные в tmpfs теряются после остановки контейнера, что обеспечивает безопасность.
Цель: Научиться монтировать volumes в read-only режиме для безопасности.
Задание:
# Создание volume с конфигом
docker volume create config-volume
docker run --rm -v config-volume:/config alpine \
sh -c "echo 'debug=false' > /config/app.conf"
# Монтирование в read-only режиме
docker run -it --rm \
-v config-volume:/config:ro \
alpine \
sh
# Внутри контейнера:
cat /config/app.conf # Чтение работает
echo 'debug=true' >> /config/app.conf # Ошибка: Read-only file system
exit
# Очистка
docker volume rm config-volumeОжидаемый результат: Чтение работает, запись заблокирована.
Цель: Научиться создавать NFS volumes для общих данных в кластере.
Требуется:
# Установка NFS сервера (для тестирования на Ubuntu)
sudo apt-get install nfs-kernel-server
# Создание экспорта
sudo mkdir -p /export/docker-volumes
sudo echo "/export/docker-volumes *(rw,sync,no_subtree_check,no_root_squash)" | \
sudo tee -a /etc/exports
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
# Создание NFS volume в Docker
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=$(hostname -I | awk '{print $1}'),rw,vers=4.1 \
--opt device=:/export/docker-volumes \
nfs-shared
# Проверка
docker run --rm -v nfs-shared:/data alpine \
sh -c "echo 'NFS test' > /data/test.txt && cat /data/test.txt"
# В Swarm режиме
docker service create \
--name nfs-test \
--mount type=volume,source=nfs-shared,target=/data \
--replicas 3 \
alpine sleep 1000
# Проверка на разных репликах
docker service logs nfs-testОжидаемый результат: Данные доступны на всех нодах кластера.
Цель: Настроить автоматическое резервное копирование volumes по расписанию.
# Создание скрипта бэкапа
cat > /usr/local/bin/docker-volume-backup.sh << 'EOF'
#!/bin/bash
set -e
VOLUME_NAME=$1
BACKUP_DIR=${2:-/backup/docker-volumes}
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${VOLUME_NAME}_${DATE}.tar.gz"
# Создание директории для бэкапов
mkdir -p "$BACKUP_DIR"
# Создание бэкапа
docker run --rm \
-v "${VOLUME_NAME}:/data:ro" \
-v "${BACKUP_DIR}:/backup" \
alpine \
tar czf "/backup/${VOLUME_NAME}_${DATE}.tar.gz" -C /data .
# Сжатие для экономии места
gzip -l "$BACKUP_FILE"
# Удаление старых бэкапов (старше 7 дней)
find "$BACKUP_DIR" -name "${VOLUME_NAME}_*.tar.gz" -mtime +7 -delete
echo "Backup completed: $BACKUP_FILE"
EOF
chmod +x /usr/local/bin/docker-volume-backup.sh
# Добавление в cron (ежедневно в 2:00)
echo "0 2 * * * /usr/local/bin/docker-volume-backup.sh postgres-data /backup" | \
sudo tee -a /etc/cron.d/docker-backup
# Тестовый запуск
sudo /usr/local/bin/docker-volume-backup.sh postgres-data /tmp/backups
# Проверка бэкапа
ls -lh /tmp/backups/
tar tzf /tmp/backups/postgres-data_*.tar.gz | headОжидаемый результат: Бэкапы создаются автоматически, старые удаляются.
Цель: Настроить мониторинг использования volumes с алертами.
# Создание docker-compose для мониторинга
cat > docker-compose.monitoring.yml << 'EOF'
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
grafana:
image: grafana/grafana:latest
volumes:
- grafana-data:/var/lib/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
depends_on:
- prometheus
node-exporter:
image: prom/node-exporter:latest
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
ports:
- "9100:9100"
volumes:
prometheus-data:
grafana-data:
EOF
# Конфигурация Prometheus
cat > prometheus.yml << 'EOF'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
rule_files:
- "alerts.yml"
EOF
# Правила алертинга
cat > alerts.yml << 'EOF'
groups:
- name: volume-alerts
rules:
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.15
for: 5m
labels:
severity: warning
annotations:
summary: "Мало места на диске"
description: "Свободно {{ $value | humanizePercentage }}"
EOF
# Запуск
docker-compose -f docker-compose.monitoring.yml up -d
# Проверка
curl http://localhost:9090/api/v1/targets
curl http://localhost:3000/api/healthОжидаемый результат: Grafana доступна на порту 3000, Prometheus собирает метрики.
Цель: Научиться шифровать чувствительные данные в volumes.
# Создание зашифрованного volume с dm-crypt
# Требуется: Linux с установленным cryptsetup
sudo apt-get install cryptsetup
# Создание файла для шифрования
dd if=/dev/zero of=/tmp/encrypted-volume.img bs=1M count=100
# Настройка шифрования
sudo cryptsetup luksFormat /tmp/encrypted-volume.img
sudo cryptsetup open /tmp/encrypted-volume.img encrypted_data
# Форматирование
sudo mkfs.ext4 /dev/mapper/encrypted_data
# Монтирование
sudo mount /dev/mapper/encrypted_data /mnt
# Создание volume
docker volume create \
--driver local \
--opt type=none \
--opt device=/mnt \
--opt o=bind \
encrypted-volume
# Использование
docker run -it --rm -v encrypted-volume:/data alpine \
sh -c "echo 'Secret data' > /data/secret.txt"
# Размонтирование
docker volume rm encrypted-volume
sudo umount /mnt
sudo cryptsetup close encrypted_dataАльтернатива с Docker Swarm secrets:
# Инициализация Swarm
docker swarm init
# Создание секрета
echo "my-super-secret-password" | docker secret create db_password -
# Использование в сервисе
docker service create \
--name postgres \
--secret db_password \
-e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
postgres:15
# Проверка
docker exec $(docker ps -q -f name=postgres) \
cat /run/secrets/db_passwordОжидаемый результат: Данные зашифрованы, доступ через secrets API.
Цель: Сравнить производительность различных типов монтирования.
# Скрипт для бенчмарка
cat > volume-benchmark.sh << 'EOF'
#!/bin/bash
echo "=== Docker Volume Benchmark ==="
echo ""
# Тест 1: Named volume
echo "1. Testing Named Volume..."
docker run --rm -v test-volume:/data alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=512 2>&1 | tail -1
docker volume rm test-volume
# Тест 2: Bind mount
echo "2. Testing Bind Mount..."
mkdir -p /tmp/docker-benchmark
docker run --rm -v /tmp/docker-benchmark:/data alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=512 2>&1 | tail -1
rm -rf /tmp/docker-benchmark
# Тест 3: tmpfs
echo "3. Testing tmpfs..."
docker run --rm --tmpfs /data:size=1g alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=512 2>&1 | tail -1
# Тест 4: tmpfs с ограничением
echo "4. Testing tmpfs (100MB limit)..."
docker run --rm --tmpfs /data:size=100m,mode=1777 alpine \
dd if=/dev/zero of=/data/testfile bs=1M count=50 2>&1 | tail -1
echo ""
echo "=== Benchmark Complete ==="
EOF
chmod +x volume-benchmark.sh
./volume-benchmark.sh
# Дополнительный тест: случайное чтение/запись
docker run --rm -v test-volume:/data alpine \
sh -c "
echo 'Random write test...'
for i in \$(seq 1 1000); do
echo \"data\$i\" > /data/file\$i.txt
done
echo 'Random read test...'
for i in \$(seq 1 1000); do
cat /data/file\$i.txt > /dev/null
done
echo 'Complete'
"
docker volume rm test-volumeОжидаемый результат: tmpfs показывает наилучшую производительность, bind mount зависит от ОС.
| Инструмент | Назначение |
|---|---|
| Portainer | Web UI для управления volumes |
| Lazydocker | TUI для мониторинга Docker |
| ctop | Top-like интерфейс для контейнеров |
| dive | Анализ слоёв Docker образов |
| trivy | Сканирование volumes на уязвимости |
# Быстрая проверка
docker system df -v # Детальное использование места
docker volume ls -q | wc -l # Количество volumes
docker volume prune -f # Очистка неиспользуемых
# Бэкап одной командой
docker run --rm -v vol:/data -v $(pwd):/backup alpine \
tar czf /backup/backup.tar.gz -C /data .
# Восстановление одной командой
docker run --rm -v vol:/data -v $(pwd):/backup alpine \
tar xzf /backup/backup.tar.gz -C /data
# Поиск больших файлов в volume
docker run --rm -v vol:/data alpine \
find /data -type f -exec du -h {} + | sort -rh | head -10
# Проверка mount points
docker inspect -f '{{range .Mounts}}{{printf "%s -> %s\n" .Source .Destination}}{{end}}' container_name:z и :Z?В следующей теме вы изучите Docker Compose для оркестрации многоконтейнерных приложений:
| Версия | Дата | Изменения |
|---|---|---|
| 2.0 | 2024-03 | Добавлены: архитектура, производительность, безопасность, Kubernetes, мониторинг |
| 1.0 | 2023-01 | Базовая версия: volumes, bind mounts, tmpfs |
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.