🌺The Begin🌺点点关注,收藏不迷路🌺

引言:为什么需要学习Docker数据管理?

在Docker生态系统中,容器默认是无状态的——这意味着容器停止后,其内部产生的所有数据都会丢失。但在实际生产环境中,我们需要持久化存储数据、实现容器间通信、以及在私有环境中安全地管理镜像。本文将深入探讨Docker的三大核心主题:数据管理容器链接私有仓库构建

第一部分:Docker数据管理深度解析

1.1 Docker数据管理的三种方式

1.1.1 Bind Mounts(绑定挂载)

将主机文件系统的目录或文件直接挂载到容器中

# 基本语法
docker run -v /host/path:/container/path image_name

# 实际示例:挂载当前目录到容器的/app目录
docker run -d \
  --name webapp \
  -v $(pwd):/app \
  -p 8080:80 \
  nginx:alpine

# 挂载单个文件(适用于配置文件)
docker run -d \
  --name mysql-custom \
  -v /etc/mysql/my.cnf:/etc/mysql/my.cnf \
  mysql:8.0

# 权限控制:设置挂载目录的读写权限
docker run -d \
  --name redis \
  -v /data/redis:/data:rw \
  redis:6.0

# 只读挂载(增强安全性)
docker run -d \
  --name readonly-app \
  -v /config:/app/config:ro \
  myapp:latest
1.1.2 Volumes(数据卷)

