第十四章:Docker Compose 部署

通过 Docker Compose 快速部署 MinIO 单机和分布式集群,以及相关配套服务。

最后更新: 2024-01-15
页面目录

第十四章:Docker Compose 部署

14.1 单机部署

14.1.1 基本单机部署

# docker-compose.yml
version: '3.8'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"   # API 端口
      - "9001:9001"   # Console 端口
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio-data:/data
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3
    restart: unless-stopped

volumes:
  minio-data:
    driver: local
# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f minio

# 访问服务
# API: http://localhost:9000
# Console: http://localhost:9001

14.1.2 带 TLS 的部署

# docker-compose-tls.yml
version: '3.8'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio-data:/data
      - ./certs:/root/.minio/certs:ro
    command: server /data --console-address ":9001"
    restart: unless-stopped

volumes:
  minio-data:
    driver: local

14.2 分布式部署

14.2.1 四节点分布式

# docker-compose-distributed.yml
version: '3.8'

services:
  minio1:
    image: minio/minio:latest
    container_name: minio1
    hostname: minio1
    ports:
      - "9001:9000"
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio1-data:/data/minio
    command: server http://minio{1...4}/data/minio --console-address ":9000"
    networks:
      minio-net:
        ipv4_address: 172.20.0.11

  minio2:
    image: minio/minio:latest
    container_name: minio2
    hostname: minio2
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio2-data:/data/minio
    command: server http://minio{1...4}/data/minio --console-address ":9000"
    networks:
      minio-net:
        ipv4_address: 172.20.0.12

  minio3:
    image: minio/minio:latest
    container_name: minio3
    hostname: minio3
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio3-data:/data/minio
    command: server http://minio{1...4}/data/minio --console-address ":9000"
    networks:
      minio-net:
        ipv4_address: 172.20.0.13

  minio4:
    image: minio/minio:latest
    container_name: minio4
    hostname: minio4
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio4-data:/data/minio
    command: server http://minio{1...4}/data/minio --console-address ":9000"
    networks:
      minio-net:
        ipv4_address: 172.20.0.14

networks:
  minio-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24

volumes:
  minio1-data:
  minio2-data:
  minio3-data:
  minio4-data:
# 启动分布式集群
docker-compose -f docker-compose-distributed.yml up -d

# 检查集群状态
docker exec minio1 mc admin info myminio

14.3 带监控的部署

14.3.1 完整监控栈

# docker-compose-full.yml
version: '3.8'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio-data:/data
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      retries: 3
    restart: unless-stopped
    networks:
      - minio-net

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    restart: unless-stopped
    networks:
      - minio-net
    depends_on:
      - minio

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin123
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    restart: unless-stopped
    networks:
      - minio-net
    depends_on:
      - prometheus

networks:
  minio-net:
    driver: bridge

volumes:
  minio-data:
  prometheus-data:
  grafana-data:

14.3.2 Prometheus 配置

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'minio'
    static_configs:
      - targets: ['minio:9000']
    metrics_path: /minio/v2/metrics/cluster

14.4 带备份的部署

14.4.1 本地备份

# docker-compose-backup.yml
version: '3.8'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio-data:/data
    command: server /data --console-address ":9001"
    restart: unless-stopped

  minio-backup:
    image: minio/mc:latest
    container_name: minio-backup
    depends_on:
      - minio
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - ./backup.sh:/backup.sh:ro
      - backup-data:/backup
    entrypoint: ["/bin/sh", "-c", "sleep infinity"]

  backup-cron:
    image: alpine:latest
    container_name: backup-cron
    depends_on:
      - minio
    volumes:
      - ./backup.sh:/backup.sh:ro
      - ./backup-data:/backup
    entrypoint: ["/bin/sh", "-c", "while true; do /backup.sh; sleep 86400; done"]

volumes:
  minio-data:
  backup-data:

14.4.2 备份脚本

#!/bin/bash
# backup.sh

ALIAS="backup"
SOURCE_BUCKET="production"
BACKUP_DIR="/backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 配置别名
mc alias set $ALIAS http://minio:9000 admin password123

# 创建备份目录
mkdir -p $BACKUP_DIR/$TIMESTAMP

# 备份数据
echo "Starting backup at $TIMESTAMP"
mc mirror $ALIAS/$SOURCE_BUCKET $BACKUP_DIR/$TIMESTAMP/

# 清理 7 天前的备份
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;

echo "Backup completed: $BACKUP_DIR/$TIMESTAMP"

14.5 带 Nginx 的部署

14.5.1 Nginx 反向代理

# docker-compose-nginx.yml
version: '3.8'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - minio-data:/data
    command: server /data
    restart: unless-stopped
    networks:
      - minio-net

  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - minio
    restart: unless-stopped
    networks:
      - minio-net

networks:
  minio-net:
    driver: bridge

volumes:
  minio-data:

14.5.2 Nginx 配置

# nginx.conf
events {
    worker_connections 1024;
}

http {
    upstream minio_api {
        server minio:9000;
    }

    upstream minio_console {
        server minio:9001;
    }

    server {
        listen 80;
        server_name minio.example.com;

        # 重定向到 HTTPS
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name minio.example.com;

        ssl_certificate /etc/nginx/certs/minio.crt;
        ssl_certificate_key /etc/nginx/certs/minio.key;

        # API 代理
        location / {
            proxy_pass http://minio_api;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            client_max_body_size 10G;
        }

        # Console 代理
        location /console {
            proxy_pass http://minio_console;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

14.6 Kubernetes 部署

14.6.1 MinIO Operator

# 安装 MinIO Operator
kubectl apply -k github.com/minio/operator

# 检查 Operator 状态
kubectl get pods -n minio-operator

14.6.2 Tenant 配置

# minio-tenant.yaml
apiVersion: minio.min.io/v4
kind: Tenant
metadata:
  name: minio-tenant
  namespace: minio-tenant
spec:
  image: minio/minio:RELEASE.2024-01-01
  pools:
    - servers: 4
      volumesPerServer: 4
      volumeClaimTemplate:
        metadata:
          name: data
        spec:
          accessModes: [ReadWriteOnce]
          resources:
            requests:
              storage: 10Gi
  env:
    - name: MINIO_ROOT_USER
      value: admin
    - name: MINIO_ROOT_PASSWORD
      value: password123
  exposeServices:
    console: true
    minio: true
# 部署 Tenant
kubectl apply -f minio-tenant.yaml

# 查看状态
kubectl get tenants -n minio-tenant

14.7 运维命令

14.7.1 日常维护

# 查看容器状态
docker-compose ps

# 查看日志
docker-compose logs -f minio

# 重启服务
docker-compose restart minio

# 停止服务
docker-compose down

# 完全清理
docker-compose down -v

14.7.2 扩容

# 添加新节点到集群
# 1. 编辑 docker-compose.yml 添加新节点
# 2. 更新 command 中的节点列表
# 3. 重启集群
docker-compose up -d

14.8 总结

本章介绍了使用 Docker Compose 部署 MinIO 的多种方式,包括单机部署、分布式部署、带监控和备份的部署方案。Docker Compose 是开发和测试环境的理想选择,生产环境建议使用 Kubernetes 部署。