docker 概念
它基于操作系统层级的虚拟化技术,将软件与其依赖项打包为容器。托管容器的软件称为Docker引擎。Docker能够帮助开发者在轻量级容器中自动部署应用程序,并使得不同容器中的应用程序彼此隔离,高效工作。
说人话!
镜像(Image) : 打包好了一套应用程序、运行环境、配置文件、系统库等。在任何支持Docker的地方(无论是Windows、Mac还是Linux服务器)内容都完全一样。
容器(Container) :当镜像在服务器上启动时,它就变成了一个正在运行镜像实例,即容器。这个实例是独立、隔离的,一个服务器可以同时运行很多个互不干扰的容器。
仓库(Registry) : 把打包好的镜像上传到公共或者私有的地方,(如:docker hub),其他人可以随时准确的拉取一个版本的镜像来运行。
应用场景
1.一键搭建/重建复杂的测试环境
场景:你需要测试一个Web应用,它依赖MySQL数据库、Redis缓存和Nginx反向代理。
-
传统方式:你需要找一台干净的机器,手动安装、配置这三个服务,调整版本和参数,耗时耗力且容易出错。
-
Docker方式:编写一个简单的
docker-compose.yml文件(或直接运行几条命令),一键启动所有服务。测试完成后,一键全部销毁,环境瞬间复原。
# docker-compose.yml 示例(概念理解)
version: '3.8' # Docker Compose 文件格式版本
services: # 定义要运行的所有容器(服务)
web-app: # 第一个服务,名为"web-app"
image: my-web-app:test-version # 使用的镜像名称
ports: # 端口映射:主机端口:容器端口
- "8080:80" # 将主机的8080端口映射到容器的80端口
depends_on: # 依赖关系:先启动这些服务,再启动本服务
- mysql
- redis
mysql: # 第二个服务,名为"mysql"
image: mysql:5.7 # 使用MySQL 5.7官方镜像
environment: # 设置环境变量
MYSQL_ROOT_PASSWORD: test123 # MySQL root用户密码
redis: # 第三个服务,名为"redis"
image: redis:alpine # 使用Redis的Alpine版本(轻量)
nginx: # 第四个服务,名为"nginx"
image: nginx:latest # 使用最新版Nginx镜像
解读yaml文件
1.Docker Compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。你可以把它理解为 Docker 的“编队指挥官”。Docker 本身擅长管理单个容器,而 Docker Compose 则擅长管理一组相互关联的容器,让它们作为一个完整的应用协同工作。
Docker Compose工作原理
-
定义:你在
docker-compose.yml文件中描述你的应用由哪些服务(容器)组成,每个服务用什么镜像、映射哪些端口、挂载哪些数据卷、如何连接等。 -
运行:在文件所在目录执行
docker-compose up,Compose 会:- 解析 YAML 文件。
- 为所有服务创建一个独立的网络,让它们能通过服务名相互发现。
- 按依赖顺序拉取镜像并启动容器。
- 将所有容器的日志聚合输出,方便查看。
-
管理:你可以用
docker-compose命令统一管理这组容器的生命周期:启动、停止、重启、查看状态、查看日志等。
2.yaml文件字段详解
version(必需)
- 含义:指定使用的 Docker Compose 文件格式版本
- 注意:不是 Docker 引擎版本。版本3.x是目前主流,不同版本支持的配置选项不同
services(必需)
- 含义:定义所有要运行的容器(在Docker Compose中称为"服务")
- 结构:下面是服务列表,每个服务有自己的配置块
- 服务名 (如
web-app、mysql)
- 含义:自定义的服务名称,在同一个文件中必须唯一
- 作用:会成为容器名称的一部分,也可用于服务间通信(通过服务名作为主机名)
image
- 含义:指定服务使用的镜像
- 格式:
镜像名:标签 - 示例:
mysql:5.7表示从Docker Hub拉取MySQL 5.7版本镜像 - 替代选项:也可以用
build字段从 Dockerfile 构建
ports
- 含义:端口映射,将主机端口绑定到容器端口
- 格式:
"主机端口:容器端口" - 注意:
8080:80表示访问主机的8080端口会转发到容器的80端口 - 可省略主机端口:
"80"或"3000"只写容器端口,Docker会随机分配主机端口
depends_on
- 含义:定义服务启动顺序依赖
- 示例:
depends_on: [mysql, redis]表示先启动mysql和redis,再启动当前服务 - 注意:只控制启动顺序,不保证依赖的服务已"就绪"(比如MySQL启动了但初始化未完成)
environment
- 含义:设置容器内的环境变量
快速测试命令:
# 启动所有服务(在docker-compose.yml所在目录运行)
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止并删除所有容器
docker-compose down
# 只启动特定服务
docker-compose up -d mysql redis
2.高效进行多版本兼容性测试
场景:你的应用需要兼容 Python 3.8 和 3.11。
- 传统方式:在机器上反复安装、卸载不同版本的Python,或维护多台测试机。
- Docker方式:同时运行两个容器,分别使用
python:3.8-slim和python:3.11-slim镜像,在里面运行你的测试套件。它们完全隔离,互不影响。
# 概念性命令
docker run --rm python:3.8-slim python -m pytest /your-test-suite
docker run --rm python:3.11-slim python -m pytest /your-test-suite
3. 实现“一次构建,处处运行”的测试执行环境
场景:你的自动化测试脚本(如Selenium、API测试)依赖特定的浏览器驱动、Java版本或第三方库。
- 传统方式:需要为每台执行测试的机器(包括CI服务器)统一配置环境,维护成本高。
- Docker方式:将你的测试代码、依赖库、浏览器等全部打包成一个测试专用镜像。在任何有Docker的地方(本地、CI服务器),只需运行这个镜像,就能启动一个包含所有依赖的、标准化的测试执行环境。
你的收益:保证所有测试执行节点环境绝对一致,排查问题时排除了环境变量干扰。
将测试代码、依赖库、浏览器等打包成专用镜像,核心是编写一个 Dockerfile 文件
4. 在CI/CD流水线中无缝集成测试
场景:代码提交后,自动触发构建和测试。
- 传统方式:CI服务器需要预装各种工具和运行时,配置复杂。
- Docker方式:CI任务(如Jenkins Job、GitLab Runner)直接拉取包含测试环境的镜像,在其中执行测试。测试结果生成后,容器被丢弃。整个流水线步骤清晰、环境纯净。
你的收益:CI流程更稳定、可移植,简化了服务器维护。
给你的实践建议
- 从使用开始:先不用学如何制作镜像。让开发提供应用的Docker镜像,你学习如何运行(
docker run)、查看日志(docker logs)、进入容器检查(docker exec -it)。 - 学习Docker Compose:这是测试人员最实用的工具,用于定义和运行多容器应用。上面例子1中的yml文件就是它的配置。
- 融入日常:下次搭建测试环境时,先问“有没有现成的Docker镜像或
docker-compose文件?”。
核心思想:作为测试,你主要将Docker作为一个强大、可靠的环境提供工具来使用。它让你从繁琐的环境配置和维护中解放出来,更专注于测试本身。
docker命令
容器生命周期管理
1.创建并启动一个新容器——run
# 基本使用
docker run ubuntu
# 后台运行容器
docker run -d ubuntu
# 交互式运行并分配终端
docker run -it ubuntu /bin/bash
# 指定容器名称
docker run --name my_container ubuntu
# 端口映射
docker run -p 8080:80 nginx
# 挂载卷
docker run -v /host/data:/container/data ubuntu
# 设置环境变量
docker run -e MY_ENV_VAR=my_value ubuntu
# 使用网络模式
docker run --network host nginx
# 指定重启策略
docker run --restart always nginx
# 指定用户
docker run -u user123 ubuntu
# 组合多个选项
docker run -d -p 8080:80 -v /host/data:/data --name webserver nginx
# 常用参数说明:
-d: 后台运行容器并返回容器 ID。
-it: 交互式运行容器,分配一个伪终端。
--name: 给容器指定一个名称。
-p: 端口映射,格式为 host_port:container_port。
-v: 挂载卷,格式为 host_dir:container_dir。
--rm: 容器停止后自动删除容器。
--env 或 -e: 设置环境变量。
--network: 指定容器的网络模式。
--restart: 容器的重启策略(如 no、on-failure、always、unless-stopped)。
-u: 指定用户。
2. 启动、停止、重启容器——start/stop/restart
# 启动一个容器
docker start my_container
# 启动并附加到容器
docker start -a my_container
# 停止一个容器
docker stop my_container
# 指定等待时间停止容器,这里是30秒
docker stop -t 30 my_container
# 重启一个容器
docker restart my_container
# 指定等待时间重启容器
docker restart -t 15 my_container
3.立即终止一个或多个正在运行的容器——kill
# 立即终止一个容器
docker kill my_container
# 发送自定义信号
docker kill -s SIGTERM my_container
# 常用信号
SIGKILL: 强制终止进程(默认信号)。
SIGTERM: 请求进程终止。
SIGINT: 发送中断信号,通常表示用户请求终止。
SIGHUP: 挂起信号,通常表示终端断开。
4.删除一个或多个已经停止的容器——rm
# 删除单个容器
docker rm <container_id_or_name>
# 删除多个容器,只需将容器 ID 或名称用空格分隔
docker rm <container_id_or_name1> <container_id_or_name2>
# 删除所有已停止的容器
docker container prune
5.暂停和恢复容器中的所有进程——pause/unpause
# 暂停一个容器
docker pause my_container
# 恢复一个容器
docker unpause my_container
6.创建一个新的容器,但不会启动它——create
# 创建一个容器
docker create ubuntu
# 创建并指定容器名称
docker create --name my_container ubuntu
# 创建并设置环境变量
docker create -e MY_ENV_VAR=my_value ubuntu
# 创建并挂载卷
docker create -v /host/data:/container/data ubuntu
# 创建并端口映射
docker create -p 8080:80 nginx
# 创建并指定重启策略
docker create --restart always nginx
# 创建并指定用户
docker create -u user123 ubuntu
7.在运行中的容器内执行一个新的命令——exec
# 在容器内运行命令
docker exec my_container ls /app
# 以交互模式运行命令
docker exec -it my_container /bin/bash
# 在后台运行命令
docker exec -d my_container touch /app/newfile.txt
# 设置环境变量
docker exec -e MY_ENV_VAR=my_value my_container env
# 以指定用户身份运行命令
docker exec -u user123 my_container whoami
# 指定工作目录
docker exec -w /app my_container pwd
容器操作
1.列出容器 ——ps
# 列出所有在运行的容器信息
docker ps
# 列出所有容器,包括停止的容器
docker ps -a
# 只显示容器ID
docker ps -q
# 显示最近创建的一个容器
docker ps -l
# 显示容器的大小
docker ps -s
获取对象(容器、镜像、卷、网络等)的详细信息——inspect
# 检查容器
docker inspect my_container
# 检查镜像
docker inspect my_image
# 检查卷
docker inspect my_volume
# 检查网络
docker inspect my_network
# 格式化输出
docker inspect --format '{{ .State.Running }}' my_container
测试场景实用命令组合
场景1:快速运行一次性测试
# 运行测试并自动清理
docker run --rm \
-v $(pwd)/test-results:/app/reports \
my-test-image:latest \
pytest --html=reports/report.html
场景2:调试测试失败
# 1. 运行测试并保留容器
docker run --name failed-test my-test-image
# 2. 查看失败日志
docker logs failed-test
# 3. 进入容器检查状态
docker exec -it failed-test /bin/bash
cd /app
pytest --lf # 只运行上次失败的测试
# 4. 清理
docker rm failed-test
场景3:性能测试监控
# 1. 启动测试
docker run -d --name perf-test my-load-test-image
# 2. 监控资源使用
docker stats perf-test
# 3. 查看实时日志
docker logs -f perf-test
最佳实践提醒
- 测试容器用
--rm:避免积累大量停止的容器 - 挂载报告目录:
-v $(pwd)/reports:/app/reports - 使用版本标签:
my-test:v1.0而非latest - 组合命令:
docker-compose管理复杂环境 - 及时清理:测试完成后运行
docker system prune