docker 入门版

4 阅读10分钟

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文件字段详解

  1. version (必需)
  • 含义:指定使用的 Docker Compose 文件格式版本
  • 注意:不是 Docker 引擎版本。版本3.x是目前主流,不同版本支持的配置选项不同
  1. services(必需)
  • 含义:定义所有要运行的容器(在Docker Compose中称为"服务")
  • 结构:下面是服务列表,每个服务有自己的配置块
  1. 服务名​ (如 web-appmysql)
  • 含义:自定义的服务名称,在同一个文件中必须唯一
  • 作用:会成为容器名称的一部分,也可用于服务间通信(通过服务名作为主机名)
  1. image
  • 含义:指定服务使用的镜像
  • 格式镜像名:标签
  • 示例mysql:5.7 表示从Docker Hub拉取MySQL 5.7版本镜像
  • 替代选项:也可以用 build 字段从 Dockerfile 构建
  1. ports
  • 含义:端口映射,将主机端口绑定到容器端口
  • 格式"主机端口:容器端口"
  • 注意8080:80 表示访问主机的8080端口会转发到容器的80端口
  • 可省略主机端口"80""3000" 只写容器端口,Docker会随机分配主机端口
  1. depends_on
  • 含义:定义服务启动顺序依赖
  • 示例depends_on: [mysql, redis] 表示先启动mysql和redis,再启动当前服务
  • 注意:只控制启动顺序,不保证依赖的服务已"就绪"(比如MySQL启动了但初始化未完成)
  1. 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-slimpython: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流程更稳定、可移植,简化了服务器维护。

给你的实践建议

  1. 从使用开始:先不用学如何制作镜像。让开发提供应用的Docker镜像,你学习如何运行docker run)、查看日志docker logs)、进入容器检查docker exec -it)。
  2. 学习Docker Compose:这是测试人员最实用的工具,用于定义和运行多容器应用。上面例子1中的yml文件就是它的配置。
  3. 融入日常:下次搭建测试环境时,先问“有没有现成的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

最佳实践提醒

  1. 测试容器用 --rm:避免积累大量停止的容器
  2. 挂载报告目录-v $(pwd)/reports:/app/reports
  3. 使用版本标签my-test:v1.0而非 latest
  4. 组合命令docker-compose管理复杂环境
  5. 及时清理:测试完成后运行 docker system prune