Skip to main content
实战收官:代码写完了,但这只是开发的结束,运维的开始。今天我们将把 Python Master 和 MySQL 数据库装进 Docker 容器,并使用 Docker Compose 进行微服务编排。最后,我们将进行全链路联调,验证这个分布式系统的运作。

学习内容 (30 mins)

为什么不写 Dockerfile?
  • Dockerfile 只能定义一个镜像(比如 Master)。
  • 但我们的系统需要 Master + MySQL 配合工作。
  • Compose 的价值: 它像一个剧本(YAML),定义了所有角色(Services)、它们之间的关系(Depends_on)、网络(Networks)和数据卷(Volumes)。
启动顺序的坑
  • 问题: 如果你在 Compose 里写了 depends_on: db,Docker 只会保证 db 容器启动了就启动 master。但 db 容器启动不代表 MySQL 进程准备好接客了(可能还在初始化数据)。这会导致 Master 连接由于 Connection Refused 崩溃。
  • 解决: 使用 healthcheck。Docker 会定期 ping 数据库,直到数据库返回 “I’m OK”,由于配置了 condition: service_healthy,Master 才会正式启动。这是一个生产级的最佳实践。

交付任务 (90 mins)

1

步骤 1: 容器化 Master 服务

master/ 目录下编写 Dockerfile
# 1. 基础镜像:使用 Python 3.9 轻量版
FROM python:3.9-slim

# 2. 设置工作目录
WORKDIR /app

# 3. 依赖层缓存优化
# 先只拷贝 requirements.txt,这样如果代码变了但依赖没变,这层 cached 可以复用
COPY requirements.txt .

# 4. 安装依赖
# --no-cache-dir 减小镜像体积,不要缓存 pip 包
RUN pip install --no-cache-dir -r requirements.txt

# 5. 拷贝业务代码
COPY . .

# 6. 声明端口(仅文档作用)
EXPOSE 8000

# 7. 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
2

步骤 2: 编写编排文件

在项目根目录 ~/final-project/ 创建 docker-compose.yaml
version: '3.8'

services:
  # --- 数据库服务 ---
  db:
    image: mysql:8.0
    container_name: monitor_db
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: monitor_system
    ports:
      - "3306:3306"
    volumes:
      # 数据持久化:防止容器重启数据丢失
      - mysql_data:/var/lib/mysql
    # 健康检查:每 10s ping 一次 mysql,成功 5 次才算健康
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  # --- Master 控制面 ---
  master:
    build: ./master # 指向 Dockerfile 所在目录
    container_name: monitor_master
    ports:
      - "8000:8000"
    depends_on:
      # 关键:等待数据库健康了再启动
      db:
        condition: service_healthy
    environment:
      # 服务发现:Host 直接写 Service Name 'db'
      - DB_URL=mysql+aiomysql://root:root@db/monitor_system

volumes:
  mysql_data:
3

步骤 3: 全链路联调 (The Final Run)

这是见证奇迹的时刻。
# 1. 一键启动后端设施
# -d 后台运行
# --build 强制重新构建镜像(防止代码更新了镜像没更)
docker-compose up -d --build

# 2. 查看日志确保正常
# 这一步非常重要,一定要看到 "Uvicorn running on..."
docker-compose logs -f master

# 3. 启动本地 Agent (模拟业务机器)
# 打开一个新的终端窗口
cd agent && go run main.go
验证检查清单:
  • Master 日志:显示 CREATE TABLE 相关 SQL,无报错。
  • Agent 终端:持续输出 ✅ Sent
  • 浏览器:访问 http://localhost:8000/api/v1/top,能看到刚刚上报的数据(ID 应该是递增的)。
  • 数据流转:CPU 负载变化时,API 返回的值也跟着变化。
常见错误
  • Access denied for user ‘root’: 检查 docker-compose.yaml 里的密码和 Master 代码里的连接串密码是否一致。
  • Connection Refused: 可能是数据库还没启动完成 Master 就抢跑了。检查 healthcheck 配置是否生效。
  • Docker 网络不通: 确保 master 和 db 在同一个 compose 文件里,或者手动指定了 network。

拓展任务 (30 mins)

Agent 要不要容器化?

思考:为什么我们不把 Agent 也写进 docker-compose?答案: 不建议。监控 Agent 主要是采集宿主机的 CPU/磁盘。如果放在容器里,默认看到的是容器内的环境。如果要采集宿主机,需要挂载 /proc/sys 并开启 pid: host 模式,这反而增加了部署复杂度。对于 Agent,直接跑二进制最简单。

可视化进阶

挑战:JSON 数据不好看,老板要看图表。任务:在 compose 里加一个 Grafana 服务。配置 MySQL 数据源,直接读 monitor_system 库,画一个 CPU 曲线图。这就真的变成商业级产品了。

🎓 30 天毕业致辞:你的蜕变

Congratulations! 🎉

在过去的 30 天里,你完成了从“脚本小子”到“全栈运维开发”的蜕变:
  1. Week 1 (基石): 掌握 Shell 自动化与 SQL 数据设计。
  2. Week 2 (Python): 学会用 Python 处理复杂逻辑与 ChatOps。
  3. Week 3 (API): 掌握 FastAPI 构建标准 Web 服务。
  4. Week 4 (Go): 突破性能瓶颈,掌握高并发与二进制分发。
  5. Week 5 (Fusion): 亲手缝合了这一切,构建了一个完整的分布式监控系统。
Keep building, keep learning. 未来的架构师,加油!

回顾本周

第 05 周 | 终极融合

回到首页

查看完整知识图谱