1. Docker:从零开始的容器化之旅
作为一名经历过"这在我机器上能跑"噩梦的老程序员,第一次接触Docker时的震撼至今难忘。记得2015年部署一个Python数据分析项目,光是解决生产环境的依赖冲突就花了三天时间。而如今,通过Docker容器技术,同样的部署过程只需要三分钟。这种变革不仅仅是效率的提升,更是开发范式的革新。
Docker本质上是一个开源的容器引擎,它通过操作系统级别的虚拟化技术(容器化),将应用程序及其所有依赖打包成一个标准化的运行单元。这个单元可以在任何支持Docker的环境中运行,彻底解决了"环境一致性"这个困扰开发者数十年的难题。
提示:Docker的跨平台特性并不意味着它能在所有操作系统上原生运行。Windows和macOS上的Docker实际上是在Linux虚拟机中运行容器,因为Docker依赖Linux内核的命名空间和控制组(cgroups)功能。
2. 为什么Docker成为现代开发的标配
2.1 环境一致性的终极解决方案
在传统开发流程中,最令人头疼的莫过于开发、测试和生产环境的不一致问题。我曾参与过一个Java Web项目,开发时使用Tomcat 8.5,测试环境却是Tomcat 9.0,生产环境又变成了WebLogic。这种环境差异导致的问题占用了团队近30%的调试时间。
Docker通过容器镜像彻底解决了这个问题。镜像一旦构建完成,在任何Docker环境中运行的表现都完全一致。这就像把整个运行环境"冷冻"起来,无论在哪解冻,内容都不会改变。
2.2 资源效率的革命性提升
与传统的虚拟机(VM)相比,Docker容器在资源利用率上有显著优势。下表展示了二者的核心差异:
| 特性 | 虚拟机 | Docker容器 |
|---|---|---|
| 隔离级别 | 硬件级(完整OS) | 进程级(共享内核) |
| 启动时间 | 分钟级 | 秒级甚至毫秒级 |
| 内存占用 | 每个VM需要独立OS内存 | 仅需应用内存 |
| 磁盘占用 | GB级别 | MB级别 |
| 性能损耗 | 显著(硬件虚拟化开销) | 几乎可以忽略 |
在实际项目中,我曾将10个微服务从VM迁移到Docker容器,服务器资源消耗降低了65%,部署时间从原来的45分钟缩短到5分钟。
2.3 持续交付的加速器
现代DevOps实践中,Docker已经成为持续集成/持续部署(CI/CD)管道的核心组件。通过将构建过程Docker化,可以实现:
- 构建环境的完全可重现性
- 构建产物的标准化
- 测试环境的即时创建和销毁
- 一键式部署到任何环境
3. Docker核心概念深度解析
3.1 镜像:应用的DNA
Docker镜像是一个只读模板,包含创建容器所需的所有指令。理解镜像的几个关键特性:
-
分层存储:镜像由多个只读层组成,每层代表Dockerfile中的一个指令。这种设计带来两个巨大优势:
- 层可以共享和复用,极大节省存储空间
- 构建时只需重新构建变更的层,加速构建过程
-
内容寻址存储:每个镜像层都有一个基于其内容计算的加密哈希值作为唯一标识。这保证了镜像内容的完整性和不可变性。
-
构建上下文:当执行
docker build时,当前目录(构建上下文)的所有文件都会被发送到Docker守护进程。这就是为什么.dockerignore文件如此重要 - 它可以避免发送不必要的文件,加速构建过程。
注意:镜像的每一层都是只读的。当容器启动时,Docker会在镜像层之上添加一个可写层(容器层),所有修改都发生在这个层中。
3.2 容器:镜像的运行实例
容器是镜像的可运行实例。你可以把它理解为一个轻量级的Linux环境,包含:
- 独立的进程树
- 独立的网络接口
- 独立的文件系统(基于镜像层+可写层)
容器的生命周期管理是日常使用中最频繁的操作。以下是一些实用技巧:
bash复制# 启动容器并进入交互模式(退出后容器停止)
docker run -it ubuntu /bin/bash
# 启动容器并在后台运行
docker run -d nginx
# 查看容器日志
docker logs -f <container_id>
# 在运行中的容器内执行命令
docker exec -it <container_id> /bin/bash
# 停止容器但不删除
docker stop <container_id>
# 启动已停止的容器
docker start <container_id>
# 删除已停止的容器
docker rm <container_id>
3.3 仓库:镜像的集散地
Docker仓库分为两种:
-
公共仓库:最著名的是Docker Hub,包含大量官方和社区维护的镜像。使用前务必检查镜像的:
- 官方认证标志(Official Image)
- 下载量
- 更新频率
- 用户评价
-
私有仓库:企业常用的部署方式,如:
- Docker Registry(开源)
- Harbor(企业级)
- 云服务商提供的仓库服务(ECR, ACR等)
实际操作中,我建议为生产环境搭建私有仓库,并实施严格的镜像扫描和签名验证机制,确保供应链安全。
4. Docker实战:从安装到部署
4.1 安装最佳实践
虽然Docker的安装过程相对简单,但有几个关键点需要注意:
Linux系统:
bash复制# Ubuntu示例
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加稳定版仓库
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)
sudo usermod -aG docker $USER
Windows/macOS:
- 推荐使用Docker Desktop,但要注意:
- 需要开启硬件虚拟化支持(BIOS中设置)
- 至少分配4GB内存给Docker
- 配置国内镜像加速器(如阿里云镜像加速器)
安装完成后,验证Docker是否正常工作:
bash复制docker --version
docker run hello-world
4.2 运行你的第一个生产级容器
让我们以一个更接近生产环境的Nginx部署为例:
bash复制docker run -d \
--name web-server \
-p 8080:80 \
-v /path/to/your/html:/usr/share/nginx/html \
-v /path/to/nginx/config:/etc/nginx/conf.d \
--restart unless-stopped \
nginx:1.21-alpine
这个命令做了以下事情:
- 在后台运行(-d)一个名为web-server的容器
- 将宿主机的8080端口映射到容器的80端口
- 挂载两个数据卷:
- 网站HTML文件目录
- Nginx配置文件目录
- 设置容器在意外停止时自动重启
- 使用轻量级的nginx:1.21-alpine镜像
提示:生产环境推荐使用特定版本标签(如1.21-alpine)而非latest,确保版本一致性。
4.3 容器网络深入理解
Docker提供了多种网络模式,满足不同场景需求:
- bridge(默认):容器通过虚拟网桥连接到宿主机网络
- host:容器直接使用宿主机的网络栈
- none:禁用所有网络
- overlay:支持多主机容器通信(Swarm/Kubernetes)
- macvlan:为容器分配MAC地址,使其在物理网络中显示为真实设备
创建自定义网络并运行容器:
bash复制# 创建自定义bridge网络
docker network create --driver bridge my-network
# 运行容器并加入自定义网络
docker run -d --name web --network my-network nginx
docker run -it --name client --network my-network alpine sh
# 在client容器中可以直接通过容器名访问web容器
ping web
5. 构建生产级Docker镜像
5.1 Dockerfile最佳实践
编写高效的Dockerfile是一门艺术。以下是一个Python应用的优化示例:
dockerfile复制# 使用官方Python slim镜像作为基础
FROM python:3.9-slim as builder
# 设置工作目录
WORKDIR /app
# 先安装依赖(利用Docker缓存层)
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 复制应用代码
COPY . .
# 第二阶段:构建最终镜像
FROM python:3.9-slim
WORKDIR /app
# 从builder阶段复制已安装的依赖
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app .
# 确保脚本可执行
RUN chmod +x entrypoint.sh
# 确保PATH中包含用户安装目录
ENV PATH=/root/.local/bin:$PATH
# 声明容器监听的端口
EXPOSE 8000
# 定义健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8000/health || exit 1
# 使用非root用户运行
RUN useradd -m myuser && chown -R myuser /app
USER myuser
# 入口点脚本
ENTRYPOINT ["./entrypoint.sh"]
这个Dockerfile体现了多个最佳实践:
- 使用多阶段构建减小最终镜像大小
- 合理利用缓存加速构建
- 添加健康检查
- 使用非root用户增强安全性
- 清晰的指令排序(从最不常变化到最常变化)
5.2 镜像优化技巧
-
选择合适的基础镜像:
- 优先使用官方镜像
- 考虑alpine或slim版本
- 注意镜像的更新频率和安全补丁
-
最小化层数:
- 合并RUN指令(使用&&和)
- 清理不必要的文件(apt-get clean)
-
安全考虑:
- 定期扫描镜像漏洞(使用docker scan)
- 不使用latest标签
- 最小化安装的软件包
-
构建参数:
- 使用--no-cache强制全新构建
- 使用--build-arg传递构建时参数
5.3 镜像扫描与安全
生产环境中,镜像安全至关重要。推荐以下实践:
- 使用Snyk或Trivy等工具扫描镜像漏洞
- 实施内容信任(Docker Content Trust)
- 定期更新基础镜像
- 最小化镜像中的软件包
扫描示例:
bash复制# 使用Docker自带的扫描功能(需要登录Docker Hub)
docker scan my-image:tag
# 使用Trivy(开源工具)
trivy image my-image:tag
6. 数据管理与持久化存储
6.1 Docker数据卷详解
Docker提供了三种主要的数据管理方式:
-
绑定挂载(Bind Mount):直接将宿主机目录挂载到容器
bash复制
docker run -v /host/path:/container/path nginx -
卷(Volume):由Docker管理的持久化存储
bash复制
docker volume create my-vol docker run -v my-vol:/container/path nginx -
临时文件系统(tmpfs):仅存在于内存中
bash复制
docker run --tmpfs /container/path nginx
提示:对于生产环境,推荐使用命名卷而非绑定挂载,因为:
- 更容易备份和迁移
- 更好的跨平台兼容性
- Docker工具链的更好支持
6.2 数据库容器化实践
以MySQL为例,展示生产级部署:
bash复制# 创建专用网络
docker network create db-network
# 创建数据卷
docker volume create mysql-data
# 运行MySQL容器
docker run -d \
--name mysql-server \
--network db-network \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=complexpassword \
-e MYSQL_DATABASE=appdb \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=userpassword \
--restart unless-stopped \
mysql:8.0 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
关键配置说明:
- 使用专用网络增强隔离性
- 命名卷确保数据持久化
- 通过环境变量配置(而非配置文件)
- 设置字符集和排序规则
- 配置自动重启策略
6.3 备份与恢复策略
对于生产环境,必须建立完善的备份机制:
- 卷备份:
bash复制# 创建备份容器临时挂载卷
docker run --rm \
-v mysql-data:/source \
-v /backup:/backup \
alpine \
tar czf /backup/mysql-backup-$(date +%Y%m%d).tar.gz -C /source .
- 数据库导出:
bash复制docker exec mysql-server \
mysqldump -u appuser -puserpassword appdb > backup.sql
- 恢复策略:
bash复制# 停止原容器
docker stop mysql-server
# 恢复卷数据
docker run --rm \
-v mysql-data:/target \
-v /backup:/backup \
alpine \
tar xzf /backup/mysql-backup-20230101.tar.gz -C /target
# 启动新容器
docker start mysql-server
7. 生产环境问题排查与优化
7.1 常见问题诊断
-
容器启动失败:
- 查看日志:
docker logs <container_id> - 检查退出代码:
docker inspect -f '{{.State.ExitCode}}' <container_id>
- 查看日志:
-
性能问题:
- 监控资源使用:
docker stats - 检查进程:
docker top <container_id>
- 监控资源使用:
-
网络问题:
- 测试连接:
docker exec -it <container_id> ping <target> - 检查网络配置:
docker network inspect <network_name>
- 测试连接:
7.2 资源限制与调优
Docker允许对容器资源进行精细控制:
bash复制# 限制内存使用
docker run -d --memory=512m --memory-swap=1g nginx
# 限制CPU使用
docker run -d --cpus=1.5 nginx
# 限制IOPS
docker run -d \
--device-read-bps /dev/sda:1mb \
--device-write-bps /dev/sda:1mb \
nginx
生产环境建议:
- 为每个容器设置内存限制
- 关键服务预留CPU资源
- 数据库类服务限制IOPS
7.3 日志管理策略
Docker日志管理要点:
-
日志驱动选择:
- json-file(默认)
- syslog
- journald
- gelf
- fluentd
-
日志轮转配置:
json复制{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
- 集中式日志收集:
- ELK Stack
- Fluentd + S3
- Loki + Grafana
8. 进阶话题与生态工具
8.1 Docker Compose:多容器编排
对于复杂的多容器应用,推荐使用Docker Compose。示例docker-compose.yml:
yaml复制version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
depends_on:
- api
api:
image: my-app:latest
environment:
- DB_HOST=db
- DB_PORT=5432
networks:
- app-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
POSTGRES_DB: appdb
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- app-network
volumes:
pgdata:
networks:
app-network:
driver: bridge
关键特性:
- 服务依赖管理
- 网络隔离
- 卷管理
- 健康检查
- 环境变量配置
8.2 容器编排:从Swarm到Kubernetes
当应用规模扩大,需要考虑容器编排:
-
Docker Swarm:
- Docker原生解决方案
- 学习曲线平缓
- 适合中小规模部署
-
Kubernetes:
- 行业标准
- 功能丰富
- 适合大规模生产环境
8.3 CI/CD集成
将Docker集成到CI/CD流水线:
yaml复制# GitHub Actions示例
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: username/my-app:latest
9. 容器安全最佳实践
9.1 最小权限原则
- 使用非root用户运行容器
- 限制容器能力:
bash复制
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx - 设置只读文件系统:
bash复制
docker run --read-only nginx
9.2 网络隔离
- 使用自定义网络
- 限制网络访问:
bash复制
docker network create --internal isolated-net - 配置网络安全策略
9.3 运行时保护
- 使用seccomp配置文件
- 启用AppArmor/SELinux
- 定期扫描镜像漏洞
10. 从开发到生产的完整流程
10.1 开发环境配置
- 使用
docker-compose.override.yml进行开发特定配置 - 配置热重载:
yaml复制services: web: volumes: - ./src:/app/src environment: - FLASK_ENV=development
10.2 测试策略
- 多阶段构建测试镜像
- 集成测试容器
- 端到端测试环境
10.3 生产部署检查清单
- 镜像标签管理
- 配置管理(环境变量 vs 配置文件)
- 监控和告警设置
- 备份和灾难恢复计划
11. 真实案例:传统应用容器化
我曾帮助一家企业将传统Java应用容器化,过程如下:
-
分析阶段:
- 识别所有依赖项
- 记录当前部署流程
- 确定配置项和密钥
-
Dockerfile编写:
dockerfile复制FROM eclipse-temurin:17-jdk-jammy WORKDIR /app COPY target/my-app.jar . COPY config/application.properties ./config/ EXPOSE 8080 ENTRYPOINT ["java", "-jar", "my-app.jar"] -
部署流程重构:
- 构建:
docker build -t my-app:${VERSION} . - 测试:
docker-compose -f docker-compose.test.yml up - 部署:滚动更新策略
- 构建:
-
成果:
- 部署时间从2小时缩短到15分钟
- 环境问题减少90%
- 资源利用率提高40%
12. 性能调优实战
12.1 内存优化
案例:一个Node.js应用频繁被OOM杀死
解决方案:
- 分析内存使用模式
- 设置合理的内存限制:
bash复制
docker run -d --memory=1g --memory-swap=1.5g my-node-app - 添加
--max-old-space-size参数
12.2 CPU优化
案例:批处理作业需要更多CPU资源
解决方案:
- 设置CPU优先级:
bash复制
docker run -d --cpus=2 --cpu-shares=512 my-batch-job - 绑定特定CPU核心:
bash复制docker run -d --cpuset-cpus="0,1" my-batch-job
12.3 IO优化
案例:数据库容器IO性能差
解决方案:
- 使用本地SSD存储
- 调整IO优先级:
bash复制
docker run -d \ --device-read-iops /dev/sda:1000 \ --device-write-iops /dev/sda:500 \ mysql - 选择合适的文件系统
13. 监控与告警体系
13.1 监控指标收集
-
容器基础指标:
- CPU使用率
- 内存使用
- 网络IO
- 磁盘IO
-
应用指标:
- 请求延迟
- 错误率
- 吞吐量
13.2 可视化工具
-
cAdvisor + Prometheus + Grafana:
- 容器专用监控方案
- 丰富的仪表板
- 告警集成
-
商业方案:
- Datadog
- New Relic
- Dynatrace
13.3 告警策略
- 基于阈值的告警(CPU > 90%持续5分钟)
- 基于异常的告警(自动基线检测)
- 多级告警(警告→严重→紧急)
14. 成本优化策略
14.1 资源利用率提升
- 合理设置资源限制
- 实施自动扩缩容
- 使用Spot实例运行非关键负载
14.2 镜像优化
- 多阶段构建
- 选择轻量级基础镜像
- 清理构建缓存
14.3 存储优化
- 使用卷驱动压缩
- 实施生命周期策略
- 定期清理无用镜像
15. 未来趋势与持续学习
容器技术仍在快速发展,值得关注的趋势:
- Wasm容器:更轻量、更安全的运行时
- eBPF:深度可观测性和安全
- 机密计算:数据使用中的保护
- 绿色计算:能效优化
持续学习资源:
- Docker官方文档
- CNCF(Cloud Native Computing Foundation)项目
- KubeCon等行业会议
- 容器安全最佳实践指南
16. 个人经验与教训
在多年的Docker实践中,我积累了一些宝贵经验:
-
标签管理:永远不要依赖latest标签,使用语义化版本控制,并为每个构建使用唯一标识符。
-
构建可重现性:确保Docker构建是可重现的。固定基础镜像版本,避免在构建过程中下载外部资源。
-
最小化攻击面:每个额外的软件包都可能引入漏洞。坚持最小化原则,只安装必要的依赖。
-
日志策略:从一开始就规划好日志管理。容器日志如果不加控制,可能很快填满磁盘。
-
网络设计:提前规划网络架构。简单的应用可能只需要默认bridge网络,但复杂系统需要精心设计的自定义网络。
-
持久化数据:明确区分哪些数据需要持久化,哪些可以随容器销毁。错误的设计可能导致数据丢失。
-
安全扫描:将镜像扫描集成到CI/CD流程中,而不是事后才考虑。
-
资源限制:即使资源充足,也应该设置合理的限制。这可以防止单个容器影响整个系统。
-
文档化:记录容器的设计决策、配置项和操作流程。三个月后的你会感谢现在的你。
-
备份验证:定期测试备份恢复流程。没有验证的备份可能比没有备份更危险。
17. 常见陷阱与解决方案
17.1 容器内时间不一致
问题:容器内时间与宿主机不同步,导致日志时间错乱等问题。
解决方案:
bash复制docker run -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro my-app
17.2 僵尸进程累积
问题:长时间运行的容器可能出现僵尸进程累积。
解决方案:
- 使用init进程:
bash复制
docker run --init my-app - 或者使用tini:
dockerfile复制ENTRYPOINT ["/sbin/tini", "--", "/app/start.sh"]
17.3 文件描述符泄漏
问题:应用可能泄漏文件描述符,最终耗尽资源。
解决方案:
- 监控文件描述符使用:
bash复制ls -l /proc/$(docker inspect -f '{{.State.Pid}}' <container_id>)/fd | wc -l - 设置限制:
bash复制docker run --ulimit nofile=1024:1024 my-app
17.4 存储驱动选择
问题:默认的存储驱动可能不适合所有场景。
解决方案:
- 根据文件系统选择最佳驱动:
- overlay2(大多数Linux发行版)
- aufs(旧版Ubuntu)
- zfs(btrfs/zfs文件系统)
- 调整Docker daemon配置:
json复制{ "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] }
18. 调试技巧与工具
18.1 容器内调试
-
进入运行中的容器:
bash复制docker exec -it <container_id> /bin/bash -
检查容器元数据:
bash复制
docker inspect <container_id> -
查看进程树:
bash复制
docker top <container_id>
18.2 网络诊断
-
测试容器间连通性:
bash复制docker run --rm --network <network_name> busybox ping <service_name> -
检查DNS解析:
bash复制docker run --rm --network <network_name> busybox nslookup <service_name> -
抓包分析:
bash复制docker run --rm --net container:<container_id> nicolaka/netshoot tcpdump -i eth0 -w /capture.pcap
18.3 高级调试工具
-
nsenter:直接进入容器的命名空间
bash复制nsenter -t $(docker inspect -f '{{.State.Pid}}' <container_id>) -n ip a -
dive:分析镜像层内容
bash复制
dive my-image:tag -
ctop:容器资源监控
bash复制
ctop
19. 企业级部署考量
19.1 镜像仓库管理
- 访问控制:基于角色的权限管理
- 镜像签名:确保镜像来源可信
- 空间配额:防止仓库无限增长
- 全球同步:多地部署时减少拉取延迟
19.2 合规与审计
- 镜像来源审计:记录所有使用的镜像及其来源
- 构建过程审计:谁在何时构建了什么镜像
- 部署审计:哪些镜像被部署到生产环境
- 漏洞扫描报告:定期生成安全报告
19.3 多环境策略
-
环境差异管理:
- 使用相同的镜像
- 通过环境变量或配置文件区分环境
- 避免为不同环境构建不同镜像
-
蓝绿部署:
- 同时运行新旧版本
- 通过路由切换流量
- 快速回滚能力
-
金丝雀发布:
- 逐步向部分用户推出新版本
- 监控关键指标
- 确认稳定后全面推广
20. 容器设计模式
20.1 边车模式(Sidecar)
场景:为主容器提供辅助功能,如日志收集、监控代理等。
实现:
yaml复制services:
main-app:
image: my-app
volumes:
- ./logs:/var/log/app
log-collector:
image: fluentd
volumes:
- ./logs:/var/log/app
depends_on:
- main-app
20.2 初始化容器模式(Init Container)
场景:在主容器启动前执行准备任务,如数据库迁移、配置文件生成等。
实现:
yaml复制services:
web:
image: nginx
depends_on:
- init-db
init-db:
image: busybox
command: ["sh", "-c", "until nc -z db 5432; do echo 'Waiting for DB'; sleep 2; done"]
20.3 适配器模式(Adapter)
场景:标准化不同容器的监控接口或日志格式。
实现:
yaml复制services:
app:
image: my-app
monitor:
image: prometheus-exporter
command: ["--source.url=http://app:8080/metrics"]
21. 性能基准测试方法
21.1 压力测试工具
-
HTTP负载测试:
bash复制docker run --rm --network host williamyeh/wrk \ -t4 -c100 -d30s http://localhost:8080/api -
数据库性能测试:
bash复制docker run --rm --network app-network severalnines/sysbench \ --db-driver=mysql --mysql-host=db --mysql-user=root \ --mysql-password=example --mysql-db=test --oltp-test-mode=complex \ --oltp-tables-count=10 --oltp-table-size=100000 \ --threads=4 --time=60 --report-interval=10 prepare
21.2 资源监控
-
实时监控:
bash复制
docker stats -
历史数据分析:
bash复制
docker run -d --name=cadvisor \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:ro \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --publish=8080:8080 \ google/cadvisor:latest
21.3 性能优化循环
- 基准测试 → 2. 识别瓶颈 → 3. 实施优化 → 4. 验证效果 → (循环)
22. 无状态与有状态服务
22.1 无状态服务容器化
特点:
- 易于水平扩展
- 快速启动
- 适合自动恢复
示例:
yaml复制services:
web:
image: nginx
deploy:
replicas: 3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
22.2 有状态服务容器化
挑战:
- 数据持久化
- 网络标识稳定性
- 有序扩展
解决方案:
- 使用StatefulSet(Kubernetes)或类似概念
- 稳定的网络标识
- 持久化存储卷
- 备份策略
示例:
yaml复制services:
db:
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: example
deploy:
placement:
constraints:
- node.role == manager
23. 跨平台开发策略
23.1 多架构镜像
-
构建多平台镜像:
bash复制
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:multi-arch . -
使用manifest组合:
bash复制
docker manifest create my-app:latest \ my-app:amd64-latest \ my-app:arm64-latest
23.2 开发环境一致性
-
远程开发容器:
- VS Code Remote - Containers
- JetBrains Gateway
-
开发容器定义:
json复制{ "image": "mcr.microsoft.com/vscode/devcontainers/base:ubuntu", "forwardPorts": [3000], "postCreateCommand": "npm install", "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint"] } } }
24. 容器化遗留系统
24.1 评估与规划
-
应用分析:
- 依赖项识别
- 配置项收集
- 数据存储需求
-
容器化策略:
- 整体容器化(单体应用)
- 逐步拆分(微服务化)
24.2 常见挑战与解决
-
硬编码配置:
- 使用环境变量注入
- 配置文件挂载
-
IP依赖:
- 使用服务发现
- DNS别名
-
状态管理:
- 外部化状态
- 共享存储
24.3 示例:传统Java应用
dockerfile复制FROM ibmjava:8-jre
# 安装传统依赖
RUN apt-get update && apt-get install -y \
libxt6 \
libxrender1 \
&& rm -rf /var/lib/apt/lists/*
# 应用部署
COPY legacy-app.war /opt/ibm/wlp/usr/servers/defaultServer/dropins/
COPY server.xml /opt/ibm/wlp/usr/servers/defaultServer/
# 传统配置转换
ENV DB_URL=jdbc:db2://db:50000/LEGACYDB
ENV JVM_ARGS="-Xmx1024m -Xms512m"
EXPOSE 9080
CMD ["/opt/ibm/wlp