由Docker管理的存储卷,存储在主机文件系统的特定区域(通常在/var/lib/docker/volumes/

# 创建数据卷
docker volume create mydata

# 查看数据卷详细信息
docker volume inspect mydata

# 使用数据卷
docker run -d \
  --name db \
  -v mydata:/var/lib/mysql \
  mysql:8.0

# 匿名数据卷(不指定名称)
docker run -d \
  --name app \
  -v /app/data \
  myapp:latest

# 多容器共享数据卷
# 创建数据卷
docker volume create shared-data

# 容器1:写入数据
docker run -d \
  --name producer \
  -v shared-data:/data \
  alpine sh -c "echo 'Hello from producer' > /data/message.txt"

# 容器2:读取数据
docker run --rm \
  --name consumer \
  -v shared-data:/data \
  alpine cat /data/message.txt

# 清理未使用的数据卷
docker volume prune
1.1.3 tmpfs mounts(临时文件系统)

将数据存储在内存中,不写入磁盘,适用于敏感信息

# 使用tmpfs挂载
docker run -d \
  --name tmpfs-app \
  --tmpfs /app/cache:size=100m,mode=1777 \
  myapp:latest

# 更详细的tmpfs配置
docker run -d \
  --name secure-app \
  --mount type=tmpfs,destination=/tmp,tmpfs-size=500m,tmpfs-mode=1777 \
  myapp:latest

1.2 数据管理最佳实践

#!/bin/bash
# 数据管理自动化脚本示例

# 1. 备份数据卷
backup_volume() {
    local VOLUME_NAME=$1
    local BACKUP_DIR=$2
    
    echo "正在备份数据卷: $VOLUME_NAME"
    docker run --rm \
      -v $VOLUME_NAME:/data \
      -v $BACKUP_DIR:/backup \
      alpine tar czf /backup/${VOLUME_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .
    
    echo "备份完成: $BACKUP_DIR/${VOLUME_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz"
}

# 2. 恢复数据卷
restore_volume() {
    local VOLUME_NAME=$1
    local BACKUP_FILE=$2
    
    echo "正在恢复数据卷: $VOLUME_NAME"
    docker volume create $VOLUME_NAME
    docker run --rm \
      -v $VOLUME_NAME:/data \
      -v $(dirname $BACKUP_FILE):/backup \
      alpine tar xzf /backup/$(basename $BACKUP_FILE) -C /data
    
    echo "恢复完成"
}

# 3. 迁移数据卷
migrate_volume() {
    local SOURCE_VOLUME=$1
    local TARGET_VOLUME=$2
    
    echo "正在迁移数据卷: $SOURCE_VOLUME -> $TARGET_VOLUME"
    docker volume create $TARGET_VOLUME
    docker run --rm \
      -v $SOURCE_VOLUME:/source \
      -v $TARGET_VOLUME:/target \
      alpine sh -c "cp -a /source/. /target/"
    
    echo "迁移完成"
}

# 使用示例
# backup_volume "mydb_data" "/backups"
# restore_volume "mydb_data" "/backups/mydb_data_20231015_143000.tar.gz"

1.3 性能对比与选择建议

存储方式性能可移植性安全性适用场景
Bind Mounts低(依赖主机路径)开发环境、配置文件
Volumes中高生产环境、数据持久化
tmpfs极高极高临时文件、敏感数据

选择指南

  • 开发环境:优先使用Bind Mounts,便于代码热更新
  • 生产环境:优先使用Volumes,保证数据安全和可移植性
  • 敏感数据:使用tmpfs或加密的Volumes

第二部分:容器互联与网络通信

2.1 传统的容器链接(Legacy Links)

# 创建源容器(提供连接)
docker run -d \
  --name database \
  -e MYSQL_ROOT_PASSWORD=secret \
  mysql:8.0

# 创建客户端容器并链接
docker run -d \
  --name webapp \
  --link database:db \
  -p 8080:80 \
  wordpress:latest

# 验证链接
docker exec webapp env | grep DB_
# 会显示类似:DB_PORT=tcp://172.17.0.2:3306
#              DB_NAME=/webapp/db

# 已弃用警告:Docker已弃用--link,推荐使用用户定义网络

2.2 现代网络方案:用户定义网络

2.2.1 创建和管理网络
# 创建自定义网络
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  my-network

# 查看网络详情
docker network inspect my-network

# 创建多个隔离的网络
docker network create frontend
docker network create backend
docker network create database

# 连接容器到网络
docker network connect frontend webapp
docker network connect backend webapp
docker network connect database mysql

# 断开网络连接
docker network disconnect frontend webapp
2.2.2 多容器应用部署示例
# docker-compose.yml示例
version: '3.8'

networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.22.0.0/16

services:
  # 数据库服务
  database:
    image: postgres:14
    container_name: postgres-db
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret123
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis缓存服务
  redis:
    image: redis:7-alpine
    container_name: redis-cache
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app-network
    ports:
      - "6379:6379"

  # 后端应用
  backend:
    build: ./backend
    container_name: app-backend
    environment:
      DATABASE_URL: postgres://admin:secret123@postgres-db:5432/myapp
      REDIS_URL: redis://redis-cache:6379
    depends_on:
      database:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - app-network
    ports:
      - "3000:3000"

  # 前端应用
  frontend:
    build: ./frontend
    container_name: app-frontend
    environment:
      API_URL: http://backend:3000
    depends_on:
      - backend
    networks:
      - app-network
    ports:
      - "80:80"
      - "443:443"

  # 监控服务
  monitoring:
    image: grafana/grafana:latest
    container_name: grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - app-network
    ports:
      - "3001:3000"

volumes:
  postgres_data:
  redis_data:
  grafana_data:

2.3 网络配置高级技巧

# 1. 设置自定义DNS
docker run -d \
  --name dns-test \
  --dns 8.8.8.8 \
  --dns-search example.com \
  nginx:alpine

# 2. 配置容器主机名
docker run -d \
  --name custom-host \
  --hostname myapp.dev.internal \
  --network my-network \
  nginx:alpine

# 3. 端口映射高级用法
# 随机映射端口
docker run -d -P nginx:alpine

# 指定IP绑定
docker run -d \
  --name web \
  -p 127.0.0.1:8080:80 \
  nginx:alpine

# IPv6支持
docker run -d \
  --name ipv6-test \
  -p [::]:8080:80 \
  nginx:alpine

# 4. 网络别名(替代--link)
docker network create app-net
docker run -d \
  --name db \
  --network app-net \
  --network-alias database \
  --network-alias mysql \
  mysql:8.0

docker run -d \
  --name app \
  --network app-net \
  nginx:alpine

# 在app容器内,可以通过database或mysql主机名访问db容器
docker exec app ping database
docker exec app ping mysql

2.4 网络故障排查

# 网络诊断工具集
#!/bin/bash
# network-diagnostics.sh

echo "=== Docker网络诊断 ==="

# 1. 查看所有网络
echo "1. 当前网络列表:"
docker network ls

# 2. 查看特定网络详情
echo -e "\n2. 网络详情:"
read -p "输入网络名称(默认bridge): " NETWORK_NAME
NETWORK_NAME=${NETWORK_NAME:-bridge}
docker network inspect $NETWORK_NAME | jq '.[] | {Name, Driver, IPAM, Containers: .Containers | length}'

# 3. 检查容器网络
echo -e "\n3. 容器网络配置:"
docker ps --format "table {{.Names}}\t{{.Ports}}"

# 4. 测试容器间连通性
echo -e "\n4. 网络连通性测试:"
read -p "输入源容器名: " SOURCE_CONTAINER
read -p "输入目标容器名或IP: " TARGET

echo "从 $SOURCE_CONTAINER 测试连接到 $TARGET..."
docker exec $SOURCE_CONTAINER ping -c 4 $TARGET 2>/dev/null || \
  echo "无法连接,检查网络配置"

# 5. 查看容器DNS配置
echo -e "\n5. DNS配置:"
docker exec $SOURCE_CONTAINER cat /etc/resolv.conf

# 6. 网络流量分析
echo -e "\n6. 安装网络工具:"
docker exec $SOURCE_CONTAINER sh -c "
  if command -v apt-get &> /dev/null; then
    apt-get update && apt-get install -y iproute2 net-tools tcpdump curl
  elif command -v apk &> /dev/null; then
    apk add iproute2 net-tools tcpdump curl
  fi" 2>/dev/null

echo "诊断完成"

第三部分:构建私有Docker仓库

3.1 使用Docker Registry官方镜像

3.1.1 快速启动基础Registry
# 1. 拉取Registry镜像
docker pull registry:2

# 2. 运行基础Registry(无认证)
docker run -d \
  --name private-registry \
  -p 5000:5000 \
  -v registry-data:/var/lib/registry \
  registry:2

# 3. 测试Registry
curl http://localhost:5000/v2/_catalog

# 4. 推送镜像到私有仓库
# 标记镜像
docker tag nginx:alpine localhost:5000/my-nginx:v1

# 推送镜像
docker push localhost:5000/my-nginx:v1

# 5. 从私有仓库拉取镜像
docker pull localhost:5000/my-nginx:v1
3.1.2 生产级Registry配置
# 创建配置目录
mkdir -p /opt/docker-registry/{auth,certs,data}

# 生成SSL证书(自签名)
openssl req -newkey rsa:4096 -nodes -sha256 \
  -keyout /opt/docker-registry/certs/domain.key \
  -x509 -days 365 \
  -out /opt/docker-registry/certs/domain.crt \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=registry.mycompany.com"

# 创建认证文件(使用htpasswd)
docker run --rm \
  --entrypoint htpasswd \
  httpd:2 -Bbn admin securepassword > /opt/docker-registry/auth/htpasswd

# 启动带认证和HTTPS的Registry
docker run -d \
  --name secure-registry \
  -p 443:5000 \
  -v /opt/docker-registry/data:/var/lib/registry \
  -v /opt/docker-registry/auth:/auth \
  -v /opt/docker-registry/certs:/certs \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

3.2 配置Docker客户端访问私有仓库

# 1. 配置Docker守护进程(适用于自签名证书)
# 复制证书到Docker信任目录
sudo mkdir -p /etc/docker/certs.d/registry.mycompany.com
sudo cp /opt/docker-registry/certs/domain.crt /etc/docker/certs.d/registry.mycompany.com/ca.crt

# 重启Docker服务
sudo systemctl restart docker

# 2. 登录私有仓库
docker login registry.mycompany.com
# 输入用户名:admin
# 输入密码:securepassword

# 3. 使用私有仓库
docker tag nginx:alpine registry.mycompany.com/my-team/nginx:latest
docker push registry.mycompany.com/my-team/nginx:latest

# 4. 配置镜像加速器和私有仓库(daemon.json)
sudo tee /etc/docker/daemon.json << EOF
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ],
  "insecure-registries": [
    "192.168.1.100:5000"
  ],
  "registry-mirror": "https://registry.mycompany.com"
}
EOF

