39. Docker 容器化技术指南
目录
点击展开目录
Docker 概述 - 什么是 Docker - 核心概念 - Docker 架构 - 与虚拟机对比
Docker 安装与配置 - 系统要求 - 安装方式 - macOS:Colima(Docker CLI / Compose) - 配置优化 - 镜像加速
Docker 镜像管理 - 镜像基础 - 镜像操作 - Dockerfile 编写 - 镜像优化
Docker 容器管理 - 容器生命周期 - 容器操作 - 数据卷管理 - 网络配置
Docker Compose - Compose 概述 - 编排文件 - 服务管理 - 实战案例
Docker 网络 - 网络模式 - 自定义网络 - 跨主机网络 - 网络故障排查
Docker 存储 - 存储驱动 - 数据持久化 - 存储优化 - 备份恢复
Docker 安全 - 安全基础 - 镜像安全 - 容器安全 - 最佳实践
Docker 监控与日志 - 监控方案 - 日志管理 - 性能调优 - 故障排查
Docker 概述
什么是 Docker
Docker 是一个开源的容器化平台,用于开发、交付和运行应用程序。它通过容器技术实现应用程序及其依赖的轻量级虚拟化。
核心价值:
- 一致性环境:确保应用在不同环境中的一致性运行
- 快速部署:秒级启动,提升开发和部署效率
- 资源高效:相比虚拟机,占用更少的系统资源
- 微服务支持:天然适合微服务架构
主要解决的问题:
- 环境一致性:解决"在我机器上能跑"的问题
- 依赖管理:简化复杂的依赖关系管理
- 部署复杂性:标准化应用部署流程
- 资源利用率:提高服务器资源利用效率
核心概念
Docker 三大核心组件:
| 组件 | 作用 | 特点 | 类比 |
|---|---|---|---|
| 镜像 (Image) | 应用程序模板 | 只读、分层存储 | 程序安装包 |
| 容器 (Container) | 运行实例 | 可读写、隔离运行 | 运行中的程序 |
| 仓库 (Repository) | 镜像存储 | 集中管理、版本控制 | 应用商店 |
关键概念解析:
构建脚本"] B["Image
镜像"] C["Container
容器"] D["Registry
镜像仓库"] end subgraph "构建流程" E["编写 Dockerfile"] F["构建镜像"] G["推送仓库"] H["拉取运行"] end A --> B B --> C B --> D E --> F F --> G G --> H style B fill:#e1f5fe style C fill:#e8f5e8 style D fill:#fff3e0
容器 vs 进程:
- 容器:拥有独立的文件系统、网络、进程空间
- 进程:共享宿主机的系统资源
- 隔离性:容器提供更强的隔离和安全性
- 可移植性:容器可以在任何支持 Docker 的环境运行
Docker 架构
Docker 采用客户端-服务器架构,包含多个核心组件:
架构组件说明:
Docker Client:
- 用户与 Docker 交互的主要方式
- 通过 REST API 与 Docker Daemon 通信
- 支持本地和远程连接
Docker Daemon:
- Docker 的核心服务进程
- 管理镜像、容器、网络、存储
- 监听 Docker API 请求
containerd:
- 容器运行时管理器
- 负责容器生命周期管理
- 镜像管理和存储
runc:
- 底层容器运行时
- 基于 OCI 标准
- 实际创建和运行容器
与虚拟机对比
Docker 容器 vs 传统虚拟机:
| 对比维度 | Docker 容器 | 传统虚拟机 |
|---|---|---|
| 启动时间 | 秒级 | 分钟级 |
| 资源占用 | MB级别 | GB级别 |
| 性能开销 | 接近原生 | 10-20% 损耗 |
| 隔离级别 | 进程级隔离 | 硬件级隔离 |
| 可移植性 | 跨平台 | 平台相关 |
| 管理复杂度 | 简单 | 复杂 |
| 安全性 | 较好 | 更好 |
技术实现对比:
使用场景选择:
选择 Docker 容器:
- 微服务架构
- 快速部署和扩缩容
- CI/CD 流水线
- 开发环境标准化
选择虚拟机:
- 需要完全隔离的环境
- 运行不同操作系统
- 传统单体应用
- 高安全要求场景
Docker 安装与配置
系统要求
支持的操作系统:
| 操作系统 | 版本要求 | 架构支持 | 特殊说明 |
|---|---|---|---|
| Ubuntu | 18.04+ | x86_64, arm64 | 推荐 LTS 版本 |
| CentOS | 7+ | x86_64, arm64 | 需要 kernel 3.10+ |
| RHEL | 7+ | x86_64, arm64 | 企业级支持 |
| Debian | 9+ | x86_64, arm64 | 稳定性好 |
| macOS | 10.14+ | Intel, Apple Silicon | Docker Desktop 或 Colima + Docker CLI(见 macOS:Colima) |
| Windows | 10/11 | x86_64 | WSL2 或 Hyper-V |
硬件要求:
- CPU:64位处理器,支持虚拟化
- 内存:最小 2GB,推荐 4GB+
- 存储:至少 10GB 可用空间
- 网络:互联网连接(下载镜像)
安装方式
Linux 系统安装:
# Ubuntu/Debian 安装
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 或者使用官方仓库
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# CentOS/RHEL 安装
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
macOS 安装:
# 方式 A:Docker Desktop(带 GUI,官方集成环境)
brew install --cask docker
# 或下载安装包:https://www.docker.com/products/docker-desktop
# 方式 B:Colima + Docker CLI / Compose(无 Desktop,引擎跑在 Lima 虚拟机内)
brew install colima docker docker-compose
# 详细用法、Apple Silicon 跑 amd64 镜像、与 Desktop 并存等见下文「macOS:Colima」
Windows 安装:
# 使用 Chocolatey
choco install docker-desktop
# 或使用 winget
winget install Docker.DockerDesktop
安装验证:
# 检查 Docker 版本
docker --version
docker version
# 运行测试容器
docker run hello-world
# 查看系统信息
docker system info
macOS:Colima
Colima 基于 Lima,在 macOS 上提供 Linux 虚拟机 + 容器运行时,与 Docker CLI / Docker Compose 配合使用,无需安装 Docker Desktop 即可在本机构建与运行容器。CLI 通过 docker context 指向 Colima 内的 Docker daemon。
适用场景:
- 希望 命令行驱动、资源占用相对可控,或 不依赖 Docker Desktop 许可/分发。
- Apple Silicon(arm64) 上需要稳定运行 仅提供
linux/amd64清单的镜像:用 Colima--arch x86_64启动虚拟机,在 x86_64 Linux 内跑 Docker,避免在 arm64 宿主机上对单容器做 QEMU 用户态模拟带来的 不稳定或 SIGSEGV(如部分分析型数据库镜像)。完整实践与排障(含 Doris Compose、镜像save/load、JVM 堆与内存)可参考同工作区外文档:data-warehouse/docs/202604131800-mac-Colima-Doris本地安装总结.md。
安装(Homebrew)
brew install colima docker docker-compose
# Colima x86_64 虚拟机若报 guest agent 缺失,可安装并链接(见下节)
brew install lima-additional-guestagents
Lima Guest Agent(arch: x86_64 常见前置)
启动若出现类似 guest agent binary could not be found for Linux-x86_64:
- 原因:
lima-additional-guestagents提供的lima-guestagent.Linux-x86_64.gz等 不会自动合并进 Lima 的share/lima。 - 处理:将
$(brew --prefix lima-additional-guestagents)/share/lima/lima-guestagent.*符号链接到$(brew --prefix lima)/share/lima/(或维护可重复执行的脚本;brew upgrade lima后若复发可再执行一次)。
创建 / 切换 Colima
# 按需清理旧实例后重建(修改 arch 必须 delete 后重建)
colima delete -f
colima start --arch x86_64 --cpu 4 --memory 8 --disk 60 # 资源按机器调整;Apple Silicon 跑 amd64 镜像用 x86_64
# 默认 aarch64 虚拟机(多数 arm64/多架构镜像足够):
# colima start --cpu 4 --memory 4 --disk 60
docker context use colima
docker info | grep -i Architecture # x86_64 或 aarch64,应与目标镜像架构策略一致
注意:--arch 在 VM 创建后不可改;要从 aarch64 换成 x86_64(或反之)需 colima delete 后 colima start 重新创建。跑 JVM 堆较大 的多个容器时,VM 内存 需大于各进程堆与系统开销之和,否则易出现 Not enough space(errno 12)。
与 Docker Desktop 并存
- 镜像与数据在 各 context 的 daemon 中 隔离;同一时间建议
docker context use只指向一个(如colima或desktop-linux,以docker context ls为准)。 - 已在 Desktop 拉取的镜像要迁到 Colima:
docker save/docker load跨 context,不要对另一 context 做无意义push指望「同步」。
docker --context desktop-linux save my/image:tag -o /tmp/image.tar
docker --context colima load -i /tmp/image.tar
配置:~/.colima/default/colima.yaml
可配置 Docker Hub 镜像加速、代理 等;修改后通常需 colima restart。
docker pull / compose pull 报 EOF、failed to do request(访问 registry-1.docker.io 或 CDN)时:
- 配置
docker.registry-mirrors(多填几个备用;具体地址以你网络环境可用为准)。 - 若宿主机 HTTP(S) 代理 被注入 Colima VM,代理不稳定时大层拉取易失败;可尝试在配置中 清空或改为 VM 可达的代理,或换网络/云厂商个人加速地址。
- 仍失败时:换网络、缩小并发拉取,或优先在稳定环境
docker pull后save到本机再load。
示例片段(仅作结构示意,镜像站域名请自行替换为当前可用):
docker:
registry-mirrors:
- https://docker.1ms.run
- https://docker.m.daocloud.io
# 若需临时去掉代理(示例):
# env:
# HTTP_PROXY: ""
# HTTPS_PROXY: ""
常用命令
| 命令 | 说明 |
|---|---|
colima start / stop / status | 启停、查看状态 |
colima restart | 改 colima.yaml 后重启 VM |
colima ssh | 进入虚拟机 Shell(排障) |
docker context use colima | CLI 指向 Colima |
参考:Colima · lima-additional-guestagents · Docker daemon registry-mirrors
配置优化
Docker Daemon 配置:
# /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
],
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"data-root": "/var/lib/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"userland-proxy": false,
"experimental": false,
"debug": false
}
用户权限配置:
# 将用户添加到 docker 组
sudo usermod -aG docker $USER
# 重新登录或执行
newgrp docker
# 验证权限
docker run hello-world
系统服务配置:
# 启动 Docker 服务
sudo systemctl start docker
# 设置开机自启
sudo systemctl enable docker
# 查看服务状态
sudo systemctl status docker
# 重启 Docker 服务
sudo systemctl restart docker
镜像加速
国内镜像源配置:
| 镜像源 | 地址 | 特点 |
|---|---|---|
| 阿里云 | https://xxx.mirror.aliyuncs.com | 需要注册获取专属地址 |
| 腾讯云 | https://mirror.ccs.tencentyun.com | 免费使用 |
| 网易 | https://hub-mirror.c.163.com | 稳定可靠 |
| 中科大 | https://docker.mirrors.ustc.edu.cn | 教育网友好 |
| Docker 中国 | https://registry.docker-cn.com | 官方中国镜像 |
配置镜像加速器:
# 方法1:修改 daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
]
}
EOF
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
docker info | grep -A 10 "Registry Mirrors"
阿里云镜像加速器:
# 1. 登录阿里云容器镜像服务
# 2. 获取专属加速器地址
# 3. 配置加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://your-id.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
测试加速效果:
# 清理本地镜像
docker rmi nginx:latest
# 测试拉取速度
time docker pull nginx:latest
# 查看镜像信息
docker images nginx
Docker 镜像管理
镜像基础
镜像的本质:
- 分层文件系统:基于 Union FS 技术
- 只读模板:用于创建容器的静态模板
- 版本控制:支持标签和版本管理
- 共享存储:相同层可以被多个镜像共享
镜像分层结构:
nginx:latest"] B["运行时层
ubuntu:20.04"] C["基础层
scratch"] end subgraph "容器运行时" D["可写层
Container Layer"] E["镜像层
Read-Only Layers"] end A --> B B --> C D --> E E --> A style A fill:#e1f5fe style B fill:#e8f5e8 style C fill:#fff3e0 style D fill:#ffebee
镜像命名规范:
[registry]/[namespace]/[repository]:[tag]
示例:
docker.io/library/nginx:1.21.6
registry.cn-hangzhou.aliyuncs.com/my-namespace/my-app:v1.0.0
镜像操作
基础镜像操作:
# 搜索镜像
docker search nginx
docker search --limit 5 --filter stars=100 nginx
# 拉取镜像
docker pull nginx
docker pull nginx:1.21.6
docker pull ubuntu:20.04
# 查看镜像
docker images
docker images nginx
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
# 查看镜像详细信息
docker inspect nginx:latest
docker history nginx:latest
# 删除镜像
docker rmi nginx:latest
docker rmi $(docker images -q) # 删除所有镜像
docker image prune # 删除悬空镜像
镜像标签管理:
# 给镜像打标签
docker tag nginx:latest my-nginx:v1.0
docker tag nginx:latest localhost:5000/nginx:latest
# 重命名镜像
docker tag old-name:tag new-name:tag
docker rmi old-name:tag
# 查看镜像标签
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}"
镜像导入导出:
# 导出镜像
docker save nginx:latest > nginx.tar
docker save -o nginx.tar nginx:latest
docker save nginx:latest | gzip > nginx.tar.gz
# 导入镜像
docker load < nginx.tar
docker load -i nginx.tar
# 容器导出导入
docker export container_name > container.tar
docker import container.tar new-image:tag
Dockerfile 编写
Dockerfile 基础语法:
# 基础镜像
FROM ubuntu:20.04
# 维护者信息
LABEL maintainer="[email protected]"
LABEL version="1.0"
LABEL description="My application"
# 设置环境变量
ENV APP_HOME=/app
ENV PATH=$PATH:$APP_HOME/bin
# 设置工作目录
WORKDIR $APP_HOME
# 复制文件
COPY . .
ADD https://example.com/file.tar.gz /tmp/
# 安装软件包
RUN apt-get update && \
apt-get install -y nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 暴露端口
EXPOSE 80 443
# 创建数据卷
VOLUME ["/data", "/logs"]
# 设置用户
USER nginx
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
Dockerfile 指令详解:
| 指令 | 作用 | 示例 | 注意事项 |
|---|---|---|---|
| FROM | 指定基础镜像 | FROM ubuntu:20.04 | 必须是第一条指令 |
| RUN | 执行命令 | RUN apt-get update | 每个RUN会创建新层 |
| COPY | 复制文件 | COPY . /app | 只能复制本地文件 |
| ADD | 添加文件 | ADD file.tar.gz /tmp | 支持URL和自动解压 |
| WORKDIR | 设置工作目录 | WORKDIR /app | 影响后续指令 |
| ENV | 设置环境变量 | ENV PATH=/usr/bin | 容器运行时可用 |
| EXPOSE | 声明端口 | EXPOSE 80 | 仅声明,不自动映射 |
| CMD | 默认命令 | CMD ["nginx"] | 可被覆盖 |
| ENTRYPOINT | 入口点 | ENTRYPOINT ["./app"] | 不可被覆盖 |
多阶段构建:
# 构建阶段
FROM golang:1.19 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 运行阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
镜像优化
镜像大小优化策略:
- 选择合适的基础镜像:
# 不推荐:使用完整 Ubuntu
FROM ubuntu:20.04 # ~72MB
# 推荐:使用 Alpine
FROM alpine:3.16 # ~5MB
# 更推荐:使用 distroless
FROM gcr.io/distroless/static # ~2MB
- 合并 RUN 指令:
# 不推荐:多个 RUN 指令
RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get clean
# 推荐:合并为一个 RUN 指令
RUN apt-get update && \
apt-get install -y nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
- 使用 .dockerignore:
# .dockerignore 文件
.git
.gitignore
README.md
Dockerfile
.dockerignore
node_modules
npm-debug.log
coverage/
.nyc_output
- 清理缓存和临时文件:
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nginx \
curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
安全优化:
# 创建非 root 用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 设置文件权限
COPY --chown=appuser:appuser . /app
# 切换到非 root 用户
USER appuser
# 只暴露必要端口
EXPOSE 8080
# 使用 HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
构建优化技巧:
# 使用构建缓存
docker build --cache-from my-app:latest -t my-app:new .
# 并行构建
docker build --build-arg BUILDKIT_INLINE_CACHE=1 .
# 指定构建上下文
docker build -f Dockerfile.prod .
# 使用 BuildKit
export DOCKER_BUILDKIT=1
docker build .
Docker 容器管理
容器生命周期
容器状态转换:
已创建"] --> B["Running
运行中"] B --> C["Paused
暂停"] C --> B B --> D["Stopped
已停止"] D --> B B --> E["Exited
已退出"] E --> B A --> F["Dead
死亡"] D --> F E --> F style B fill:#e8f5e8 style D fill:#fff3e0 style E fill:#ffebee style F fill:#f3e5f5
生命周期管理命令:
| 状态 | 命令 | 说明 |
|---|---|---|
| 创建 | docker create | 创建容器但不启动 |
| 启动 | docker start | 启动已创建的容器 |
| 运行 | docker run | 创建并启动容器 |
| 暂停 | docker pause | 暂停容器进程 |
| 恢复 | docker unpause | 恢复暂停的容器 |
| 停止 | docker stop | 优雅停止容器 |
| 强杀 | docker kill | 强制终止容器 |
| 重启 | docker restart | 重启容器 |
| 删除 | docker rm | 删除容器 |
容器操作
基础容器操作:
# 运行容器
docker run nginx
docker run -d nginx # 后台运行
docker run -it ubuntu bash # 交互式运行
docker run --name my-nginx nginx # 指定容器名称
# 查看容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# 容器操作
docker start container_name
docker stop container_name
docker restart container_name
docker pause container_name
docker unpause container_name
# 删除容器
docker rm container_name
docker rm -f container_name # 强制删除运行中的容器
docker container prune # 删除所有停止的容器
容器交互:
# 进入容器
docker exec -it container_name bash
docker exec -it container_name sh
docker exec container_name ls /app
# 查看容器日志
docker logs container_name
docker logs -f container_name # 实时查看
docker logs --tail 100 container_name # 查看最后100行
docker logs --since "2023-01-01" container_name
# 查看容器信息
docker inspect container_name
docker stats container_name # 查看资源使用情况
docker top container_name # 查看容器进程
端口映射:
# 端口映射
docker run -p 8080:80 nginx # 映射到宿主机8080端口
docker run -p 127.0.0.1:8080:80 nginx # 绑定到特定IP
docker run -P nginx # 随机映射所有暴露端口
# 查看端口映射
docker port container_name
数据卷管理
数据卷类型:
| 类型 | 特点 | 使用场景 | 示例 |
|---|---|---|---|
| 匿名卷 | 系统自动管理 | 临时数据存储 | docker run -v /data nginx |
| 具名卷 | 用户命名管理 | 持久化数据 | docker run -v mydata:/data nginx |
| 绑定挂载 | 挂载宿主机目录 | 开发调试 | docker run -v /host/path:/container/path nginx |
| tmpfs 挂载 | 内存文件系统 | 临时敏感数据 | docker run --tmpfs /tmp nginx |
数据卷操作:
# 创建数据卷
docker volume create mydata
docker volume create --driver local mydata
# 查看数据卷
docker volume ls
docker volume inspect mydata
# 使用数据卷
docker run -v mydata:/data nginx
docker run --mount source=mydata,target=/data nginx
# 绑定挂载
docker run -v /host/data:/container/data nginx
docker run --mount type=bind,source=/host/data,target=/container/data nginx
# 只读挂载
docker run -v /host/data:/container/data:ro nginx
# 删除数据卷
docker volume rm mydata
docker volume prune # 删除未使用的数据卷
数据卷最佳实践:
# 备份数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup ubuntu tar czf /backup/backup.tar.gz -C /data .
# 恢复数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup ubuntu tar xzf /backup/backup.tar.gz -C /data
# 数据卷迁移
docker run --rm -v old_volume:/from -v new_volume:/to alpine sh -c "cd /from && cp -av . /to"
网络配置
Docker 网络模式:
172.17.0.2"] B["容器B
172.17.0.3"] C["Docker Bridge
docker0"] end subgraph "Host 网络" D["容器C
使用宿主机网络"] end subgraph "None 网络" E["容器D
无网络接口"] end A --> C B --> C C --> F["宿主机
eth0"] D --> F style C fill:#e1f5fe style F fill:#e8f5e8
网络模式对比:
| 网络模式 | 特点 | 性能 | 隔离性 | 使用场景 |
|---|---|---|---|---|
| bridge | 默认模式,NAT网络 | 中等 | 好 | 一般应用 |
| host | 使用宿主机网络 | 最佳 | 差 | 高性能应用 |
| none | 无网络接口 | 无 | 最好 | 安全要求高 |
| container | 共享其他容器网络 | 好 | 中等 | 容器间通信 |
| 自定义 | 用户自定义网络 | 好 | 好 | 微服务架构 |
网络操作命令:
# 查看网络
docker network ls
docker network inspect bridge
# 创建自定义网络
docker network create mynetwork
docker network create --driver bridge --subnet=172.20.0.0/16 mynetwork
# 容器连接网络
docker run --network mynetwork nginx
docker network connect mynetwork container_name
docker network disconnect mynetwork container_name
# 删除网络
docker network rm mynetwork
docker network prune # 删除未使用的网络
容器间通信:
# 使用容器名通信(自定义网络)
docker network create app-network
docker run -d --name db --network app-network mysql
docker run -d --name web --network app-network nginx
# 在 web 容器中可以通过 'db' 访问数据库容器
# 使用 link(已废弃,不推荐)
docker run --link db:database nginx
网络故障排查:
# 查看容器网络配置
docker exec container_name ip addr
docker exec container_name netstat -tlnp
# 测试网络连通性
docker exec container_name ping google.com
docker exec container_name telnet db 3306
# 查看网络详细信息
docker network inspect bridge
docker inspect container_name | grep -i network
Docker Compose
Compose 概述
Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 YAML 文件配置应用服务,然后使用单个命令创建并启动所有服务。
核心优势:
- 简化部署:一个命令启动整个应用栈
- 环境一致性:开发、测试、生产环境配置统一
- 服务编排:自动处理服务依赖关系
- 网络管理:自动创建服务间网络
Compose 工作流程:
安装 Docker Compose:
# Linux 安装
sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 或使用 pip 安装
pip install docker-compose
# 验证安装
docker-compose --version
编排文件
docker-compose.yml 基础结构:
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DEBUG=1
depends_on:
- db
- redis
networks:
- app-network
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:6-alpine
networks:
- app-network
volumes:
postgres_data:
networks:
app-network:
driver: bridge
Compose 文件版本对比:
| 版本 | Docker Engine | 特性 |
|---|---|---|
| 3.8 | 19.03.0+ | 最新特性支持 |
| 3.7 | 18.06.0+ | 外部网络支持 |
| 3.6 | 18.02.0+ | tmpfs 支持 |
| 3.5 | 17.12.0+ | 隔离模式支持 |
| 3.4 | 17.09.0+ | 平台指定支持 |
服务配置详解:
services:
app:
# 镜像配置
image: nginx:latest
# 或构建配置
build:
context: .
dockerfile: Dockerfile.prod
args:
- BUILD_ENV=production
# 容器名称
container_name: my-app
# 重启策略
restart: unless-stopped
# 端口映射
ports:
- "80:80"
- "443:443"
# 环境变量
environment:
- NODE_ENV=production
- API_URL=http://api:3000
env_file:
- .env
# 数据卷
volumes:
- ./app:/usr/share/nginx/html:ro
- nginx_logs:/var/log/nginx
# 网络配置
networks:
- frontend
- backend
# 依赖关系
depends_on:
- api
- db
# 健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
服务管理
基础 Compose 命令:
# 启动服务
docker-compose up
docker-compose up -d # 后台运行
docker-compose up --build # 重新构建镜像
# 停止服务
docker-compose down
docker-compose down -v # 同时删除数据卷
docker-compose down --rmi all # 同时删除镜像
# 查看服务状态
docker-compose ps
docker-compose top
docker-compose logs
docker-compose logs -f web # 实时查看特定服务日志
# 服务操作
docker-compose start
docker-compose stop
docker-compose restart
docker-compose pause
docker-compose unpause
# 扩缩容
docker-compose up --scale web=3
docker-compose up --scale web=3 --scale worker=2
服务管理命令:
# 执行命令
docker-compose exec web bash
docker-compose exec db psql -U user myapp
# 运行一次性命令
docker-compose run web python manage.py migrate
docker-compose run --rm web npm test
# 查看配置
docker-compose config
docker-compose config --services
docker-compose config --volumes
# 拉取镜像
docker-compose pull
docker-compose pull web
# 构建镜像
docker-compose build
docker-compose build --no-cache web
实战案例
LNMP 架构示例:
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./www:/var/www/html:ro
- ./nginx/logs:/var/log/nginx
depends_on:
- php
networks:
- lnmp-network
php:
build:
context: ./php
dockerfile: Dockerfile
volumes:
- ./www:/var/www/html
- ./php/conf.d:/usr/local/etc/php/conf.d:ro
depends_on:
- mysql
- redis
networks:
- lnmp-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppassword
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d:ro
- ./mysql/init:/docker-entrypoint-initdb.d:ro
ports:
- "3306:3306"
networks:
- lnmp-network
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
ports:
- "6379:6379"
networks:
- lnmp-network
volumes:
mysql_data:
redis_data:
networks:
lnmp-network:
driver: bridge
微服务架构示例:
version: '3.8'
services:
# API 网关
gateway:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./gateway/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- user-service
- order-service
networks:
- microservices
# 用户服务
user-service:
build: ./user-service
environment:
- DATABASE_URL=postgresql://user:pass@postgres:5432/users
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
networks:
- microservices
deploy:
replicas: 2
# 订单服务
order-service:
build: ./order-service
environment:
- DATABASE_URL=postgresql://user:pass@postgres:5432/orders
- USER_SERVICE_URL=http://user-service:8080
depends_on:
- postgres
networks:
- microservices
# 数据库
postgres:
image: postgres:13
environment:
POSTGRES_DB: microservices
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- microservices
# 缓存
redis:
image: redis:6-alpine
networks:
- microservices
# 监控
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
networks:
- microservices
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
networks:
- microservices
volumes:
postgres_data:
grafana_data:
networks:
microservices:
driver: bridge
开发环境配置:
# docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
- DEBUG=*
ports:
- "3000:3000"
- "9229:9229" # Node.js 调试端口
command: npm run dev
db:
image: postgres:13
environment:
POSTGRES_DB: myapp_dev
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
ports:
- "5432:5432"
volumes:
- postgres_dev_data:/var/lib/postgresql/data
volumes:
postgres_dev_data:
多环境管理:
# 使用不同的 compose 文件
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
# 使用环境变量文件
docker-compose --env-file .env.dev up
# 项目名称管理
docker-compose -p myapp-dev up
docker-compose -p myapp-prod up
Docker 网络
网络模式
Docker 网络驱动类型:
| 驱动类型 | 作用域 | 特点 | 使用场景 |
|---|---|---|---|
| bridge | 单主机 | 默认网络,NAT模式 | 单机容器通信 |
| host | 单主机 | 使用宿主机网络栈 | 高性能网络应用 |
| overlay | 多主机 | 跨主机容器通信 | Docker Swarm 集群 |
| macvlan | 单主机 | 容器拥有独立MAC地址 | 需要直接网络访问 |
| none | 单主机 | 禁用网络 | 高安全要求 |
| ipvlan | 单主机 | 共享MAC地址 | 网络虚拟化 |
网络模式详细对比:
172.17.0.2"] A2["容器B
172.17.0.3"] A3["Docker Bridge
docker0"] A4["iptables NAT"] A5["宿主机网卡"] end subgraph "Host 网络模式" B1["容器C"] B2["宿主机网络栈"] end subgraph "Overlay 网络模式" C1["主机1容器"] C2["主机2容器"] C3["VXLAN隧道"] end A1 --> A3 A2 --> A3 A3 --> A4 A4 --> A5 B1 --> B2 C1 --> C3 C3 --> C2 style A3 fill:#e1f5fe style B2 fill:#e8f5e8 style C3 fill:#fff3e0
Bridge 网络详解:
# 查看默认 bridge 网络
docker network inspect bridge
# 创建自定义 bridge 网络
docker network create --driver bridge my-bridge
docker network create --driver bridge --subnet=172.20.0.0/16 --gateway=172.20.0.1 my-bridge
# 指定 IP 地址
docker run --network my-bridge --ip 172.20.0.10 nginx
# 网络别名
docker run --network my-bridge --network-alias web nginx
Host 网络使用:
# 使用 host 网络
docker run --network host nginx
# 查看网络配置
docker run --network host alpine ip addr show
自定义网络
创建和管理自定义网络:
# 创建 bridge 网络
docker network create \
--driver bridge \
--subnet=172.30.0.0/16 \
--ip-range=172.30.240.0/20 \
--gateway=172.30.0.1 \
--opt com.docker.network.bridge.name=my-bridge \
--opt com.docker.network.mtu=1500 \
my-network
# 创建 macvlan 网络
docker network create \
--driver macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--opt parent=eth0 \
macvlan-net
# 查看网络详情
docker network inspect my-network
# 连接容器到网络
docker network connect my-network container_name
docker network connect --ip 172.30.0.100 my-network container_name
# 断开网络连接
docker network disconnect my-network container_name
网络配置示例:
# docker-compose.yml 网络配置
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
- backend
api:
image: node:alpine
networks:
backend:
ipv4_address: 172.20.0.10
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.19.0.0/16
backend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
external-net:
external: true
name: existing-network
跨主机网络
Docker Swarm Overlay 网络:
# 初始化 Swarm 集群
docker swarm init --advertise-addr 192.168.1.100
# 加入 Swarm 集群
docker swarm join --token SWMTKN-xxx 192.168.1.100:2377
# 创建 overlay 网络
docker network create --driver overlay --attachable my-overlay
# 在 overlay 网络中运行容器
docker run -d --network my-overlay --name web1 nginx
docker run -d --network my-overlay --name web2 nginx
# 跨主机容器通信测试
docker exec web1 ping web2
第三方网络解决方案:
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Flannel | 简单易用,性能一般 | 小规模集群 |
| Calico | 高性能,支持网络策略 | 大规模生产环境 |
| Weave | 功能丰富,自动发现 | 混合云环境 |
| Cilium | 基于 eBPF,高性能 | 现代化容器平台 |
网络故障排查
常见网络问题:
- 容器无法访问外网:
# 检查 DNS 配置
docker exec container_name nslookup google.com
# 检查路由表
docker exec container_name ip route
# 检查 iptables 规则
sudo iptables -t nat -L
- 容器间无法通信:
# 检查网络连接
docker network ls
docker network inspect network_name
# 测试连通性
docker exec container1 ping container2
docker exec container1 telnet container2 80
# 检查端口监听
docker exec container_name netstat -tlnp
- 端口映射问题:
# 检查端口映射
docker port container_name
# 检查宿主机端口占用
netstat -tlnp | grep :8080
# 检查防火墙规则
sudo ufw status
sudo firewall-cmd --list-all
网络诊断工具:
# 安装网络工具
docker run --rm --network container:target_container nicolaka/netshoot
# 使用 tcpdump 抓包
docker exec container_name tcpdump -i eth0 -w /tmp/capture.pcap
# 使用 ss 查看连接
docker exec container_name ss -tlnp
# 查看网络统计
docker exec container_name cat /proc/net/dev
网络性能测试:
# 使用 iperf3 测试网络性能
# 服务端
docker run -d --name iperf3-server --network my-network iperf3 -s
# 客户端
docker run --rm --network my-network iperf3 -c iperf3-server
# 使用 ping 测试延迟
docker exec container1 ping -c 10 container2
# 使用 curl 测试 HTTP 性能
docker exec container_name curl -w "@curl-format.txt" -o /dev/null -s http://target/
网络监控:
# 实时监控网络流量
docker exec container_name iftop -i eth0
# 监控网络连接
docker exec container_name watch -n 1 'ss -tuln'
# 使用 Prometheus 监控
# 在 docker-compose.yml 中添加 cAdvisor
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
网络安全配置:
# 创建隔离网络
docker network create --internal isolated-network
# 使用网络策略(需要支持的网络插件)
# 示例:Calico 网络策略
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: deny-all
spec:
selector: all()
types:
- Ingress
- Egress
# 限制容器网络访问
docker run --cap-drop NET_ADMIN --cap-drop NET_RAW nginx
Docker 存储
存储驱动
Docker 存储驱动类型:
| 存储驱动 | 特点 | 性能 | 适用系统 | 推荐场景 |
|---|---|---|---|---|
| overlay2 | 现代化,功能完整 | 高 | Linux 4.0+ | 生产环境推荐 |
| aufs | 成熟稳定 | 中 | Ubuntu/Debian | 旧版本系统 |
| devicemapper | 企业级特性 | 中 | RHEL/CentOS | 企业环境 |
| btrfs | 写时复制,快照 | 高 | 支持 Btrfs 的系统 | 需要高级特性 |
| zfs | 企业级,数据完整性 | 高 | 支持 ZFS 的系统 | 数据安全要求高 |
| vfs | 无联合文件系统 | 低 | 所有系统 | 调试和测试 |
存储驱动架构:
Container Layer"] B["镜像层 N
Image Layer N"] C["镜像层 2
Image Layer 2"] D["镜像层 1
Image Layer 1"] E["基础层
Base Layer"] end subgraph "存储驱动" F["overlay2"] G["联合文件系统
Union FS"] H["宿主机文件系统
Host FS"] end A --> B B --> C C --> D D --> E A --> F F --> G G --> H style A fill:#ffebee style F fill:#e1f5fe style H fill:#e8f5e8
查看和配置存储驱动:
# 查看当前存储驱动
docker info | grep "Storage Driver"
# 查看存储详细信息
docker system df
docker system df -v
# 配置存储驱动(daemon.json)
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
# 查看镜像层信息
docker history nginx:latest
docker inspect nginx:latest
数据持久化
数据持久化方案对比:
数据卷最佳实践:
# 创建命名数据卷
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/path/to/dir \
nfs-volume
# 使用本地存储驱动选项
docker volume create --driver local \
--opt type=btrfs \
--opt device=/dev/sdb \
btrfs-volume
# 数据卷标签管理
docker volume create --label environment=production \
--label backup=daily \
prod-data
# 查看数据卷使用情况
docker system df -v
docker volume ls --filter dangling=true
高级数据卷配置:
# docker-compose.yml 高级数据卷配置
version: '3.8'
services:
app:
image: myapp
volumes:
# 命名卷
- app_data:/app/data
# 绑定挂载(只读)
- ./config:/app/config:ro
# tmpfs 挂载
- type: tmpfs
target: /app/tmp
tmpfs:
size: 100M
# 数据卷配置
- type: volume
source: app_logs
target: /app/logs
volume:
nocopy: true
volumes:
app_data:
driver: local
driver_opts:
type: nfs
o: addr=nfs-server,rw
device: ":/exports/app_data"
app_logs:
driver: local
driver_opts:
type: btrfs
device: /dev/sdb1
存储优化
镜像层优化:
# 优化前:多个 RUN 指令创建多层
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get install -y curl
RUN apt-get clean
# 优化后:合并 RUN 指令
FROM ubuntu:20.04
RUN apt-get update && \
apt-get install -y nginx curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 使用多阶段构建减少最终镜像大小
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
存储空间管理:
# 清理未使用的资源
docker system prune # 清理停止的容器、未使用的网络、悬空镜像
docker system prune -a # 清理所有未使用的镜像
docker system prune --volumes # 同时清理未使用的数据卷
# 分别清理不同类型的资源
docker container prune # 清理停止的容器
docker image prune # 清理悬空镜像
docker image prune -a # 清理未使用的镜像
docker volume prune # 清理未使用的数据卷
docker network prune # 清理未使用的网络
# 查看存储使用情况
docker system df
docker system df -v
# 分析镜像大小
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
dive nginx:latest # 使用 dive 工具分析镜像层
存储性能优化:
# 配置存储驱动选项
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true",
"overlay2.size=20G"
],
"data-root": "/var/lib/docker"
}
# 使用 SSD 存储
# 将 Docker 数据目录移动到 SSD
sudo systemctl stop docker
sudo mv /var/lib/docker /ssd/docker
sudo ln -s /ssd/docker /var/lib/docker
sudo systemctl start docker
# 配置日志轮转
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
备份恢复
数据卷备份策略:
# 方法1:使用临时容器备份
docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
ubuntu tar czf /backup/backup-$(date +%Y%m%d).tar.gz -C /data .
# 方法2:直接访问数据卷目录
sudo tar czf backup.tar.gz -C /var/lib/docker/volumes/mydata/_data .
# 方法3:使用专用备份容器
docker run --rm \
-v mydata:/source:ro \
-v backup_storage:/backup \
alpine sh -c "tar czf /backup/data-$(date +%Y%m%d).tar.gz -C /source ."
自动化备份脚本:
#!/bin/bash
# docker-backup.sh
BACKUP_DIR="/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份所有数据卷
for volume in $(docker volume ls -q); do
echo "Backing up volume: $volume"
docker run --rm \
-v $volume:/data:ro \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/${volume}_${DATE}.tar.gz -C /data .
done
# 清理旧备份(保留7天)
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
echo "Backup completed: $BACKUP_DIR"
数据恢复:
# 恢复数据卷
# 1. 创建新的数据卷
docker volume create mydata_restored
# 2. 恢复数据
docker run --rm \
-v mydata_restored:/data \
-v $(pwd):/backup \
ubuntu tar xzf /backup/backup-20231201.tar.gz -C /data
# 3. 验证恢复的数据
docker run --rm -v mydata_restored:/data alpine ls -la /data
容器状态备份:
# 提交容器为镜像
docker commit container_name my-backup:$(date +%Y%m%d)
# 导出容器文件系统
docker export container_name > container-backup.tar
# 导出镜像
docker save my-app:latest > my-app-backup.tar
# 批量备份脚本
#!/bin/bash
BACKUP_DIR="/backup/containers"
mkdir -p $BACKUP_DIR
# 备份运行中的容器
for container in $(docker ps --format "{{.Names}}"); do
echo "Backing up container: $container"
docker commit $container ${container}-backup:$(date +%Y%m%d)
docker save ${container}-backup:$(date +%Y%m%d) > $BACKUP_DIR/${container}-$(date +%Y%m%d).tar
done
灾难恢复计划:
# 1. 系统恢复脚本
#!/bin/bash
# disaster-recovery.sh
# 重新安装 Docker
curl -fsSL https://get.docker.com | sh
# 恢复配置文件
cp backup/daemon.json /etc/docker/
systemctl restart docker
# 恢复镜像
for image in backup/*.tar; do
docker load < $image
done
# 恢复数据卷
for volume_backup in backup/volumes/*.tar.gz; do
volume_name=$(basename $volume_backup .tar.gz)
docker volume create $volume_name
docker run --rm \
-v $volume_name:/data \
-v $(pwd)/backup/volumes:/backup \
alpine tar xzf /backup/$(basename $volume_backup) -C /data
done
# 重启服务
docker-compose up -d
Docker 安全
安全基础
Docker 安全模型:
安全威胁模型:
| 威胁类型 | 风险等级 | 影响范围 | 防护措施 |
|---|---|---|---|
| 容器逃逸 | 高 | 宿主机 | 内核更新、权限控制 |
| 镜像漏洞 | 中 | 容器内 | 漏洞扫描、及时更新 |
| 权限提升 | 高 | 系统级 | 最小权限原则 |
| 资源耗尽 | 中 | 服务可用性 | 资源限制 |
| 网络攻击 | 中 | 网络通信 | 网络隔离、防火墙 |
| 数据泄露 | 高 | 敏感数据 | 加密、访问控制 |
镜像安全
安全镜像构建:
# 安全 Dockerfile 示例
FROM alpine:3.16 AS base
# 创建非 root 用户
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
# 安装必要软件包并清理
RUN apk add --no-cache \
ca-certificates \
curl && \
rm -rf /var/cache/apk/*
# 设置工作目录
WORKDIR /app
# 复制应用文件并设置权限
COPY --chown=appuser:appgroup . .
# 切换到非 root 用户
USER appuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# 使用非 root 端口
EXPOSE 8080
CMD ["./app"]
镜像漏洞扫描:
# 使用 Docker Scout 扫描
docker scout cves nginx:latest
docker scout recommendations nginx:latest
# 使用 Trivy 扫描
trivy image nginx:latest
trivy image --severity HIGH,CRITICAL nginx:latest
# 使用 Clair 扫描
clairctl analyze nginx:latest
# 使用 Anchore 扫描
anchore-cli image add nginx:latest
anchore-cli image wait nginx:latest
anchore-cli image vuln nginx:latest all
镜像签名和验证:
# 启用 Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# 生成签名密钥
docker trust key generate mykey
# 签名镜像
docker trust sign myregistry.com/myimage:latest
# 验证镜像签名
docker trust inspect myregistry.com/myimage:latest
# 使用 Notary 进行高级签名管理
notary init myregistry.com/myimage
notary publish myregistry.com/myimage
容器安全
容器运行时安全配置:
# 限制容器权限
docker run --user 1001:1001 nginx # 指定用户ID
docker run --read-only nginx # 只读文件系统
docker run --no-new-privileges nginx # 禁止权限提升
# 删除危险能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# 使用安全计算模式
docker run --security-opt seccomp=seccomp-profile.json nginx
docker run --security-opt no-new-privileges nginx
# 限制系统调用
docker run --security-opt seccomp=unconfined nginx # 不推荐
资源限制配置:
# CPU 限制
docker run --cpus="1.5" nginx # 限制 1.5 个 CPU
docker run --cpu-shares=512 nginx # 相对权重
# 内存限制
docker run --memory=512m nginx # 限制内存 512MB
docker run --memory=1g --memory-swap=2g nginx # 内存+交换空间
# 磁盘 IO 限制
docker run --device-read-bps /dev/sda:1mb nginx
docker run --device-write-bps /dev/sda:1mb nginx
# 进程数限制
docker run --pids-limit=100 nginx
网络安全配置:
# 网络隔离
docker run --network none nginx # 无网络访问
docker run --network isolated-net nginx # 自定义隔离网络
# 端口限制
docker run -p 127.0.0.1:8080:80 nginx # 只绑定本地接口
# 使用用户定义网络
docker network create --internal secure-network
docker run --network secure-network nginx
最佳实践
安全配置清单:
# docker-compose.yml 安全配置示例
version: '3.8'
services:
web:
image: nginx:alpine
user: "1001:1001"
read_only: true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
- seccomp:seccomp-profile.json
tmpfs:
- /tmp
- /var/cache/nginx
volumes:
- ./html:/usr/share/nginx/html:ro
ports:
- "127.0.0.1:8080:80"
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Seccomp 安全配置文件:
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": [
"accept",
"accept4",
"access",
"bind",
"brk",
"close",
"connect",
"dup",
"dup2",
"execve",
"exit",
"exit_group",
"fstat",
"getpid",
"getuid",
"listen",
"mmap",
"open",
"read",
"socket",
"write"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
AppArmor 配置:
# 创建 AppArmor 配置文件
# /etc/apparmor.d/docker-nginx
#include <tunables/global>
profile docker-nginx flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
/usr/sbin/nginx ix,
/etc/nginx/ r,
/etc/nginx/** r,
/var/log/nginx/ w,
/var/log/nginx/** w,
/usr/share/nginx/html/ r,
/usr/share/nginx/html/** r,
deny /proc/sys/** w,
deny /sys/** w,
}
# 加载配置文件
sudo apparmor_parser -r /etc/apparmor.d/docker-nginx
# 使用 AppArmor 配置运行容器
docker run --security-opt apparmor=docker-nginx nginx
安全监控和审计:
# 启用 Docker 审计日志
# 在 /etc/audit/rules.d/docker.rules 中添加
-w /usr/bin/docker -p wa -k docker
-w /var/lib/docker -p wa -k docker
-w /etc/docker -p wa -k docker
-w /lib/systemd/system/docker.service -p wa -k docker
-w /etc/systemd/system/docker.service -p wa -k docker
# 重启审计服务
sudo systemctl restart auditd
# 查看审计日志
sudo ausearch -k docker
# 使用 Falco 进行运行时安全监控
# falco_rules.yaml
- rule: Write below binary dir
desc: an attempt to write to any file below a set of binary directories
condition: >
bin_dir and evt.dir = < and open_write
and not package_mgmt_procs
and not exe_running_docker_save
and not python_running_get_pip
and not python_running_ms_oms
output: >
File below a known binary directory opened for writing (user=%user.name
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2])
priority: ERROR
容器镜像安全扫描集成:
# .github/workflows/security-scan.yml
name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
Docker 监控与日志
监控方案
Docker 监控架构:
基础监控指标:
| 指标类别 | 关键指标 | 说明 | 告警阈值 |
|---|---|---|---|
| CPU | cpu_usage_percent | CPU 使用率 | > 80% |
| cpu_throttled_seconds | CPU 限流时间 | > 0 | |
| 内存 | memory_usage_bytes | 内存使用量 | > 90% |
| memory_oom_kills | OOM 杀死次数 | > 0 | |
| 网络 | network_rx_bytes | 网络接收字节 | 异常增长 |
| network_tx_bytes | 网络发送字节 | 异常增长 | |
| 磁盘 | disk_usage_percent | 磁盘使用率 | > 85% |
| disk_io_bytes | 磁盘 IO 字节 | 异常增长 | |
| 容器 | container_count | 容器数量 | 异常变化 |
| container_restarts | 容器重启次数 | > 5/小时 |
监控工具配置
Prometheus + Grafana 监控栈:
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- 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'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
networks:
- monitoring
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
privileged: true
devices:
- /dev/kmsg
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
networks:
- monitoring
volumes:
prometheus_data:
grafana_data:
networks:
monitoring:
driver: bridge
Prometheus 配置文件:
# prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'docker'
static_configs:
- targets: ['host.docker.internal:9323']
metrics_path: /metrics
告警规则配置:
# prometheus/alert_rules.yml
groups:
- name: docker_alerts
rules:
- alert: ContainerDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Container {{ $labels.instance }} is down"
description: "Container {{ $labels.instance }} has been down for more than 1 minute."
- alert: HighCPUUsage
expr: rate(container_cpu_usage_seconds_total[5m]) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.name }}"
description: "Container {{ $labels.name }} CPU usage is above 80% for more than 5 minutes."
- alert: HighMemoryUsage
expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage on {{ $labels.name }}"
description: "Container {{ $labels.name }} memory usage is above 90% for more than 5 minutes."
- alert: ContainerRestartTooOften
expr: increase(container_restart_count[1h]) > 5
for: 0m
labels:
severity: warning
annotations:
summary: "Container restarting too often"
description: "Container {{ $labels.name }} has restarted {{ $value }} times in the last hour."
日志管理
Docker 日志驱动:
| 日志驱动 | 特点 | 适用场景 | 配置示例 |
|---|---|---|---|
| json-file | 默认驱动,本地存储 | 开发环境 | --log-driver json-file |
| syslog | 系统日志服务 | 传统环境 | --log-driver syslog |
| journald | systemd 日志 | systemd 系统 | --log-driver journald |
| fluentd | 结构化日志收集 | 微服务架构 | --log-driver fluentd |
| awslogs | AWS CloudWatch | AWS 环境 | --log-driver awslogs |
| splunk | Splunk 平台 | 企业环境 | --log-driver splunk |
集中化日志收集架构:
# ELK Stack 日志收集
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
networks:
- elk
logstash:
image: docker.elastic.co/logstash/logstash:7.17.0
volumes:
- ./logstash/config:/usr/share/logstash/pipeline:ro
ports:
- "5044:5044"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:7.17.0
ports:
- "5601:5601"
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
networks:
- elk
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:7.17.0
user: root
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- elk
depends_on:
- logstash
volumes:
elasticsearch_data:
networks:
elk:
driver: bridge
Filebeat 配置:
# filebeat/filebeat.yml
filebeat.inputs:
- type: container
paths:
- '/var/lib/docker/containers/*/*.log'
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
- decode_json_fields:
fields: ["message"]
target: ""
overwrite_keys: true
output.logstash:
hosts: ["logstash:5044"]
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
Fluentd 日志收集:
# Fluentd 配置
version: '3.8'
services:
fluentd:
build: ./fluentd
volumes:
- ./fluentd/conf:/fluentd/etc
ports:
- "24224:24224"
- "24224:24224/udp"
networks:
- logging
app:
image: nginx
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
tag: nginx.access
networks:
- logging
networks:
logging:
driver: bridge
性能调优
容器性能监控:
# 实时监控容器资源使用
docker stats
docker stats --no-stream
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 查看容器进程
docker top container_name
docker exec container_name ps aux
# 监控容器网络
docker exec container_name netstat -i
docker exec container_name ss -tuln
# 监控容器磁盘 IO
docker exec container_name iostat -x 1
性能调优参数:
# CPU 性能调优
docker run --cpus="2.0" --cpu-shares=1024 nginx
# 内存性能调优
docker run --memory=1g --memory-swap=2g --oom-kill-disable nginx
# 磁盘 IO 调优
docker run --device-read-bps /dev/sda:10mb --device-write-bps /dev/sda:5mb nginx
# 网络性能调优
docker run --network=host nginx # 使用主机网络获得最佳性能
故障排查
常见问题诊断:
# 1. 容器启动失败
docker logs container_name
docker inspect container_name
docker events --filter container=container_name
# 2. 性能问题诊断
docker stats container_name
docker exec container_name top
docker exec container_name free -h
docker exec container_name df -h
# 3. 网络连接问题
docker exec container_name ping google.com
docker exec container_name nslookup google.com
docker exec container_name netstat -tlnp
# 4. 存储问题诊断
docker system df
docker system events
docker volume inspect volume_name
故障排查工具:
# 使用 dive 分析镜像
dive nginx:latest
# 使用 ctop 监控容器
ctop
# 使用 docker-compose 调试
docker-compose config
docker-compose logs service_name
docker-compose exec service_name bash
# 使用 portainer 管理界面
docker run -d -p 9000:9000 --name portainer \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
性能基准测试:
# 容器启动时间测试
time docker run --rm alpine echo "Hello World"
# 网络性能测试
docker run --rm -it networkstatic/iperf3 -c iperf.he.net
# 磁盘 IO 性能测试
docker run --rm -v /tmp:/tmp alpine sh -c "dd if=/dev/zero of=/tmp/test bs=1M count=100"
# 内存性能测试
docker run --rm alpine sh -c "free -m && sync && echo 3 > /proc/sys/vm/drop_caches && free -m"
生产环境实践
部署策略
生产环境部署模式:
| 部署模式 | 特点 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|---|
| 单机部署 | 简单直接 | 部署简单、成本低 | 无高可用、扩展性差 | 小型应用、开发环境 |
| Docker Swarm | 原生集群 | 简单易用、内置负载均衡 | 功能相对简单 | 中小型集群 |
| Kubernetes | 容器编排平台 | 功能强大、生态丰富 | 复杂度高、学习成本大 | 大规模生产环境 |
| 云服务 | 托管服务 | 免运维、高可用 | 成本高、厂商绑定 | 快速上线、企业应用 |
蓝绿部署示例:
#!/bin/bash
# blue-green-deploy.sh
# 配置变量
IMAGE_NAME="myapp"
NEW_VERSION=$1
CURRENT_COLOR=$(docker ps --filter "name=app-" --format "{{.Names}}" | head -1 | cut -d'-' -f2)
if [ "$CURRENT_COLOR" = "blue" ]; then
NEW_COLOR="green"
OLD_COLOR="blue"
else
NEW_COLOR="blue"
OLD_COLOR="green"
fi
echo "当前版本: $OLD_COLOR, 新版本: $NEW_COLOR"
# 部署新版本
docker run -d \
--name app-$NEW_COLOR \
--network app-network \
-e COLOR=$NEW_COLOR \
$IMAGE_NAME:$NEW_VERSION
# 健康检查
echo "等待新版本启动..."
sleep 30
# 检查新版本健康状态
if docker exec app-$NEW_COLOR curl -f http://localhost:8080/health; then
echo "新版本健康检查通过"
# 切换流量
docker exec nginx nginx -s reload
# 停止旧版本
docker stop app-$OLD_COLOR
docker rm app-$OLD_COLOR
echo "部署完成: $NEW_VERSION"
else
echo "新版本健康检查失败,回滚"
docker stop app-$NEW_COLOR
docker rm app-$NEW_COLOR
exit 1
fi
滚动更新策略:
# docker-compose.yml 滚动更新配置
version: '3.8'
services:
app:
image: myapp:${VERSION:-latest}
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
monitor: 60s
max_failure_ratio: 0.3
rollback_config:
parallelism: 1
delay: 10s
failure_action: pause
monitor: 60s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
CI/CD 集成
GitLab CI/CD 流水线:
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
services:
- docker:20.10.16-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
only:
- main
- develop
test:
stage: test
script:
- docker run --rm $IMAGE_TAG npm test
- docker run --rm $IMAGE_TAG npm run lint
only:
- main
- develop
security_scan:
stage: security
script:
- docker run --rm -v /var/run/docker.sock:/var/run/docker.sock
aquasec/trivy image --exit-code 1 --severity HIGH,CRITICAL $IMAGE_TAG
allow_failure: true
only:
- main
deploy_staging:
stage: deploy
script:
- docker-compose -f docker-compose.staging.yml pull
- docker-compose -f docker-compose.staging.yml up -d
environment:
name: staging
url: https://staging.example.com
only:
- develop
deploy_production:
stage: deploy
script:
- ./scripts/blue-green-deploy.sh $CI_COMMIT_SHA
environment:
name: production
url: https://example.com
when: manual
only:
- main
GitHub Actions 工作流:
# .github/workflows/docker.yml
name: Docker Build and Deploy
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Run tests
run: |
docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} npm test
security:
needs: build
runs-on: ubuntu-latest
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
deploy:
if: github.ref == 'refs/heads/main'
needs: [build, test, security]
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to production
run: |
# 部署脚本
echo "Deploying ${{ github.sha }} to production"
集群管理
Docker Swarm 集群配置:
# 初始化 Swarm 集群
docker swarm init --advertise-addr 192.168.1.100
# 添加管理节点
docker swarm join-token manager
docker swarm join --token SWMTKN-xxx 192.168.1.100:2377
# 添加工作节点
docker swarm join-token worker
docker swarm join --token SWMTKN-xxx 192.168.1.100:2377
# 查看集群状态
docker node ls
docker service ls
docker stack ls
# 部署服务栈
docker stack deploy -c docker-compose.yml myapp
Docker Swarm 服务配置:
# docker-compose.swarm.yml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
deploy:
replicas: 3
placement:
constraints:
- node.role == worker
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
networks:
- webnet
volumes:
- web_data:/usr/share/nginx/html
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
deploy:
replicas: 1
placement:
constraints:
- node.labels.type == database
secrets:
- db_password
volumes:
- db_data:/var/lib/postgresql/data
networks:
- dbnet
volumes:
web_data:
db_data:
networks:
webnet:
driver: overlay
dbnet:
driver: overlay
secrets:
db_password:
external: true
运维经验
生产环境检查清单:
#!/bin/bash
# production-checklist.sh
echo "=== Docker 生产环境检查清单 ==="
# 1. 系统资源检查
echo "1. 系统资源检查"
df -h
free -h
docker system df
# 2. 容器状态检查
echo "2. 容器状态检查"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# 3. 镜像安全检查
echo "3. 镜像安全检查"
for image in $(docker images --format "{{.Repository}}:{{.Tag}}"); do
echo "扫描镜像: $image"
trivy image --severity HIGH,CRITICAL $image
done
# 4. 网络连通性检查
echo "4. 网络连通性检查"
docker network ls
for container in $(docker ps --format "{{.Names}}"); do
echo "检查容器 $container 网络连通性"
docker exec $container ping -c 1 google.com > /dev/null && echo "OK" || echo "FAIL"
done
# 5. 数据卷检查
echo "5. 数据卷检查"
docker volume ls
docker volume ls --filter dangling=true
# 6. 日志检查
echo "6. 日志检查"
for container in $(docker ps --format "{{.Names}}"); do
echo "检查容器 $container 日志"
docker logs --tail 10 $container
done
# 7. 性能指标检查
echo "7. 性能指标检查"
docker stats --no-stream
echo "=== 检查完成 ==="
故障恢复脚本:
#!/bin/bash
# disaster-recovery.sh
BACKUP_DIR="/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
# 1. 停止所有服务
echo "停止所有 Docker 服务..."
docker-compose down
# 2. 备份当前状态
echo "备份当前状态..."
mkdir -p $BACKUP_DIR/failed_$DATE
docker save $(docker images -q) > $BACKUP_DIR/failed_$DATE/images.tar
cp -r /var/lib/docker/volumes $BACKUP_DIR/failed_$DATE/
# 3. 恢复到最近的备份
echo "恢复到最近的备份..."
LATEST_BACKUP=$(ls -t $BACKUP_DIR/backup_* | head -1)
if [ -n "$LATEST_BACKUP" ]; then
docker load < $LATEST_BACKUP/images.tar
rsync -av $LATEST_BACKUP/volumes/ /var/lib/docker/volumes/
fi
# 4. 重启服务
echo "重启服务..."
docker-compose up -d
# 5. 健康检查
echo "执行健康检查..."
sleep 30
./production-checklist.sh
echo "故障恢复完成"
性能优化配置:
{
"data-root": "/var/lib/docker",
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
},
"live-restore": true,
"userland-proxy": false,
"experimental": false,
"metrics-addr": "127.0.0.1:9323",
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"default-shm-size": "64M"
}
监控告警配置:
# alertmanager.yml
global:
smtp_smarthost: 'localhost:587'
smtp_from: '[email protected]'
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
email_configs:
- to: '[email protected]'
subject: 'Docker Alert: {{ .GroupLabels.alertname }}'
body: |
{{ range .Alerts }}
Alert: {{ .Annotations.summary }}
Description: {{ .Annotations.description }}
{{ end }}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
自动化运维脚本:
#!/bin/bash
# auto-maintenance.sh
# 定期清理脚本(建议每天运行)
echo "开始自动维护..."
# 1. 清理停止的容器
docker container prune -f
# 2. 清理未使用的镜像
docker image prune -f
# 3. 清理未使用的网络
docker network prune -f
# 4. 清理未使用的数据卷(谨慎使用)
# docker volume prune -f
# 5. 清理构建缓存
docker builder prune -f
# 6. 检查磁盘空间
DISK_USAGE=$(df /var/lib/docker | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 80 ]; then
echo "警告:Docker 存储空间使用率超过 80%"
# 发送告警
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Docker 存储空间不足,使用率: '$DISK_USAGE'%"}' \
$SLACK_WEBHOOK_URL
fi
# 7. 更新镜像(可选)
# docker-compose pull
# docker-compose up -d
echo "自动维护完成"
这样就完成了 Docker 技术文档的编写。文档涵盖了从基础概念到生产环境实践的全方位内容,包括安装配置、镜像管理、容器管理、网络存储、安全监控等各个方面,为 Docker 的学习和使用提供了完整的参考指南。