跳到主要内容

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容器化应用,实现快速部署和可靠运行。