3.3 使用Harbor企业级Registry

3.3.1 Harbor安装与配置
# 1. 下载Harbor离线安装包
wget https://github.com/goharbor/harbor/releases/download/v2.7.0/harbor-offline-installer-v2.7.0.tgz
tar xzf harbor-offline-installer-v2.7.0.tgz
cd harbor

# 2. 修改配置文件
cp harbor.yml.tmpl harbor.yml
vim harbor.yml

# 修改关键配置
hostname: registry.mycompany.com
https:
  port: 443
  certificate: /data/cert/domain.crt
  private_key: /data/cert/domain.key
harbor_admin_password: Harbor12345
database:
  password: root123
data_volume: /data/harbor

# 3. 运行安装脚本
./install.sh --with-trivy --with-chartmuseum

# 4. 访问Harbor Web界面
# https://registry.mycompany.com
# 用户:admin
# 密码:Harbor12345
3.3.2 Harbor高级功能配置
# harbor.yml 高级配置示例
# 复制策略
replication:
  # 启用复制功能
  enabled: true
  # 复制策略
  policies:
    - name: "sync-to-cloud"
      description: "同步到云仓库"
      filters:
        - kind: "resource"
          value: "repository"
        - kind: "name"
          value: "library/.*"
        - kind: "tag"
          value: ".*"
      trigger:
        type: "scheduled"
        settings:
          cron: "0 0 * * *"
      deletion: false
      dest_namespaces:
        - cloud-registry

