Docker完整实践指南
目录
- 概述
- Docker核心概念
- Docker安装与配置
- Dockerfile最佳实践
- Docker镜像管理
- Docker网络配置
- Docker存储管理
- Docker Compose实践
- Docker安全实践
- Docker监控与调试
- 生产环境最佳实践
概述
Docker是目前最流行的容器化平台,它通过提供简单易用的工具和API,使开发人员能够快速构建、打包、分发和运行应用程序。本指南详细介绍Docker的核心概念、基本操作、高级特性和最佳实践,帮助开发人员和运维人员掌握Docker的使用技巧,提高应用交付和管理效率。
Docker核心概念
基础概念
- 镜像(Image):一个只读的模板,包含运行应用所需的所有内容(代码、运行时、库、环境变量和配置文件等)
- 容器(Container):镜像的运行实例,可以看作是一个轻量级的沙箱环境
- 仓库(Repository):存储和分发Docker镜像的场所
- Dockerfile:定义如何构建Docker镜像的文本文件
- Docker Engine:运行Docker容器的核心组件,包括Docker守护进程、REST API和命令行界面
- Docker Compose:用于定义和运行多容器Docker应用的工具
- Docker Swarm:Docker原生的容器编排工具
Docker架构
┌─────────────────────────────────────────────────────────┐
│ Docker架构 │
├─────────────────────────────────────────────────────────┤
│ Docker Client (docker命令) │
│ ↓ │
│ Docker Daemon (dockerd) │
│ ↓ │
│ Containerd (容器运行时) │
│ ↓ │
│ runc (底层容器运行时) │
│ ↓ │
│ Linux Kernel (命名空间、cgroups、联合文件系统) │
└─────────────────────────────────────────────────────────┘
Docker安装与配置
在不同操作系统上安装Docker
Ubuntu/Debian
# 更新包索引
sudo apt-get update
# 安装必要的依赖包
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加Docker仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 更新包索引并安装Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
docker --version
docker run hello-world
CentOS/RHEL
# 安装必要的依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
docker --version
docker run hello-world
macOS
# 使用Homebrew安装
brew install --cask docker
# 或者下载Docker Desktop for Mac
# https://www.docker.com/products/docker-desktop
Windows
# 使用Chocolatey安装
choco install docker-desktop
# 或者下载Docker Desktop for Windows
# https://www.docker.com/products/docker-desktop
Docker配置优化
1. 配置Docker守护进程
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"data-root": "/var/lib/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"userland-proxy": false,
"experimental": false,
"metrics-addr": "127.0.0.1:9323",
"insecure-registries": ["localhost:5000"]
}
2. 配置日志轮转
# 创建日志轮转配置
sudo tee /etc/logrotate.d/docker > /dev/null <<EOF
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
size=1M
missingok
delaycompress
copytruncate
}
EOF
Dockerfile最佳实践
基础Dockerfile示例
Node.js应用
# 多阶段构建 - 构建阶段
FROM node:18-alpine AS builder
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production && npm cache clean --force
# 复制源代码
COPY . .
# 构建应用
RUN npm run build
# 运行阶段
FROM node:18-alpine AS runner
# 创建非root用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# 设置工作目录
WORKDIR /app
# 复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
# 切换到非root用户
USER nextjs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# 启动命令
CMD ["npm", "start"]
Python应用
# 多阶段构建
FROM python:3.11-slim AS builder
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制requirements文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 运行阶段
FROM python:3.11-slim AS runner
# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 设置工作目录
WORKDIR /app
# 复制依赖
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
# 复制应用代码
COPY . .
# 切换到非root用户
USER appuser
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["python", "app.py"]
Dockerfile最佳实践
1. 使用多阶段构建
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# 运行阶段
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
USER node
EXPOSE 3000
CMD ["npm", "start"]
2. 优化镜像层
# 优化前
COPY . .
RUN npm install
RUN npm run build
# 优化后
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
3. 使用.dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
.nyc_output
.coverage
4. 安全最佳实践
# 使用非root用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
USER nextjs
# 使用只读根文件系统
RUN mkdir -p /app/tmp
VOLUME ["/app/tmp"]
# 移除不必要的包
RUN apk del build-dependencies
# 设置健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
Docker镜像管理
镜像操作
1. 基础操作
# 拉取镜像
docker pull nginx:latest
# 查看本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
# 查看镜像详细信息
docker inspect nginx:latest
# 查看镜像历史
docker history nginx:latest
2. 镜像构建
# 构建镜像
docker build -t myapp:latest .
# 构建时指定构建参数
docker build --build-arg NODE_ENV=production -t myapp:prod .
# 构建时指定Dockerfile路径
docker build -f Dockerfile.prod -t myapp:prod .
# 构建时禁用缓存
docker build --no-cache -t myapp:latest .
3. 镜像标记和推送
# 标记镜像
docker tag myapp:latest myregistry.com/myapp:latest
docker tag myapp:latest myregistry.com/myapp:v1.0.0
# 推送镜像
docker push myregistry.com/myapp:latest
docker push myregistry.com/myapp:v1.0.0
# 登录到镜像仓库
docker login myregistry.com
镜像优化
1. 镜像大小优化
# 使用Alpine基础镜像
FROM node:18-alpine
# 清理包管理器缓存
RUN apk update && apk add --no-cache \
curl \
&& rm -rf /var/cache/apk/*
# 使用多阶段构建
FROM node:18-alpine AS builder
# ... 构建步骤
FROM node:18-alpine AS runner
COPY --from=builder /app/dist ./dist
2. 镜像安全扫描
# 使用Trivy扫描镜像
trivy image myapp:latest
# 使用Snyk扫描镜像
snyk test --docker myapp:latest
# 使用Docker Scout扫描
docker scout cves myapp:latest
Docker网络配置
网络模式
1. 网络类型
# 查看网络列表
docker network ls
# 创建自定义网络
docker network create mynetwork
# 创建带配置的网络
docker network create \
--driver bridge \
--subnet=172.20.0.0/16 \
--ip-range=172.20.240.0/20 \
mynetwork
2. 容器网络连接
# 运行容器并连接到网络
docker run -d --name web --network mynetwork nginx
# 将运行中的容器连接到网络
docker network connect mynetwork existing-container
# 从网络断开容器
docker network disconnect mynetwork existing-container
网络配置示例
1. 多容器应用网络
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
networks:
- frontend
- backend
api:
image: myapp:latest
networks:
- backend
- database
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
networks:
- database
networks:
frontend:
backend:
database:
2. 服务发现
# 在同一网络中,容器可以通过服务名互相访问
# web容器可以通过 http://api:3000 访问API服务
# api容器可以通过 postgres://db:5432/myapp 访问数据库
Docker存储管理
数据卷
1. 数据卷操作
# 创建数据卷
docker volume create mydata
# 查看数据卷
docker volume ls
# 查看数据卷详细信息
docker volume inspect mydata
# 删除数据卷
docker volume rm mydata
2. 使用数据卷
# 使用命名数据卷
docker run -v mydata:/data nginx
# 使用绑定挂载
docker run -v /host/path:/container/path nginx
# 使用只读挂载
docker run -v /host/path:/container/path:ro nginx
数据卷备份
1. 备份数据卷
# 备份数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz -C /data .
# 恢复数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup \
alpine tar xzf /backup/backup.tar.gz -C /data
2. 数据卷管理脚本
#!/bin/bash
# backup-volume.sh
VOLUME_NAME=$1
BACKUP_FILE="backup-${VOLUME_NAME}-$(date +%Y%m%d-%H%M%S).tar.gz"
if [ -z "$VOLUME_NAME" ]; then
echo "Usage: $0 <volume-name>"
exit 1
fi
echo "Backing up volume $VOLUME_NAME to $BACKUP_FILE"
docker run --rm -v $VOLUME_NAME:/data -v $(pwd):/backup \
alpine tar czf /backup/$BACKUP_FILE -C /data .
echo "Backup completed: $BACKUP_FILE"
Docker Compose实践
基础配置
1. 简单应用
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
2. 高级配置
# docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
ports:
- "80:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:password@db:5432/myapp
depends_on:
- db
- redis
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:6-alpine
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
postgres_data:
redis_data:
Compose命令
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs -f web
# 停止服务
docker-compose down
# 重新构建并启动
docker-compose up --build -d
# 扩展服务
docker-compose up --scale web=3 -d
Docker安全实践
容器安全
1. 运行时安全
# 以非root用户运行
docker run --user 1000:1000 nginx
# 限制容器权限
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# 使用只读根文件系统
docker run --read-only nginx
# 限制资源使用
docker run --memory=512m --cpus=1 nginx
2. 网络安全
# 创建隔离网络
docker network create --internal isolated-network
# 使用TLS加密
docker run -p 443:443 -v /path/to/certs:/certs nginx
镜像安全
1. 镜像扫描
# 使用Trivy扫描
trivy image nginx:latest
# 使用Snyk扫描
snyk test --docker nginx:latest
# 使用Docker Scout
docker scout cves nginx:latest
2. 镜像签名
# 启用Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# 签名镜像
docker push myregistry.com/myapp:latest
# 验证签名
docker trust inspect myregistry.com/myapp:latest
Docker监控与调试
监控命令
1. 容器监控
# 查看容器状态
docker ps -a
# 查看容器资源使用
docker stats
# 查看容器详细信息
docker inspect container_name
# 查看容器日志
docker logs -f container_name
2. 系统监控
# 查看Docker系统信息
docker system df
# 查看Docker事件
docker events
# 清理未使用的资源
docker system prune -a
调试技巧
1. 进入容器调试
# 进入运行中的容器
docker exec -it container_name /bin/bash
# 使用sh进入容器
docker exec -it container_name /bin/sh
# 以root用户进入
docker exec -it --user root container_name /bin/bash
2. 容器调试
# 查看容器进程
docker top container_name
# 查看容器网络
docker network inspect bridge
# 查看容器挂载
docker inspect container_name | grep -A 10 "Mounts"
生产环境最佳实践
1. 资源管理
# docker-compose.yml
version: '3.8'
services:
web:
image: myapp:latest
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
restart: unless-stopped
2. 健康检查
# docker-compose.yml
services:
web:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
3. 日志管理
# docker-compose.yml
services:
web:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
4. 安全配置
# docker-compose.yml
services:
web:
image: myapp:latest
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
- /var/cache
user: "1000:1000"
通过遵循这些最佳实践,可以构建安全、高效、可维护的Docker容器化应用,实现快速部署和可靠运行。