Linux运维5 min read

Docker 容器化运维实战

为什么需要容器化

传统运维面临的最大痛点之一是环境一致性。开发环境正常、测试环境异常、生产环境崩溃——这类问题几乎每个运维都遇到过。Docker 通过将应用及其依赖打包成一个标准化的容器,从根本上解决了这个问题。

Docker 核心概念速览

概念 类比 说明
镜像 (Image) 类 (Class) 容器的模板,定义了运行环境
容器 (Container) 实例 (Instance) 镜像的运行实例,相互隔离
仓库 (Registry) GitHub 存放和分发镜像的地方
Dockerfile Makefile 定义镜像构建步骤的脚本

Dockerfile 最佳实践

# 1. 使用官方精简镜像作为基础
FROM node:20-alpine AS builder

# 2. 设置工作目录
WORKDIR /app

# 3. 利用缓存层:先复制依赖文件
COPY package*.json ./
RUN npm ci --only=production

# 4. 再复制源代码
COPY . .

# 5. 多阶段构建减小镜像体积
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist

# 6. 使用非 root 用户运行
RUN addgroup -g 1001 -S app && adduser -S app -u 1001 -G app
USER app

# 7. 声明端口
EXPOSE 3000

# 8. 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

CMD ["node", "dist/server.js"]

网络模式深入

Docker 提供五种网络驱动,各有用武之地:

# 1. bridge (默认) — 单机容器互联
docker network create --driver bridge my-bridge
docker run -d --network my-bridge --name app1 nginx

# 2. host — 直接使用宿主机网络(性能最佳,无隔离)
docker run -d --network host nginx

# 3. overlay — 跨主机容器通信(Swarm/K8s 场景)
docker network create -d overlay my-overlay

# 4. macvlan — 容器分配独立 MAC 地址(传统网络对接)
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 my-macvlan

# 5. none — 完全隔离,手动配置
docker run -d --network none alpine

数据卷管理

# 具名卷(推荐,Docker 管理)
docker volume create app-data
docker run -v app-data:/data nginx

# 绑定挂载(开发环境)
docker run -v $(pwd)/logs:/var/log/nginx nginx

# tmpfs(敏感数据,仅内存)
docker run --tmpfs /tmp nginx

# 备份数据卷
docker run --rm -v app-data:/source -v $(pwd):/backup alpine \
  tar czf /backup/app-data-$(date +%Y%m%d).tar.gz -C /source .

docker-compose 生产级编排

version: '3.8'
services:
  web:
    build: .
    ports:
      - "8080:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  db:
    image: mysql:8.0
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: app_prod
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  db-data:

生产环境检查清单

  1. 镜像安全扫描docker scan <image> 或使用 Trivy
  2. 资源限制:必须设置 CPU/内存上限,防止单个容器拖垮宿主机
  3. 日志轮转:配置 max-sizemax-file,避免磁盘写满
  4. 非 root 运行:安全性基本原则
  5. 健康检查:配合编排工具实现自愈
  6. 只读根文件系统--read-only 防止容器被篡改
  7. 密钥管理:使用 Docker Secrets 或外部 Vault

常用运维命令速查

# 清理无用的镜像/容器/卷/网络
docker system prune -a --volumes

# 查看容器资源使用
docker stats --no-stream

# 查看容器日志(带时间戳)
docker logs -f --tail 100 --timestamps <container>

# 进入运行中的容器
docker exec -it <container> sh

# 查看镜像层历史
docker history --no-trunc <image>

# 从容器创建镜像(用于排查)
docker commit <container> debug-image
docker run -it debug-image sh

核心原则:容器是无状态的,有状态的数据必须持久化到卷中。不要依赖容器的文件系统来存储重要数据。

分享:

相关文章