# 漏洞扫描
trivy:
  ignore_unfixed: false
  severity: critical,high,medium,low
  insecure: false
  skip_update: false

# 保留策略
retention:
  dry_run: false
  rules:
    - repositories:
        - "**"
      tag_selectors:
        - kind: "regularExpression"
          pattern: ".*"
      keep_most_recent: 10
      keep_days: 30

# Webhook通知
notification:
  webhook:
    - name: "slack-notification"
      enabled: true
      endpoint: "https://hooks.slack.com/services/xxx/yyy/zzz"
      events:
        - pushImage
        - deleteImage
        - scanCompleted

3.4 私有仓库运维与监控

#!/bin/bash
# registry-maintenance.sh

set -e

REGISTRY_URL="registry.mycompany.com"
BACKUP_DIR="/backup/registry"
LOG_FILE="/var/log/registry-maintenance.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 1. 备份Registry数据
backup_registry() {
    log "开始备份Registry数据..."
    
    # 停止Registry容器
    docker stop private-registry 2>/dev/null || true
    
    # 创建备份目录
    BACKUP_PATH="$BACKUP_DIR/$(date +%Y%m%d_%H%M%S)"
    mkdir -p $BACKUP_PATH
    
    # 备份数据卷
    docker run --rm \
      -v registry-data:/source \
      -v $BACKUP_PATH:/backup \
      alpine tar czf /backup/registry-data.tar.gz -C /source .
    
    # 备份配置文件
    cp /opt/docker-registry/{auth,certs}/* $BACKUP_PATH/ 2>/dev/null || true
    
    # 启动Registry容器
    docker start private-registry
    
    log "备份完成: $BACKUP_PATH"
    
    # 清理旧备份(保留最近7天)
    find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;
}

# 2. Registry垃圾回收
garbage_collect() {
    log "开始Registry垃圾回收..."
    
    # 进入Registry容器执行垃圾回收
    docker exec private-registry registry garbage-collect \
      --delete-untagged=true /etc/docker/registry/config.yml
    
    log "垃圾回收完成"
}

# 3. 镜像清理策略
cleanup_images() {
    log "开始清理旧镜像..."
    
    # 安装并配置registry-cli
    pip install registry-cli
    
    # 删除30天前的未标签镜像
    registry-cli -r $REGISTRY_URL -l admin -p password \
      delete --untagged --older-than 30d
    
    # 保留每个仓库最新的10个标签
    registry-cli -r $REGISTRY_URL -l admin -p password \
      delete --num 10 --dry-run  # 先预览
    
    log "镜像清理完成"
}

# 4. 健康检查
health_check() {
    log "执行Registry健康检查..."
    
    # 检查服务状态
    if curl -s -f "https://$REGISTRY_URL/v2/_catalog" > /dev/null; then
        log "✓ Registry服务运行正常"
        
        # 检查磁盘空间
        DISK_USAGE=$(df -h /var/lib/docker | tail -1 | awk '{print $5}')
        log "磁盘使用率: $DISK_USAGE"
        
        # 检查镜像数量
        IMAGE_COUNT=$(curl -s "https://$REGISTRY_URL/v2/_catalog" | jq '.repositories | length')
        log "仓库镜像数量: $IMAGE_COUNT"
    else
        log "✗ Registry服务异常"
        # 发送告警
        send_alert "Registry服务异常"
    fi
}

# 5. 发送告警
send_alert() {
    local message=$1
    # 这里可以实现邮件、Slack、Webhook等告警方式
    echo "ALERT: $message" >> $LOG_FILE
    
    # 示例:发送Slack通知
    # curl -X POST -H 'Content-type: application/json' \
    #   --data "{\"text\":\"$message\"}" \
    #   https://hooks.slack.com/services/xxx/yyy/zzz
}

# 主程序
main() {
    case $1 in
        "backup")
            backup_registry
            ;;
        "gc")
            garbage_collect
            ;;
        "cleanup")
            cleanup_images
            ;;
        "health")
            health_check
            ;;
        "all")
            health_check
            backup_registry
            garbage_collect
            cleanup_images
            ;;
        *)
            echo "用法: $0 {backup|gc|cleanup|health|all}"
            exit 1
            ;;
    esac
}

main "$@"

3.5 私有仓库安全最佳实践

# Docker Content Trust (DCT) 配置
# 启用镜像签名验证

# 1. 启用Docker Content Trust
export DOCKER_CONTENT_TRUST=1

# 2. 初始化镜像签名密钥
docker trust key generate my-signer
docker trust signer add --key my-signer.pub my-signer registry.mycompany.com/library/myapp

# 3. 推送已签名的镜像
docker trust sign registry.mycompany.com/library/myapp:1.0.0

# 4. 拉取时验证签名(自动)
docker pull registry.mycompany.com/library/myapp:1.0.0

# 5. 查看镜像签名信息
docker trust inspect --pretty registry.mycompany.com/library/myapp:1.0.0

第四部分:综合实战案例

4.1 完整的企业级应用部署

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

# 定义网络
networks:
  front-tier:
    driver: overlay
    attachable: true
  back-tier:
    driver: overlay
    internal: true  # 内部网络,不对外暴露
  monitoring:
    driver: overlay

# 定义数据卷
volumes:
  postgres_data:
    driver: local
    driver_opts:
      type: nfs
      o: addr=nfs-server.mycompany.com,rw
      device: ":/exports/postgres"
  redis_data:
    driver: local
  elasticsearch_data:
    driver: local

# 定义配置
configs:
  nginx_config:
    file: ./nginx/nginx.conf
  app_config:
    file: ./config/app.prod.yml

# 定义密钥
secrets:
  db_password:
    external: true
  ssl_cert:
    file: ./secrets/ssl_cert.pem
  ssl_key:
    file: ./secrets/ssl_key.pem

services:
  # 负载均衡器
  traefik:
    image: traefik:v2.10
    container_name: traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard
    networks:
      - front-tier
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml
      - ./traefik/config:/etc/traefik/config
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    deploy:
      mode: replicated
      replicas: 2
      placement:
        constraints:
          - node.role == manager

  # 主应用服务
  webapp:
    image: registry.mycompany.com/myapp/webapp:${WEBAPP_VERSION:-latest}
    container_name: webapp
    networks:
      - front-tier
      - back-tier
    depends_on:
      - database
      - redis
      - elasticsearch
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:${DB_PASSWORD}@database:5432/myapp
      - REDIS_URL=redis://redis:6379
      - ELASTICSEARCH_HOSTS=elasticsearch:9200
    secrets:
      - db_password
    configs:
      - source: app_config
        target: /app/config.yml
    deploy:
      mode: replicated
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.mycompany.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls=true"
      - "traefik.http.services.webapp.loadbalancer.server.port=3000"

  # 数据库服务
  database:
    image: postgres:14-alpine
    container_name: postgres-db
    networks:
      - back-tier
    environment:
      POSTGRES_USER: user
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.labels.db == true
      resources:
        limits:
          cpus: '2'
          memory: 4G
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis缓存
  redis:
    image: redis:7-alpine
    container_name: redis-cache
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    networks:
      - back-tier
    volumes:
      - redis_data:/data
    deploy:
      mode: replicated
      replicas: 2
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]

  # Elasticsearch
  elasticsearch:
    image: elasticsearch:8.9.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    networks:
      - back-tier
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    deploy:
      resources:
        limits:
          memory: 1G
    ulimits:
      memlock:
        soft: -1
        hard: -1

  # 监控栈
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    networks:
      - monitoring
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
    deploy:
      placement:
        constraints:
          - node.role == manager

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    networks:
      - monitoring
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    depends_on:
      - prometheus
    deploy:
      placement:
        constraints:
          - node.role == manager

# 部署命令
# docker stack deploy -c docker-compose.prod.yml myapp

总结与最佳实践

关键要点总结:

  1. 数据管理

    • 开发环境使用Bind Mounts,生产环境使用Volumes
    • 敏感数据使用tmpfs或加密Volumes
    • 定期备份数据卷,实现灾难恢复
  2. 容器互联

    • 避免使用已弃用的–link参数
    • 使用用户定义网络实现服务发现
    • 合理规划网络拓扑,隔离不同服务
  3. 私有仓库

    • 开发测试使用简单Registry,生产环境使用Harbor
    • 实施镜像签名和漏洞扫描
    • 配置合理的镜像保留策略

推荐工具链:

用途推荐工具说明
本地开发Docker Desktop一体化开发环境
生产编排Docker Swarm / Kubernetes容器编排
私有仓库Harbor企业级Registry
镜像扫描Trivy / Clair安全扫描
网络监控Weave Scope / cAdvisor容器网络可视化
日志管理ELK Stack / Loki集中式日志

下一步学习建议:

  1. 深入学习Docker安全

    # 安全扫描工具
    docker scan myimage:latest
    docker run --rm aquasec/trivy image myimage:latest
    
  2. 探索容器编排

    # Docker Swarm
    docker swarm init
    docker stack deploy -c docker-compose.yml myapp
    
    # Kubernetes基础
    minikube start
    kubectl apply -f deployment.yaml
    
  3. CI/CD集成

    • 在Jenkins/GitLab CI中集成Docker构建
    • 实现自动化的镜像构建和部署流水线

在这里插入图片描述


🌺The End🌺点点关注,收藏不迷路🌺

更多推荐